use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class TypeArgumentInference method inferNullaryFunctionCallTypeArgs.
/**
* Infer type arguments for the invocation of a
* nullary function that occurs as an argument.
* The parameter to which it is an argument isn't
* a callable parameter.
*/
private List<Type> inferNullaryFunctionCallTypeArgs(Tree.StaticMemberOrTypeExpression smte, Type receiverType, Declaration reference, List<TypeParameter> typeParameters, Type paramType, Declaration parameterizedDec) {
Reference arg = appliedReference(smte);
List<Type> inferredTypes = new ArrayList<Type>(typeParameters.size());
Type argType = arg.getType();
TypeDeclaration ptd = paramType.getDeclaration();
Type template = // all supertypes of argType?
ptd instanceof ClassOrInterface ? argType.getSupertype(ptd) : argType;
for (TypeParameter tp : typeParameters) {
boolean covariant = template.occursCovariantly(tp) && !template.occursContravariantly(tp);
boolean contravariant = template.occursContravariantly(tp) && !template.occursCovariantly(tp);
Type it = inferNullaryFunctionCallTypeArg(smte, tp, paramType, parameterizedDec, template, covariant, contravariant);
inferredTypes.add(it);
}
return constrainInferredTypes(typeParameters, inferredTypes, receiverType, reference);
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class TypeArgumentInference method appliedReference.
private Reference appliedReference(Tree.StaticMemberOrTypeExpression smte) {
// TODO: this might not be right for static refs
Declaration dec = smte.getDeclaration();
if (smte.getStaticMethodReferencePrimary()) {
// TODO: why this special case, exactly?
TypeDeclaration td = (TypeDeclaration) dec;
return td.getType();
} else {
List<Type> list;
if (dec.isParameterized()) {
list = typeParametersAsArgList(dec);
} else {
list = NO_TYPE_ARGS;
}
Type qt = getQualifyingType(smte);
return dec.appliedReference(qt, list);
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration 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.TypeDeclaration in project ceylon by eclipse.
the class ImportVisitor method importMember.
private String importMember(Tree.ImportMemberOrType member, TypeDeclaration td, ImportList il) {
Tree.Identifier id = member.getIdentifier();
if (id == null) {
return null;
}
Import i = new Import();
member.setImportModel(i);
Tree.Alias alias = member.getAlias();
String name = name(id);
if (alias == null) {
i.setAlias(name);
} else {
i.setAlias(name(alias.getIdentifier()));
}
Declaration m = td.getMember(name, null, false);
if (m == null && td.isJava()) {
String newName = adaptJavaName(name);
m = td.getMember(newName, null, false);
}
if (m == null) {
id.addError("imported declaration not found: '" + name + "' of '" + td.getName() + "'" + memberCorrectionMessage(name, td, null, unit, cancellable), 100);
unit.setUnresolvedReferences();
} else {
List<Declaration> members = m.getContainer().getMembers();
for (Declaration d : members) {
String dn = d.getName();
if (dn != null && dn.equals(name) && !d.sameKind(m) && !d.isAnonymous()) {
// crazy interop cases like isOpen() + open()
id.addError("ambiguous member declaration: '" + name + "' of '" + td.getName() + "' is ambiguous");
return null;
}
}
if (!m.isShared()) {
id.addError("imported declaration is not visible: '" + name + "' of '" + td.getName() + "' is not shared", 400);
} else if (!m.withinRestrictions(unit)) {
id.addError("imported declaration is not visible: '" + name + "' of '" + td.getName() + "' is restricted", 400);
} else if (!declaredInPackage(m, unit)) {
if (m.isPackageVisibility()) {
id.addError("imported declaration is not visible: '" + name + "' of '" + td.getName() + "' is package private");
} else if (m.isProtectedVisibility()) {
id.addError("imported declaration is not visible: '" + name + "' of '" + td.getName() + "' is protected");
}
}
i.setTypeDeclaration(td);
if (!isStaticNonGeneric(m, td) && !isToplevelClassConstructor(td, m) && !isToplevelAnonymousClass(m.getContainer())) {
if (alias == null) {
if (m.isStatic()) {
member.addError("illegal static import: static member '" + name + "' belongs to the generic type '" + td.getName() + "'");
} else if (isConstructor(m)) {
member.addError("illegal static import: '" + td.getName() + "' is not a toplevel class");
} else if (isAnonymousClass(m.getContainer())) {
member.addError("illegal static import: '" + td.getName() + "' is not a toplevel anonymous class");
} else {
member.addError("illegal static import: '" + name + "' is not static");
}
}
}
i.setDeclaration(m);
member.setDeclarationModel(m);
if (il.hasImport(m)) {
id.addError("duplicate import: '" + name + "' of '" + td.getName() + "' is already imported");
} else {
if (isStaticNonGeneric(m, td) || isToplevelClassConstructor(td, m) || isToplevelAnonymousClass(m.getContainer())) {
if (!checkForHiddenToplevel(id, i, alias, il)) {
addImport(member, il, i);
}
} else {
addMemberImport(member, il, i);
}
}
checkAliasCase(alias, m);
}
if (m != null) {
importMembers(member, m);
}
// imtl.addError("member aliases may not have member aliases");
return name;
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class ImportVisitor method importMembers.
private void importMembers(Tree.ImportMemberOrType member, Declaration d) {
Tree.ImportMemberOrTypeList imtl = member.getImportMemberOrTypeList();
if (imtl != null) {
if (d instanceof Value) {
Value v = (Value) d;
TypeDeclaration td = v.getTypeDeclaration();
if (td.isObjectClass()) {
d = td;
}
}
if (d instanceof TypeDeclaration) {
Set<String> names = new HashSet<String>();
ImportList til = imtl.getImportList();
TypeDeclaration td = (TypeDeclaration) d;
til.setImportedScope(td);
List<Tree.ImportMemberOrType> imts = imtl.getImportMemberOrTypes();
for (Tree.ImportMemberOrType imt : imts) {
names.add(importMember(imt, td, til));
}
if (imtl.getImportWildcard() != null) {
importAllMembers(td, names, til);
} else if (imts.isEmpty()) {
imtl.addError("empty import list", 1020);
}
} else {
imtl.addError("member alias list must follow a type");
}
}
}
Aggregations