use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration 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.TypedDeclaration in project ceylon by eclipse.
the class ExpressionVisitor method visitInvocationPrimary.
private void visitInvocationPrimary(Tree.InvocationExpression that, Tree.StaticMemberOrTypeExpression reference) {
if (reference instanceof Tree.QualifiedMemberOrTypeExpression) {
Tree.QualifiedMemberOrTypeExpression qmte = (Tree.QualifiedMemberOrTypeExpression) reference;
Tree.Term term = unwrapExpressionUntilTerm(qmte.getPrimary());
if (term instanceof Tree.StaticMemberOrTypeExpression) {
Tree.StaticMemberOrTypeExpression pmte = (Tree.StaticMemberOrTypeExpression) term;
visitInvocationPrimary(that, pmte);
}
}
Tree.TypeArguments tas = reference.getTypeArguments();
if (reference instanceof Tree.BaseTypeExpression) {
Tree.BaseTypeExpression bte = (Tree.BaseTypeExpression) reference;
TypeDeclaration type = resolveBaseTypeExpression(bte, true);
if (type != null) {
setArgumentParameters(that, type);
Type receivingType = getBaseReceivingType(that, type);
List<Type> typeArgs = getOrInferTypeArguments(that, type, reference, receivingType);
if (typeArgs != null) {
tas.setTypeModels(typeArgs);
} else {
typeArgs = tas.getTypeModels();
}
visitBaseTypeExpression(bte, type, typeArgs, tas, receivingType);
}
} else if (reference instanceof Tree.QualifiedTypeExpression) {
Tree.QualifiedTypeExpression qte = (Tree.QualifiedTypeExpression) reference;
TypeDeclaration type = resolveQualifiedTypeExpression(qte, true);
if (type != null) {
setArgumentParameters(that, type);
Type receivingType = getReceivingType(qte);
List<Type> typeArgs = getOrInferTypeArguments(that, type, reference, unwrap(receivingType, qte));
if (typeArgs != null) {
tas.setTypeModels(typeArgs);
} else {
typeArgs = tas.getTypeModels();
}
Tree.Primary primary = qte.getPrimary();
if (primary instanceof Tree.Package) {
visitBaseTypeExpression(qte, type, typeArgs, tas, null);
} else {
visitQualifiedTypeExpression(qte, receivingType, type, typeArgs, tas);
}
}
} else if (reference instanceof Tree.BaseMemberExpression) {
Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) reference;
TypedDeclaration base = resolveBaseMemberExpression(bme, true);
if (base != null) {
setArgumentParameters(that, base);
Type receivingType = getBaseReceivingType(that, base);
List<Type> typeArgs = getOrInferTypeArguments(that, base, reference, receivingType);
if (typeArgs != null) {
tas.setTypeModels(typeArgs);
} else {
typeArgs = tas.getTypeModels();
}
visitBaseMemberExpression(bme, base, typeArgs, tas, receivingType);
}
} else if (reference instanceof Tree.QualifiedMemberExpression) {
Tree.QualifiedMemberExpression qme = (Tree.QualifiedMemberExpression) reference;
TypedDeclaration member = resolveQualifiedMemberExpression(qme, true);
if (member != null) {
setArgumentParameters(that, member);
Type receivingType = getReceivingType(qme);
List<Type> typeArgs = getOrInferTypeArguments(that, member, reference, unwrap(receivingType, qme));
if (typeArgs != null) {
tas.setTypeModels(typeArgs);
} else {
typeArgs = tas.getTypeModels();
}
Tree.Primary primary = qme.getPrimary();
if (primary instanceof Tree.Package) {
visitBaseMemberExpression(qme, member, typeArgs, tas, null);
} else {
visitQualifiedMemberExpression(qme, receivingType, member, typeArgs, tas);
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.QualifiedMemberExpression that) {
super.visit(that);
boolean notIndirectlyInvoked = !that.getIndirectlyInvoked();
boolean notDirectlyInvoked = !that.getDirectlyInvoked();
TypedDeclaration member = resolveQualifiedMemberExpression(that, notIndirectlyInvoked);
boolean inferrableAnyway = !notDirectlyInvoked && inferrableAnyway(member);
if (member != null && notDirectlyInvoked || inferrableAnyway) {
Tree.Primary primary = that.getPrimary();
Tree.TypeArguments tal = that.getTypeArguments();
Type receiverType = primary.getTypeModel().resolveAliases();
if (receiverType.isTypeConstructor()) {
that.addError("missing type arguments in reference to member of generic type: the type '" + receiverType.asString(unit) + "' is a type constructor (specify explicit type arguments)");
}
List<Type> typeArgs;
if (typeConstructorArgumentsInferrable(member, that)) {
typeArgs = new TypeArgumentInference(unit).getInferredTypeArgsForFunctionRef(that, receiverType, inferrableAnyway);
} else if (explicitTypeArguments(member, tal)) {
typeArgs = getTypeArguments(tal, receiverType, member.getTypeParameters());
} else {
typeArgs = new TypeArgumentInference(unit).getInferredTypeArgsForFunctionRef(that, receiverType, inferrableAnyway);
}
if (typeArgs != null) {
tal.setTypeModels(typeArgs);
if (primary instanceof Tree.Package) {
visitBaseMemberExpression(that, member, typeArgs, tal, null);
} else {
visitQualifiedMemberExpression(that, receiverType, member, typeArgs, tal);
}
} else if (notDirectlyInvoked) {
if (primary instanceof Tree.Package) {
visitGenericBaseMemberReference(that, member);
} else {
visitGenericQualifiedMemberReference(that, receiverType, member);
}
}
if (that.getStaticMethodReference()) {
handleStaticReferenceImplicitTypeArguments(that);
}
// otherwise infer type arguments later
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class InheritanceVisitor method visit.
@Override
public void visit(Tree.Enumerated that) {
super.visit(that);
Value v = that.getDeclarationModel();
Scope container = v.getContainer();
if (container instanceof Class) {
Class cl = (Class) container;
List<TypedDeclaration> caseValues = cl.getCaseValues();
if (caseValues != null && !caseValues.contains(v) && !cl.isAbstract()) {
that.addError("value constructor is not a case of enumerated class: '" + v.getName() + "' is not listed in the 'of' clause of '" + cl.getName() + "'");
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class InheritanceVisitor method collectCaseValues.
void collectCaseValues(Tree.CaseTypes that, TypeDeclaration td) {
Unit unit = that.getUnit();
Set<Declaration> valueSet = new HashSet<Declaration>();
for (Tree.StaticMemberOrTypeExpression bme : that.getBaseMemberExpressions()) {
String name = name(bme.getIdentifier());
TypedDeclaration value = bme instanceof Tree.BaseMemberExpression ? getTypedDeclaration(bme.getScope(), name, null, false, unit) : getPackageTypedDeclaration(name, null, false, unit);
if (value != null) {
if (value != null && !valueSet.add(value)) {
// this error is not really truly necessary
bme.addError("duplicate case: '" + value.getName(unit) + "' of '" + td.getName() + "'");
}
Type type = value.getType();
if (type != null) {
TypeDeclaration caseDec = type.getDeclaration();
if (caseDec instanceof Constructor) {
Scope scope = caseDec.getContainer();
if (scope instanceof Class) {
// enumerated singleton constructors
Constructor cons = (Constructor) caseDec;
Class c = (Class) scope;
if (!c.isToplevel() && !c.isStatic()) {
bme.addError("case must be a value constructor of a toplevel or static class: '" + c.getName(unit) + "' is not toplevel");
} else if (!cons.getParameterLists().isEmpty()) {
bme.addError("case must be a value constructor of a toplevel or static class: '" + cons.getName(unit) + "' is not a value constructor");
}
/*else if (!c.inherits(unit.getIdentifiableDeclaration())) {
bme.addError("case must be a value constructor of an identifiable class: '" +
c.getName(unit) +
"' is not a subtype of 'Identifiable'");
}*/
}
} else {
// enumerated anonymous subclasses
if (!caseDec.isObjectClass()) {
bme.addError("case must be a toplevel or static anonymous class: '" + value.getName(unit) + "' is not an anonymous class");
} else if (!value.isToplevel() && !value.isStatic()) {
bme.addError("case must be a toplevel or static anonymous class: '" + value.getName(unit) + "' is neither static nor toplevel");
}
}
if (checkDirectSubtype(td, bme, type)) {
checkAssignable(type, td.getType(), bme, getCaseTypeExplanation(td, type));
}
}
}
}
}
Aggregations