use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class TypeVisitor method visit.
public void visit(Tree.SuperType that) {
// if (inExtendsClause) { //can't appear anywhere else in the tree!
Scope scope = that.getScope();
ClassOrInterface ci = getContainingClassOrInterface(scope);
if (ci != null) {
if (scope instanceof Constructor) {
that.setTypeModel(intersectionOfSupertypes(ci));
} else if (ci.isClassOrInterfaceMember()) {
ClassOrInterface oci = (ClassOrInterface) ci.getContainer();
that.setTypeModel(intersectionOfSupertypes(oci));
} else {
that.addError("super appears in extends for non-member class");
}
}
// }
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class AnalyzerUtil method notAssignableMessage.
static String notAssignableMessage(Type type, Type supertype, Node node) {
Unit unit = node.getUnit();
if (supertype.covers(type)) {
return ": the assigned type '" + type.asString(unit) + "' is covered by, but not assignable to, the type '" + supertype.asString(unit) + "' (explicitly narrow assigned expression using 'of " + supertype.asString(unit) + "')";
}
String result = typingMessage(type, " is not assignable to ", supertype, unit);
if (unit.getDefiniteType(type).isSubtypeOf(supertype)) {
return result + " (the assigned type contains 'null')";
} else if (unit.isCallableType(type) && unit.getCallableReturnType(type).isSubtypeOf(supertype)) {
return result + " (specify arguments to the function reference)";
} else {
TypeDeclaration typeDec = type.getDeclaration();
TypeDeclaration supertypeDec = supertype.getDeclaration();
if (typeDec instanceof ClassOrInterface && supertypeDec instanceof ClassOrInterface && typeDec.isToplevel() && supertypeDec.isToplevel()) {
String typeName = typeDec.getName();
String supertypeName = supertypeDec.getName();
if (typeName.equals(supertypeName)) {
String typePackage = typeDec.getUnit().getPackage().getNameAsString();
String supertypePackage = supertypeDec.getUnit().getPackage().getNameAsString();
if (typePackage.startsWith("ceylon.") && supertypePackage.startsWith("java.")) {
return result + " (Java '" + supertypeName + "' is not the same type as Ceylon '" + typeName + "')";
}
if (typePackage.startsWith("java.") && supertypePackage.startsWith("ceylon.")) {
return result + " (Ceylon '" + supertypeName + "' is not the same type as Java '" + typeName + "')";
}
}
}
return result;
}
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.TypeLiteral that) {
if (that instanceof Tree.InterfaceLiteral || that instanceof Tree.ClassLiteral || that instanceof Tree.NewLiteral || that instanceof Tree.AliasLiteral || that instanceof Tree.TypeParameterLiteral) {
declarationLiteral = true;
} else {
modelLiteral = true;
}
try {
super.visit(that);
} finally {
declarationLiteral = false;
modelLiteral = false;
}
Type t;
TypeDeclaration d;
Tree.StaticType type = that.getType();
Node errorNode;
if (type != null) {
t = type.getTypeModel();
d = t.getDeclaration();
errorNode = type;
} else {
errorNode = that;
ClassOrInterface classOrInterface = getContainingClassOrInterface(that.getScope());
if (that instanceof Tree.ClassLiteral || that instanceof Tree.InterfaceLiteral) {
d = classOrInterface;
if (d == null) {
errorNode.addError("no containing type");
// EARLY EXIT!!
return;
} else {
t = classOrInterface.getType();
}
} else {
errorNode.addError("missing type reference");
// EARLY EXIT!!
return;
}
}
if (t != null) {
that.setDeclaration(d);
that.setWantsDeclaration(true);
if (that instanceof Tree.ClassLiteral) {
if (!(d instanceof Class)) {
if (d != null) {
errorNode.addError("referenced declaration is not a class" + getDeclarationReferenceSuggestion(d));
}
that.setTypeModel(unit.getClassDeclarationType());
} else {
that.setTypeModel(unit.getClassDeclarationType((Class) d));
}
} else if (that instanceof Tree.NewLiteral) {
if (d instanceof Class) {
Class c = (Class) d;
Constructor defaultConstructor = c.getDefaultConstructor();
if (defaultConstructor != null) {
d = defaultConstructor;
}
}
if (d instanceof Constructor) {
Constructor c = (Constructor) d;
if (c.getParameterList() == null) {
that.setTypeModel(unit.getValueConstructorDeclarationType());
} else {
that.setTypeModel(unit.getCallableConstructorDeclarationType());
}
} else if (d != null) {
errorNode.addError("referenced declaration is not a constructor" + getDeclarationReferenceSuggestion(d));
}
} else if (that instanceof Tree.InterfaceLiteral) {
if (!(d instanceof Interface)) {
if (d != null) {
errorNode.addError("referenced declaration is not an interface" + getDeclarationReferenceSuggestion(d));
}
}
that.setTypeModel(unit.getInterfaceDeclarationType());
} else if (that instanceof Tree.AliasLiteral) {
if (!(d instanceof TypeAlias)) {
errorNode.addError("referenced declaration is not a type alias" + getDeclarationReferenceSuggestion(d));
}
that.setTypeModel(unit.getAliasDeclarationType());
} else if (that instanceof Tree.TypeParameterLiteral) {
if (!(d instanceof TypeParameter)) {
errorNode.addError("referenced declaration is not a type parameter" + getDeclarationReferenceSuggestion(d));
}
that.setTypeModel(unit.getTypeParameterDeclarationType());
} else if (d != null) {
that.setWantsDeclaration(false);
t = t.resolveAliases();
if (t == null || t.isUnknown()) {
return;
}
// checkNonlocalType(that.getType(), t.getDeclaration());
if (d instanceof Constructor) {
if (((Constructor) d).isAbstraction()) {
errorNode.addError("constructor is overloaded");
} else {
that.setTypeModel(unit.getConstructorMetatype(t));
}
} else if (d instanceof Class) {
// checkNonlocal(that, t.getDeclaration());
that.setTypeModel(unit.getClassMetatype(t));
} else if (d instanceof Interface) {
that.setTypeModel(unit.getInterfaceMetatype(t));
} else {
that.setTypeModel(unit.getTypeMetaType(t));
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class ExpressionVisitor method checkSuperInvocation.
private void checkSuperInvocation(Tree.MemberOrTypeExpression qmte, List<Type> signature, boolean spread) {
Declaration member = qmte.getDeclaration();
if (member != null) {
String name = member.getName();
TypeDeclaration type = (TypeDeclaration) member.getContainer();
if (member.isFormal() && !inExtendsClause) {
qmte.addError("supertype member is declared formal: '" + name + "' of '" + type.getName() + "'");
} else {
Scope scope = qmte.getScope();
ClassOrInterface ci = getContainingClassOrInterface(scope);
if (ci != null) {
List<TypeDeclaration> refiners = new ArrayList<TypeDeclaration>(1);
Type et = ci.getExtendedType();
if (et != null) {
Declaration etm = et.getDeclaration().getMember(name, signature, spread);
if (etm != null && !etm.getContainer().equals(type) && etm.refines(member)) {
TypeDeclaration container = (TypeDeclaration) etm.getContainer();
refiners.add(container);
}
}
for (Type st : ci.getSatisfiedTypes()) {
Declaration stm = st.getDeclaration().getMember(name, signature, spread);
if (stm != null && !stm.getContainer().equals(type) && stm.refines(member)) {
TypeDeclaration container = (TypeDeclaration) stm.getContainer();
refiners.add(container);
}
}
if (refiners.size() == 1) {
TypeDeclaration r = refiners.get(0);
if (r instanceof Class) {
qmte.addError("inherited member is refined by intervening superclass: '" + r.getName() + "' refines '" + name + "' declared by '" + type.getName() + "'");
} else {
qmte.addError("inherited member is refined by intervening superinterface: '" + r.getName() + "' refines '" + name + "' declared by '" + type.getName() + "'");
}
} else if (!refiners.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (TypeDeclaration r : refiners) {
if (sb.length() > 0) {
sb.append(", ");
}
sb.append('\'').append(r.getName()).append('\'');
}
qmte.addError("inherited member is refined by intervening supertypes: '" + name + "' declared by '" + type.getName() + "' is refined by intervening types " + sb);
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class TypeUtils method resolveTypeParameter.
/**
* Finds the owner of the type parameter and outputs a reference to the corresponding type argument.
*/
static void resolveTypeParameter(final Node node, final TypeParameter tp, final GenerateJsVisitor gen, final boolean skipSelfDecl) {
Scope parent = ModelUtil.getRealScope(node.getScope());
int outers = 0;
while (parent != null && parent != tp.getContainer()) {
if (parent instanceof TypeDeclaration && !(parent instanceof Constructor || ((TypeDeclaration) parent).isAnonymous())) {
outers++;
}
parent = parent.getScope();
}
if (tp.getContainer() instanceof ClassOrInterface) {
if (parent == tp.getContainer()) {
if (!skipSelfDecl) {
TypeDeclaration ontoy = ModelUtil.getContainingClassOrInterface(node.getScope());
while (ontoy.isAnonymous()) ontoy = ModelUtil.getContainingClassOrInterface(ontoy.getScope());
gen.out(gen.getNames().self(ontoy));
if (ontoy == parent)
outers--;
for (int i = 0; i < outers; i++) {
gen.out(".outer$");
}
gen.out(".");
}
gen.out("$$targs$$.", gen.getNames().typeParameterName(tp));
} else {
// This can happen in expressions such as Singleton(n) when n is dynamic
gen.out("{/*NO PARENT*/t:", gen.getClAlias(), "Anything}");
}
} else if (tp.getContainer() instanceof TypeAlias) {
if (parent == tp.getContainer()) {
gen.out("'", gen.getNames().typeParameterName(tp), "'");
} else {
// This can happen in expressions such as Singleton(n) when n is dynamic
gen.out("{/*NO PARENT ALIAS*/t:", gen.getClAlias(), "Anything}");
}
} else {
// it has to be a method, right?
// We need to find the index of the parameter where the argument occurs
// ...and it could be null...
Type type = null;
for (Iterator<ParameterList> iter0 = ((Function) tp.getContainer()).getParameterLists().iterator(); type == null && iter0.hasNext(); ) {
for (Iterator<Parameter> iter1 = iter0.next().getParameters().iterator(); iter1.hasNext(); ) {
type = typeContainsTypeParameter(iter1.next().getType(), tp);
}
}
// A type argument of the argument's type, in which case we must get the reified generic from the argument
if (tp.getContainer() == parent) {
gen.out(gen.getNames().typeArgsParamName((Function) tp.getContainer()), ".", gen.getNames().typeParameterName(tp));
} else {
if (parent == null && node instanceof Tree.StaticMemberOrTypeExpression) {
if (tp.getContainer() == ((Tree.StaticMemberOrTypeExpression) node).getDeclaration()) {
type = ((Tree.StaticMemberOrTypeExpression) node).getTarget().getTypeArguments().get(tp);
typeNameOrList(node, type, gen, skipSelfDecl);
return;
}
}
gen.out("'", gen.getNames().typeParameterName(tp), "'");
// gen.out.spitOut("Passing reference to " + tp.getQualifiedNameString() + " as a string...");
// gen.out("/*Please report this to the ceylon-js team: METHOD TYPEPARM plist ",
// Integer.toString(plistCount), "#", tp.getName(), "*/'", type.getProducedTypeQualifiedName(),
// "' container " + tp.getContainer() + " at " + node);
}
}
}
Aggregations