use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class RefinementVisitor method visit.
@Override
public void visit(Tree.Declaration that) {
super.visit(that);
Declaration dec = that.getDeclarationModel();
if (dec != null) {
boolean mayBeShared = dec.isToplevel() || dec.isClassOrInterfaceMember();
if (dec.isShared() && !mayBeShared) {
that.addError("shared declaration is not a member of a class, interface, or package: " + message(dec) + " may not be annotated 'shared'", 1200);
}
boolean mayBeRefined = dec instanceof Value || dec instanceof Function || dec instanceof Class;
if (!mayBeRefined) {
checkNonrefinableDeclaration(that, dec);
}
boolean member = dec.isClassOrInterfaceMember() && dec.isShared() && !isConstructor(dec) && // TODO: what about nested interfaces and abstract classes?!
!(dec instanceof TypeParameter);
if (member) {
checkMember(that, dec);
} else {
checkNonMember(that, dec);
}
if (dec.isNativeImplementation() || isNativeMember(dec)) {
checkNative(that, dec);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class SpecificationVisitor method checkReference.
private void checkReference(Node that, Declaration member, boolean assigned, boolean metamodel) {
Scope scope = that.getScope();
if ((member == declaration || isDelegationToDefaultConstructor(member)) && declaration.isDefinedInScope(scope) && // TODO: THIS IS TERRIBLE!!!!!
!isReferenceToNativeHeaderMember(scope)) {
if (!declared) {
if (!metamodel && !isForwardReferenceable() && !hasParameter) {
Scope container = declaration.getContainer();
if (container instanceof Class) {
that.addError("forward reference to class member in initializer: " + name() + " is not yet declared (forward references must occur in declaration section)");
} else {
that.addError("forward reference to local declaration: " + name() + " is not yet declared");
}
}
} else if (!definitely || declaration.isFormal()) {
// section or interface
if (declaration.isFormal()) {
if (!isForwardReferenceable()) {
that.addError("formal member may not be used in initializer: " + name() + " is declared 'formal'");
}
} else if (!metamodel && !isNativeHeader(declaration) && !isLate()) {
String message = "not definitely " + (isVariable() ? "initialized" : "specified") + ": " + name() + " has not been assigned " + (declaration instanceof Value ? "a value" : "a definition") + " by every conditional branch";
that.addError(message);
}
} else if (parameter != null) {
Declaration paramDec = parameter.getDeclaration();
if (isConstructor(paramDec) && !declaration.isStatic() && paramDec.getContainer().equals(declaration.getContainer())) {
that.addError("default argument to constructor parameter is a member of the constructed class");
}
}
if (!assigned && declaration.isDefault() && !isForwardReferenceable()) {
that.addError("default member may not be used in initializer: " + name() + " is declared 'default'");
}
if (definitely && isVariable() && inLazyExpression) {
if (inParameter) {
Declaration paramDec = parameter.getDeclaration();
if (paramDec.equals(declaration.getContainer())) {
that.addError("value may not be captured by lazy expression in default argument: " + name() + " is declared 'variable'");
}
}
if (inExtends) {
if (declaration.isClassOrInterfaceMember() && getContainingClassOrInterface(scope).equals(declaration.getContainer())) {
that.addError("value may not be captured by lazy expression in extends clause: " + name() + " is declared 'variable'");
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Class 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.Class 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));
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class InheritanceVisitor method checkSelfTypes.
private void checkSelfTypes(Tree.StaticType that, TypeDeclaration td, Type type) {
if (!(td instanceof TypeParameter)) {
// TODO: is this really ok?!
List<TypeParameter> params = type.getDeclaration().getTypeParameters();
List<Type> args = type.getTypeArgumentList();
Unit unit = that.getUnit();
for (int i = 0; i < params.size(); i++) {
TypeParameter param = params.get(i);
if (param.isSelfType() && !args.isEmpty()) {
Type arg = args.get(i);
if (arg == null) {
arg = unit.getUnknownType();
}
TypeDeclaration std = param.getSelfTypedDeclaration();
Type at;
TypeDeclaration mtd;
if (param.getContainer().equals(std)) {
at = td.getType();
mtd = td;
} else {
// TODO: lots wrong here?
mtd = (TypeDeclaration) td.getMember(std.getName(), null, false);
at = mtd == null ? null : mtd.getType();
}
if (at != null && !at.isSubtypeOf(arg)) {
Type st = mtd.getSelfType();
if (st == null || !st.isExactly(arg)) {
String help = "";
TypeDeclaration atd = at.getDeclaration();
TypeDeclaration ad = arg.getDeclaration();
if (ad instanceof TypeParameter) {
TypeParameter tp = (TypeParameter) ad;
if (tp.getDeclaration().equals(td)) {
help = " (try making '" + ad.getName() + "' a self type of '" + td.getName() + "')";
}
} else if (ad instanceof Interface) {
help = " (try making " + message(atd) + " satisfy '" + ad.getName() + "')";
} else if (ad instanceof Class && td instanceof Class) {
help = " (try making " + message(atd) + " extend '" + ad.getName() + "')";
}
that.addError("type argument does not satisfy self type constraint on type parameter '" + param.getName() + "' of '" + type.getDeclaration().getName(unit) + "': '" + arg.asString(unit) + "' is not a supertype or self type of " + message(atd) + help);
}
}
}
}
}
}
Aggregations