use of org.eclipse.ceylon.model.typechecker.model.Import in project ceylon by eclipse.
the class ExpressionTransformer method addThisOrObjectQualifierIfRequired.
/**
* We may need to force a qualified this prefix (direct or outer) in the following cases:
*
* - Required because of mixin inheritance with different type arguments (the same is already
* done for qualified references, but not for direct references)
* - The compiler generates anonymous local classes for things like
* Callables and Comprehensions. When referring to a member foo
* within one of those things we need a qualified {@code this}
* to ensure we're accessing the outer instances member, not
* a member of the anonymous local class that happens to have the same name.
*/
private JCExpression addThisOrObjectQualifierIfRequired(JCExpression qualExpr, Tree.StaticMemberOrTypeExpression expr, Declaration decl) {
// find out the real target
Declaration typeDecl;
if (Decl.isConstructor(decl))
typeDecl = ModelUtil.getConstructedClass(decl);
else
typeDecl = decl;
if (qualExpr == null && // statics are not members that can be inherited
!decl.isStatic() && (!Decl.isConstructor(decl) || !Decl.isConstructor(typeDecl)) && typeDecl.isMember() && // and have a name mapping)
expr.getTarget().getDeclaration() == decl && !ModelUtil.isLocalToInitializer(typeDecl) && !isWithinSuperInvocation()) {
// First check whether the expression is captured from an enclosing scope
TypeDeclaration outer = Decl.getOuterScopeOfMemberInvocation(expr, typeDecl);
if (outer != null) {
Type targetType = expr.getTarget().getQualifyingType();
Type declarationContainerType = ((TypeDeclaration) outer).getType();
// check if we need a variance cast
VarianceCastResult varianceCastResult = getVarianceCastResult(targetType, declarationContainerType);
// if we are within a comprehension body, or if we need a variance cast
if (isWithinSyntheticClassBody() || varianceCastResult != null) {
if (decl.isShared() && outer instanceof Interface) {
// always prefer qualified
qualExpr = makeQualifiedDollarThis(declarationContainerType);
} else {
// Class or companion class,
qualExpr = naming.makeQualifiedThis(makeJavaType(((TypeDeclaration) outer).getType(), JT_RAW | (outer instanceof Interface ? JT_COMPANION : 0)));
}
// add the variance cast if required
if (varianceCastResult != null) {
qualExpr = applyVarianceCasts(qualExpr, targetType, varianceCastResult, 0);
}
}
} else if (typeDecl.isClassOrInterfaceMember()) {
ClassOrInterface container;
if (((ClassOrInterface) typeDecl.getContainer()).isAnonymous() && ((ClassOrInterface) typeDecl.getContainer()).isToplevel()) {
// easy
container = (Class) typeDecl.getContainer();
} else {
// find the import
Import foundImport = statementGen().findImport(expr, decl);
container = (Class) foundImport.getTypeDeclaration();
}
Value value = (Value) ((Package) container.getContainer()).getMember(container.getName(), null, false);
qualExpr = make().Apply(null, naming.makeName(value, Naming.NA_FQ | Naming.NA_WRAPPER | Naming.NA_MEMBER), List.<JCExpression>nil());
} else if (decl.isMember() && !expr.getStaticMethodReference()) {
throw new BugException(expr, decl.getQualifiedNameString() + " was unexpectedly a member");
}
}
return qualExpr;
}
use of org.eclipse.ceylon.model.typechecker.model.Import in project ceylon by eclipse.
the class ImportVisitor method addWildcardImport.
private void addWildcardImport(ImportList il, Declaration dec) {
if (!hidesToplevel(dec, il)) {
Import i = new Import();
i.setAlias(dec.getName());
i.setDeclaration(dec);
i.setWildcardImport(true);
addWildcardImport(il, dec, i);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Import 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.Import in project ceylon by eclipse.
the class ImportVisitor method addWildcardImport.
private void addWildcardImport(ImportList il, Declaration dec, TypeDeclaration td) {
if (!hidesToplevel(dec, il)) {
Import i = new Import();
i.setAlias(dec.getName());
i.setDeclaration(dec);
i.setWildcardImport(true);
i.setTypeDeclaration(td);
addWildcardImport(il, dec, i);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Import in project ceylon by eclipse.
the class ImportVisitor method addWildcardImport.
private void addWildcardImport(ImportList il, Declaration dec, Import i) {
if (notOverloaded(dec)) {
String alias = i.getAlias();
if (alias != null) {
ImportScope scope = getImportScope(il);
Import o = scope.getImport(dec.getName());
if (o != null && o.isWildcardImport()) {
if (o.getDeclaration().equals(dec) || dec.isNativeHeader()) {
// this case only happens in the IDE,
// due to reuse of the Unit
scope.removeImport(o);
il.getImports().remove(o);
} else if (!dec.isNative()) {
i.setAmbiguous(true);
o.setAmbiguous(true);
}
}
scope.addImport(i);
il.getImports().add(i);
}
}
}
Aggregations