use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method checkSequencedPositionalArgument.
private void checkSequencedPositionalArgument(Parameter p, Reference pr, List<Tree.PositionalArgument> args) {
Type paramType = pr.getTypedParameter(p).getFullType();
Type set = paramType == null ? null : unit.getIteratedType(paramType);
for (int j = 0; j < args.size(); j++) {
Tree.PositionalArgument a = args.get(j);
a.setParameter(p);
Type at = a.getTypeModel();
if (!isTypeUnknown(at) && !isTypeUnknown(paramType)) {
if (a instanceof Tree.SpreadArgument) {
at = spreadType(at, unit, true);
checkAssignable(at, paramType, a, "spread argument must be assignable to variadic parameter " + argdesc(p, pr), 2101);
} else {
checkAssignable(at, set, a, "argument must be assignable to variadic parameter " + argdesc(p, pr), 2101);
// if we already have an arg to a nonempty variadic parameter,
// we can treat it like a possibly-empty variadic now
Interface sd = unit.getSequentialDeclaration();
paramType = paramType.getSupertype(sd);
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.IndexExpression that) {
super.visit(that);
Type pt = type(that);
Tree.Primary primary = that.getPrimary();
if (pt == null) {
if (primary == null || !hasError(primary)) {
that.addError("could not determine type of receiver");
}
} else {
/*if (that.getIndexOperator() instanceof Tree.SafeIndexOp) {
if (unit.isOptionalType(pt)) {
pt = unit.getDefiniteType(pt);
}
else {
that.getPrimary().addError("receiving type not of optional type: " +
pt.getDeclaration().getName(unit) + " is not a subtype of Optional");
}
}*/
Tree.ElementOrRange eor = that.getElementOrRange();
if (eor == null) {
that.addError("malformed index expression");
} else if (!that.getAssigned() && !isTypeUnknown(pt) && !involvesUnknownTypes(eor)) {
if (eor instanceof Tree.Element) {
Interface cd = unit.getCorrespondenceDeclaration();
checkIndexElement(that, pt, cd, true, "Correspondence", false);
} else {
Interface rd = unit.getRangedDeclaration();
Type rst = pt.getSupertype(rd);
if (rst == null) {
primary.addError("illegal receiving type for index range expression: '" + pt.getDeclaration().getName(unit) + "' is not a subtype of 'Ranged'");
} else {
List<Type> args = rst.getTypeArgumentList();
Type kt = args.get(0);
Type rt = args.get(2);
Tree.ElementRange er = (Tree.ElementRange) eor;
Tree.Expression lb = er.getLowerBound();
Tree.Expression ub = er.getUpperBound();
Tree.Expression l = er.getLength();
if (lb != null) {
checkAssignable(lb.getTypeModel(), kt, lb, "lower bound must be assignable to index type");
}
if (ub != null) {
checkAssignable(ub.getTypeModel(), kt, ub, "upper bound must be assignable to index type");
}
if (l != null) {
checkAssignable(l.getTypeModel(), unit.getIntegerType(), l, "length must be an integer");
}
that.setTypeModel(rt);
// else if (er.getLowerBound()!=null) {
if (lb != null && ub == null && l == null) {
refineTypeForTupleOpenRange(that, pt, lb.getTerm());
}
/*if (that.getIndexOperator() instanceof Tree.SafeIndexOp) {
that.setTypeModel(unit.getOptionalType(that.getTypeModel()));
}*/
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method visitIndirectInvocation.
/**
* Typecheck an indirect invocation.
*/
private void visitIndirectInvocation(Tree.InvocationExpression that) {
Tree.Term primary = unwrapExpressionUntilTerm(that.getPrimary());
if (primary == null) {
return;
}
Type pt = primary.getTypeModel();
if (!isTypeUnknown(pt)) {
if (that.getNamedArgumentList() != null) {
that.addError("named arguments not supported for indirect invocations");
return;
}
Tree.PositionalArgumentList pal = that.getPositionalArgumentList();
if (pal == null) {
return;
}
if (pt.isNothing()) {
that.setTypeModel(unit.getNothingType());
} else if (checkCallable(pt, primary, "invoked expression must be callable")) {
Interface cd = unit.getCallableDeclaration();
Type ct = pt.getSupertype(cd);
if (ct == null) {
primary.addError("invoked expression must be callable: type '" + pt.asString(unit) + "' involves a type function");
return;
}
List<Type> typeArgs = ct.getTypeArgumentList();
if (!typeArgs.isEmpty()) {
that.setTypeModel(typeArgs.get(0));
}
// typecheck arguments using the type args of Callable
if (typeArgs.size() >= 2) {
Type paramTypesAsTuple = typeArgs.get(1);
if (paramTypesAsTuple != null) {
TypeDeclaration pttd = paramTypesAsTuple.getDeclaration();
if (pttd instanceof ClassOrInterface && (pttd.isEmpty() || pttd.isTuple() || pttd.isSequence() || pttd.isSequential())) {
// we have a plain tuple type so we can check the
// arguments individually
checkIndirectInvocationArguments(that, paramTypesAsTuple, unit.getTupleElementTypes(paramTypesAsTuple), unit.isTupleLengthUnbounded(paramTypesAsTuple), unit.isTupleVariantAtLeastOne(paramTypesAsTuple), unit.getTupleMinimumLength(paramTypesAsTuple));
} else {
// we have something exotic, a union of tuple types
// or whatever, so just check the whole argument tuple
Type tt = getTupleType(pal.getPositionalArguments(), unit, false);
checkAssignable(tt, paramTypesAsTuple, pal, "argument list type must be assignable to parameter list type");
}
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class AnalyzerUtil method getTupleType.
public static Type getTupleType(List<Tree.PositionalArgument> es, Unit unit, boolean requireSequential) {
Type result = unit.getEmptyType();
Type ut = unit.getNothingType();
Class td = unit.getTupleDeclaration();
Interface id = unit.getIterableDeclaration();
for (int i = es.size() - 1; i >= 0; i--) {
Tree.PositionalArgument a = es.get(i);
Type t = a.getTypeModel();
if (t != null) {
// unit.denotableType(t);
Type et = t;
if (a instanceof Tree.SpreadArgument) {
/*if (requireSequential) {
checkSpreadArgumentSequential((Tree.SpreadArgument) a, et);
}*/
if (unit.isIterableType(et)) {
ut = unit.getIteratedType(et);
result = spreadType(et, unit, requireSequential);
} else if (unit.isJavaIterableType(et)) {
ut = unit.getJavaIteratedType(et);
result = unit.getSequentialType(ut);
} else if (unit.isJavaArrayType(et)) {
ut = unit.getJavaArrayElementType(et);
result = unit.getSequentialType(ut);
} else {
result = unit.getUnknownType();
}
} else if (a instanceof Tree.Comprehension) {
ut = et;
Tree.Comprehension c = (Tree.Comprehension) a;
Tree.InitialComprehensionClause icc = c.getInitialComprehensionClause();
result = icc.getPossiblyEmpty() ? unit.getSequentialType(et) : unit.getSequenceType(et);
if (!requireSequential) {
Type it = appliedType(id, et, icc.getFirstTypeModel());
result = intersectionType(result, it, unit);
}
} else {
ut = unionType(ut, et, unit);
result = appliedType(td, ut, et, result);
}
}
}
return result;
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class DeclarationVisitor method visit.
@Override
public void visit(Tree.Enumerated that) {
Constructor e = new Constructor();
that.setEnumerated(e);
visitDeclaration(that, e, false);
Type at;
if (scope instanceof Class) {
Class clazz = (Class) scope;
Type ot = clazz.getType();
e.setExtendedType(ot);
at = e.appliedType(ot, NO_TYPE_ARGS);
clazz.setEnumerated(true);
if (clazz.isAnonymous()) {
that.addError("anonymous class may not have a value constructor: '" + clazz.getName() + "' is an anonymous class");
} else if (clazz.isAbstract()) {
that.addError("abstract class may not have a value constructor: '" + clazz.getName() + "' is abstract");
} else if (!clazz.getTypeParameters().isEmpty()) {
that.addError("generic class may not have a value constructor: '" + clazz.getName() + "' is generic");
} else if (scope.getContainer() instanceof Interface) {
that.addError("class nested inside an interface may not have a value constructor: '" + clazz.getName() + "' belongs to an interface");
}
} else {
at = null;
that.addError("value constructor declaration must occur directly in the body of a class");
}
Value v = new Value();
v.setType(at);
that.setDeclarationModel(v);
visitDeclaration(that, v);
Scope o = enterScope(e);
super.visit(that);
exitScope(o);
v.setImplemented(that.getBlock() != null);
}
Aggregations