use of org.eclipse.ceylon.model.typechecker.model.Type in project ceylon by eclipse.
the class ExpressionVisitor method checkForMissingNamedParameters.
private void checkForMissingNamedParameters(ParameterList pl, Reference pr, Tree.NamedArgumentList nal, Set<Parameter> foundParameters) {
StringBuilder missing = null;
int count = 0;
for (Parameter p : pl.getParameters()) {
if (!foundParameters.contains(p) && !p.isDefaulted() && (!p.isSequenced() || p.isAtLeastOne())) {
count++;
Type type = pr.getTypedParameter(p).getFullType();
if (missing == null) {
missing = new StringBuilder();
} else {
missing.append(", ");
}
if (type != null) {
missing.append(type.asString(unit)).append(" ");
}
missing.append(p.getName());
}
}
if (count == 1) {
nal.addError("missing named argument to required parameter '" + missing + "' of '" + pr.getDeclaration().getName(unit) + "'", 11000);
} else if (count > 1) {
nal.addError("missing named arguments to " + count + " required parameters '" + missing + "' of '" + pr.getDeclaration().getName(unit) + "'", 11000);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Type in project ceylon by eclipse.
the class ExpressionVisitor method checkTypeConstructorParam.
private void checkTypeConstructorParam(TypeParameter param, Type argType, Node argNode) {
if (!argType.isTypeConstructor()) {
argNode.addError("not a type constructor: '" + argType.asString(unit) + "'");
} else {
argType = unwrapAliasedTypeConstructor(argType);
if (argType.isUnion()) {
for (Type ct : argType.getCaseTypes()) {
checkTypeConstructorParam(param, ct, argNode);
}
} else if (argType.isIntersection()) {
for (Type st : argType.getSatisfiedTypes()) {
checkTypeConstructorParam(param, st, argNode);
}
} else if (argType.isNothing()) {
// just let it through?!
} else {
TypeDeclaration argTypeDec = argType.getDeclaration();
List<TypeParameter> argTypeParams = argTypeDec.getTypeParameters();
int allowed = argTypeParams.size();
int required = 0;
for (TypeParameter tp : argTypeParams) {
if (tp.isDefaulted()) {
break;
}
required++;
}
List<TypeParameter> paramTypeParams = param.getTypeParameters();
int size = paramTypeParams.size();
if (allowed < size || required > size) {
argNode.addError("argument type constructor has wrong number of type parameters: argument '" + argTypeDec.getName(unit) + "' has " + allowed + " type parameters " + "but parameter '" + param.getName(unit) + "' has " + size + " type parameters");
}
for (int j = 0; j < size && j < allowed; j++) {
TypeParameter paramParam = paramTypeParams.get(j);
TypeParameter argParam = argTypeParams.get(j);
if (paramParam.isCovariant() && !argParam.isCovariant()) {
argNode.addError("argument type constructor is not covariant: '" + argParam.getName() + "' of '" + argTypeDec.getName(unit) + "' must have the same variance as '" + paramParam.getName() + "' of '" + param.getName(unit) + "'");
} else if (paramParam.isContravariant() && !argParam.isContravariant()) {
argNode.addError("argument type constructor is not contravariant: '" + argParam.getName() + "' of '" + argTypeDec.getName(unit) + "' must have the same variance as '" + paramParam.getName() + "' of '" + param.getName(unit) + "'");
}
if (!intersectionOfSupertypes(paramParam).isSubtypeOf(intersectionOfSupertypes(argParam))) {
argNode.addError("upper bound on type parameter of argument type constructor is not a supertype of upper bound on corresponding type parameter of parameter: '" + argParam.getName() + "' of '" + argTypeDec.getName(unit) + "' does accept all type arguments accepted by '" + paramParam.getName() + "' of '" + param.getName(unit) + "'");
}
if (!unionOfCaseTypes(paramParam).isSubtypeOf(unionOfCaseTypes(argParam))) {
argNode.addError("enumerated bound on type parameter of argument type constructor is not a supertype of enumerated bound on corresponding type parameter of parameter: '" + argParam.getName() + "' of '" + argTypeDec.getName(unit) + "' does accept all type arguments accepted by '" + paramParam.getName() + "' of '" + param.getName(unit) + "'");
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Type 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.Type 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.Type in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.Outer that) {
Type oci = getOuterClassOrInterface(that.getScope());
if (oci == null) {
that.addError("'outer' occurs outside a nested class or interface definition");
} else {
that.setTypeModel(oci);
that.setDeclarationModel(oci.getDeclaration());
}
/*if (defaultArgument) {
that.addError("reference to outer from default argument expression");
}*/
}
Aggregations