use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class RefinementVisitor method checkOverloadedParameters.
private void checkOverloadedParameters(Tree.Declaration that, Declaration member) {
String name = member.getName();
Declaration abstraction = member.getScope().getDirectMember(name, null, false);
if (abstraction != null) {
Functional fun = (Functional) member;
List<Parameter> parameters = fun.getFirstParameterList().getParameters();
for (Parameter param : parameters) {
if (param.isDefaulted()) {
that.addError("overloaded function parameter must be required: parameter '" + param.getName() + "' is defaulted");
}
}
Unit unit = that.getUnit();
for (Declaration dec : abstraction.getOverloads()) {
if (dec == member)
break;
Functional other = (Functional) dec;
List<Parameter> otherParams = other.getFirstParameterList().getParameters();
if (otherParams.size() == parameters.size()) {
boolean allSame = true;
for (int i = 0; i < parameters.size(); i++) {
TypeDeclaration paramType = erasedType(parameters.get(i), unit);
TypeDeclaration otherType = erasedType(otherParams.get(i), unit);
if (paramType != null && otherType != null && !paramType.equals(otherType)) {
allSame = false;
break;
}
}
if (allSame) {
that.addError("non-unique parameter list erasure for overloaded function: each overloaded declaration of '" + name + "' must have a distinct parameter list erasure");
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class SelfReferenceVisitor method checkSelfReference.
private void checkSelfReference(Node that, Tree.Term term) {
Tree.Term t = eliminateParensAndWidening(term);
if (directlyInBody() && t instanceof Tree.Super) {
that.addError("leaks 'super' reference: '" + typeDeclaration.getName() + "'");
}
if (mayNotLeakThis() && t instanceof Tree.This) {
that.addError("leaks 'this' reference in initializer: '" + typeDeclaration.getName() + "'");
}
if (mayNotLeakOuter() && t instanceof Tree.Outer) {
that.addError("leaks 'outer' reference in initializer: '" + typeDeclaration.getName() + "'");
}
if (typeDeclaration.isObjectClass() && mayNotLeakAnonymousClass() && t instanceof Tree.BaseMemberExpression) {
Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) t;
Declaration declaration = bme.getDeclaration();
if (declaration instanceof TypedDeclaration) {
TypedDeclaration td = (TypedDeclaration) declaration;
if (td.getTypeDeclaration() == typeDeclaration) {
that.addError("anonymous class leaks self reference in initializer: '" + typeDeclaration.getName() + "'");
}
}
}
if (typeDeclaration.isObjectClass() && mayNotLeakAnonymousClass() && t instanceof Tree.QualifiedMemberExpression) {
Tree.QualifiedMemberExpression qme = (Tree.QualifiedMemberExpression) t;
if (qme.getPrimary() instanceof Tree.Outer) {
Declaration declaration = qme.getDeclaration();
if (declaration instanceof TypedDeclaration) {
TypedDeclaration td = (TypedDeclaration) declaration;
if (td.getTypeDeclaration() == typeDeclaration) {
that.addError("anonymous class leaks self reference in initializer: '" + typeDeclaration.getName() + "'");
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class SupertypeVisitor method checkForUndecidability.
private void checkForUndecidability(Tree.ExtendedType etn, Tree.SatisfiedTypes stn, TypeDeclaration type, Tree.TypeDeclaration that) {
boolean errors = false;
if (stn != null) {
for (Tree.StaticType st : stn.getTypes()) {
Type t = st.getTypeModel();
if (t != null) {
TypeDeclaration td = t.getDeclaration();
if (!(td instanceof UnknownType) && !(td instanceof TypeAlias)) {
if (td == type) {
brokenSatisfiedType(type, st, null);
errors = true;
} else {
List<TypeDeclaration> list = t.isRecursiveRawTypeDefinition(singleton(type));
if (!list.isEmpty()) {
brokenSatisfiedType(type, st, list);
errors = true;
}
}
}
}
}
}
if (etn != null) {
Tree.StaticType et = etn.getType();
if (et != null) {
Type t = et.getTypeModel();
if (t != null) {
TypeDeclaration td = t.getDeclaration();
if (!(td instanceof UnknownType) && !(td instanceof TypeAlias)) {
if (td == type) {
brokenExtendedType(type, et, null);
errors = true;
} else {
List<TypeDeclaration> list = t.isRecursiveRawTypeDefinition(singleton(type));
if (!list.isEmpty()) {
brokenExtendedType(type, et, list);
errors = true;
}
}
}
}
}
}
if (!errors) {
Unit unit = type.getUnit();
List<Type> list = new ArrayList<Type>();
try {
List<Type> supertypes = type.getType().getSupertypes();
for (Type st : supertypes) {
addToIntersection(list, st, unit);
}
// probably unnecessary - if it were
// going to blow up, it would have
// already blown up in addToIntersection()
canonicalIntersection(list, unit);
} catch (DecidabilityException re) {
brokenHierarchy(type, that, unit);
return;
}
try {
type.getType().getUnionOfCases();
} catch (DecidabilityException re) {
brokenSelfType(type, that);
}
if (stn != null) {
for (Tree.StaticType st : stn.getTypes()) {
Type t = st.getTypeModel();
if (t != null) {
if (checkSupertypeVariance(t, type, st)) {
type.getSatisfiedTypes().remove(t);
type.clearProducedTypeCache();
}
}
}
}
if (etn != null) {
Tree.StaticType et = etn.getType();
if (et != null) {
Type t = et.getTypeModel();
if (t != null) {
if (checkSupertypeVariance(t, type, et)) {
type.setExtendedType(unit.getBasicType());
type.clearProducedTypeCache();
}
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class SupertypeVisitor method checkSupertypeVariance.
private boolean checkSupertypeVariance(Type type, TypeDeclaration d, Node node) {
List<TypeDeclaration> errors = type.resolveAliases().checkDecidability();
if (displayErrors) {
for (TypeDeclaration td : errors) {
Unit unit = node.getUnit();
node.addError("type with contravariant type parameter '" + td.getName() + "' appears in contravariant or invariant location in supertype: '" + type.asString(unit) + "'");
}
}
return !errors.isEmpty();
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class TypeArgumentInference method getInferredTypeArgsForStaticReference.
/**
* Infer type arguments for the qualifying type in a
* static method reference that is directly invoked.
* This method does not correctly handle stuff like
* constructors or Java static methods.
*
* @param that the invocation
* @param type the type whose type arguments we're
* inferring (the qualifying type)
* @param receiverType
*/
List<Type> getInferredTypeArgsForStaticReference(Tree.InvocationExpression that, TypeDeclaration type, Type receiverType, Tree.MemberOrTypeExpression primary) {
Tree.PositionalArgumentList pal = that.getPositionalArgumentList();
Declaration invoked = primary.getDeclaration();
if (pal == null) {
return null;
} else {
if (invoked instanceof Functional) {
List<PositionalArgument> args = pal.getPositionalArguments();
Functional fun = (Functional) invoked;
List<ParameterList> parameterLists = fun.getParameterLists();
if (args.isEmpty() || parameterLists.isEmpty()) {
return null;
} else {
// a static method ref invocation has exactly
// one meaningful argument (the instance of
// the receiving type)
Tree.PositionalArgument arg = args.get(0);
if (arg == null) {
return null;
} else {
Type at = arg.getTypeModel();
Type tt = type.getType();
List<TypeParameter> typeParams = type.getTypeParameters();
List<Type> typeArgs = new ArrayList<Type>(typeParams.size());
for (TypeParameter tp : typeParams) {
Type it = inferTypeArg(tp, tt, at, // TODO: is this 100% correct?
false, arg);
if (it == null || it.containsUnknowns()) {
that.addError("could not infer type argument from given arguments: type parameter '" + tp.getName() + "' could not be inferred");
}
typeArgs.add(it);
}
return constrainInferredTypes(typeParams, typeArgs, receiverType, invoked);
}
}
} else {
return null;
}
}
}
Aggregations