use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class ExpressionVisitor method resetSuperReference.
void resetSuperReference(Tree.QualifiedMemberOrTypeExpression that) {
// Just for the IDE!
Tree.Term p = that.getPrimary();
if (p instanceof Tree.Super) {
Declaration dec = that.getDeclaration();
if (dec != null) {
Tree.Super s = (Tree.Super) p;
TypeDeclaration td = (TypeDeclaration) dec.getContainer();
s.setDeclarationModel(td);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.MemberLiteral that) {
if (that instanceof Tree.FunctionLiteral || that instanceof Tree.ValueLiteral) {
declarationLiteral = true;
} else {
modelLiteral = true;
}
try {
super.visit(that);
} finally {
declarationLiteral = false;
modelLiteral = false;
}
Tree.Identifier id = that.getIdentifier();
if (id != null) {
String name = name(id);
Tree.StaticType type = that.getType();
if (type == null) {
TypedDeclaration result;
if (that.getPackageQualified()) {
result = getPackageTypedDeclaration(name, null, false, unit);
} else {
result = getTypedDeclaration(that.getScope(), name, null, false, unit);
}
if (result != null) {
checkBaseVisibility(that, result, name);
setMemberMetatype(that, result);
} else {
that.addError("function or value is not defined: '" + name(id) + "'", 100);
unit.setUnresolvedReferences();
}
} else {
TypeDeclaration qtd = type.getTypeModel().getDeclaration();
// checkNonlocalType(that.getType(), qtd);
String container = "type '" + qtd.getName(unit) + "'";
TypedDeclaration member = getTypedMember(qtd, name, null, false, unit, that.getScope());
if (member == null) {
if (qtd.isMemberAmbiguous(name, unit, null, false)) {
that.addError("method or attribute is ambiguous: '" + name + "' for " + container);
} else {
that.addError("method or attribute is not defined: '" + name + "' in " + container);
}
} else {
checkQualifiedVisibility(that, member, name, container, false);
setMemberMetatype(that, member);
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration 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.TypeDeclaration in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.BaseType that) {
super.visit(that);
TypeDeclaration type = that.getDeclarationModel();
if (type != null) {
type = (TypeDeclaration) handleNativeHeader(type, that, true);
if (!type.isVisible(that.getScope())) {
that.addError("type is not visible: " + baseDescription(that), 400);
} else if (type.isPackageVisibility() && !declaredInPackage(type, unit)) {
that.addError("type is not visible: " + baseDescription(that) + "is package private");
}
// don't need to consider "protected" because
// toplevel types can't be declared protected
// and inherited protected member types are
// visible to subclasses
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration 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");
}
}
}
}
}
}
Aggregations