Search in sources :

Example 1 with Import

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;
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) Import(org.eclipse.ceylon.model.typechecker.model.Import) Value(org.eclipse.ceylon.model.typechecker.model.Value) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Package(org.eclipse.ceylon.model.typechecker.model.Package) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 2 with Import

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);
    }
}
Also used : Import(org.eclipse.ceylon.model.typechecker.model.Import)

Example 3 with Import

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;
}
Also used : Import(org.eclipse.ceylon.model.typechecker.model.Import) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 4 with Import

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);
    }
}
Also used : Import(org.eclipse.ceylon.model.typechecker.model.Import)

Example 5 with Import

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);
        }
    }
}
Also used : Import(org.eclipse.ceylon.model.typechecker.model.Import) ImportScope(org.eclipse.ceylon.model.typechecker.model.ImportScope)

Aggregations

Import (org.eclipse.ceylon.model.typechecker.model.Import)10 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)5 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)4 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)4 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)4 Class (org.eclipse.ceylon.model.typechecker.model.Class)2 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)2 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)2 ImportScope (org.eclipse.ceylon.model.typechecker.model.ImportScope)2 Value (org.eclipse.ceylon.model.typechecker.model.Value)2 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)1 AttributeDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)1 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)1 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)1 FieldValue (org.eclipse.ceylon.model.loader.model.FieldValue)1 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)1 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)1 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)1 Package (org.eclipse.ceylon.model.typechecker.model.Package)1 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)1