Search in sources :

Example 21 with Package

use of com.redhat.ceylon.model.typechecker.model.Package in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformConstructorDelegation.

/**
 * Transform a delegated constructor call ({@code extends XXX()})
 * which may be either a superclass initializer/constructor or a
 * same-class constructor.
 * @param extendedType
 * @param delegation The kind of delegation
 * @param invocation
 * @param classBuilder
 * @return
 */
JCStatement transformConstructorDelegation(Node extendedType, CtorDelegation delegation, Tree.InvocationExpression invocation, ClassDefinitionBuilder classBuilder, boolean forDelegationConstructor) {
    if (delegation != null && delegation.isError()) {
        return delegation.makeThrow(this);
    }
    Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) invocation.getPrimary()).getDeclaration();
    java.util.List<ParameterList> paramLists = ((Functional) primaryDeclaration).getParameterLists();
    if (paramLists.isEmpty()) {
        classBuilder.getInitBuilder().delegateCall(at(extendedType).Exec(makeErroneous(extendedType, "compiler bug: super class " + primaryDeclaration.getName() + " is missing parameter list")));
        return null;
    }
    SuperInvocation builder = new SuperInvocation(this, classBuilder.getForDefinition(), delegation, invocation, paramLists.get(0), forDelegationConstructor);
    CallBuilder callBuilder = CallBuilder.instance(this);
    boolean prevFnCall = withinInvocation(true);
    try {
        if (invocation.getPrimary() instanceof Tree.StaticMemberOrTypeExpression) {
            transformTypeArguments(callBuilder, (Tree.StaticMemberOrTypeExpression) invocation.getPrimary());
        }
        at(builder.getNode());
        JCExpression expr = null;
        Scope outerDeclaration;
        if (Decl.isConstructor(primaryDeclaration)) {
            outerDeclaration = builder.getPrimaryDeclaration().getContainer().getContainer();
        } else {
            outerDeclaration = builder.getPrimaryDeclaration().getContainer();
        }
        if ((Strategy.generateInstantiator(builder.getPrimaryDeclaration()) || builder.getPrimaryDeclaration() instanceof Class) && outerDeclaration instanceof Interface) {
            // If the subclass is inner to an interface then it will be
            // generated inner to the companion and we need to qualify the
            // super(), *unless* the subclass is nested within the same
            // interface as it's superclass.
            Scope outer = builder.getSub().getContainer();
            while (!(outer instanceof Package)) {
                if (outer == outerDeclaration) {
                    expr = naming.makeSuper();
                    break;
                }
                outer = outer.getContainer();
            }
            if (expr == null) {
                if (delegation.isSelfDelegation()) {
                    throw new BugException();
                }
                Interface iface = (Interface) outerDeclaration;
                JCExpression superQual;
                if (Decl.getClassOrInterfaceContainer(classBuilder.getForDefinition(), false) instanceof Interface) {
                    superQual = naming.makeCompanionAccessorCall(naming.makeQuotedThis(), iface);
                } else {
                    superQual = naming.makeCompanionFieldName(iface);
                }
                expr = naming.makeQualifiedSuper(superQual);
            }
        } else {
            expr = delegation.isSelfDelegation() ? naming.makeThis() : naming.makeSuper();
        }
        final List<JCExpression> superArguments = transformSuperInvocationArguments(classBuilder, builder, callBuilder);
        JCExpression superExpr = callBuilder.invoke(expr).arguments(superArguments).build();
        return at(extendedType).Exec(superExpr);
    // classBuilder.getInitBuilder().superCall(at(extendedType).Exec(superExpr));
    } finally {
        withinInvocation(prevFnCall);
    }
}
Also used : Functional(com.redhat.ceylon.model.typechecker.model.Functional) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Scope(com.redhat.ceylon.model.typechecker.model.Scope) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Package(com.redhat.ceylon.model.typechecker.model.Package) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Example 22 with Package

use of com.redhat.ceylon.model.typechecker.model.Package in project ceylon-compiler by ceylon.

the class ClassTransformer method typeParametersOfAllContainers.

private java.util.List<TypeParameter> typeParametersOfAllContainers(final ClassOrInterface model, boolean includeModelTypeParameters) {
    java.util.List<java.util.List<TypeParameter>> r = new ArrayList<java.util.List<TypeParameter>>(1);
    Scope s = model.getContainer();
    while (!(s instanceof Package)) {
        if (s instanceof Generic) {
            r.add(0, ((Generic) s).getTypeParameters());
        }
        s = s.getContainer();
    }
    Set<String> names = new HashSet<String>();
    for (TypeParameter tp : model.getTypeParameters()) {
        names.add(tp.getName());
    }
    java.util.List<TypeParameter> result = new ArrayList<TypeParameter>(1);
    for (java.util.List<TypeParameter> tps : r) {
        for (TypeParameter tp : tps) {
            if (names.add(tp.getName())) {
                result.add(tp);
            }
        }
    }
    if (includeModelTypeParameters)
        result.addAll(model.getTypeParameters());
    return result;
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Generic(com.redhat.ceylon.model.typechecker.model.Generic) ArrayList(java.util.ArrayList) Scope(com.redhat.ceylon.model.typechecker.model.Scope) ArrayList(java.util.ArrayList) AnnotationList(com.redhat.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(com.sun.tools.javac.util.List) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) Package(com.redhat.ceylon.model.typechecker.model.Package) HashSet(java.util.HashSet)

Example 23 with Package

use of com.redhat.ceylon.model.typechecker.model.Package in project ceylon-compiler by ceylon.

the class ClassTransformer method typeParametersForInstantiator.

/**
 * When generating an instantiator method if the inner class has a type
 * parameter with the same name as a type parameter of an outer type, then the
 * instantiator method shouldn't declare its own type parameter of that
 * name -- it should use the captured one. This method filters out the
 * type parameters of the inner class which are the same as type parameters
 * of the outer class so that they can be captured.
 */
private java.util.List<TypeParameter> typeParametersForInstantiator(final Class model) {
    java.util.List<TypeParameter> filtered = new ArrayList<TypeParameter>();
    java.util.List<TypeParameter> tps = model.getTypeParameters();
    if (tps != null) {
        for (TypeParameter tp : tps) {
            boolean omit = false;
            Scope s = model.getContainer();
            while (!(s instanceof Package)) {
                if (s instanceof Generic) {
                    for (TypeParameter outerTp : ((Generic) s).getTypeParameters()) {
                        if (tp.getName().equals(outerTp.getName())) {
                            omit = true;
                        }
                    }
                }
                s = s.getContainer();
            }
            if (!omit) {
                filtered.add(tp);
            }
        }
    }
    return filtered;
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Scope(com.redhat.ceylon.model.typechecker.model.Scope) Generic(com.redhat.ceylon.model.typechecker.model.Generic) ArrayList(java.util.ArrayList) Package(com.redhat.ceylon.model.typechecker.model.Package)

Example 24 with Package

use of com.redhat.ceylon.model.typechecker.model.Package in project ceylon-compiler by ceylon.

the class ClassTransformer method addAtContainer.

private void addAtContainer(ClassDefinitionBuilder classBuilder, TypeDeclaration model) {
    Scope scope = Decl.getNonSkippedContainer((Scope) model);
    Scope declarationScope = Decl.getFirstDeclarationContainer((Scope) model);
    boolean inlineObjectInToplevelAttr = Decl.isTopLevelObjectExpressionType(model);
    if (scope == null || (scope instanceof Package && !inlineObjectInToplevelAttr) && scope == declarationScope)
        return;
    if (scope instanceof ClassOrInterface && scope == declarationScope && !inlineObjectInToplevelAttr && // we do not check for types inside initialiser section which are private and not captured because we treat them as members
    !(model instanceof Interface && Decl.hasLocalNotInitializerAncestor(model))) {
        ClassOrInterface container = (ClassOrInterface) scope;
        List<JCAnnotation> atContainer = makeAtContainer(container.getType());
        classBuilder.annotations(atContainer);
    } else {
        if (model instanceof Interface)
            classBuilder.annotations(makeLocalContainerPath((Interface) model));
        Declaration declarationContainer = getDeclarationContainer(model);
        classBuilder.annotations(makeAtLocalDeclaration(model.getQualifier(), declarationContainer == null));
    }
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Scope(com.redhat.ceylon.model.typechecker.model.Scope) Package(com.redhat.ceylon.model.typechecker.model.Package) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(com.redhat.ceylon.model.loader.model.LazyInterface) Interface(com.redhat.ceylon.model.typechecker.model.Interface) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 25 with Package

use of com.redhat.ceylon.model.typechecker.model.Package in project ceylon-compiler by ceylon.

the class Resolve method loadClass.

/**
 * Load toplevel or member class with given fully qualified name and
 *  verify that it is accessible.
 *  @param env       The current environment.
 *  @param name      The fully qualified name of the class to be loaded.
 */
Symbol loadClass(Env<AttrContext> env, Name name) {
    try {
        ClassSymbol c = reader.loadClass(name);
        if (!isAccessible(env, c))
            return new AccessError(c);
        if (modelLoader != null && !sourceLanguage.isCeylon()) {
            // special cases for java.lang.String and java.lang.Override which are fine
            // See https://github.com/ceylon/ceylon-compiler/issues/2003
            String nameString = name.toString();
            if (!nameString.equals("java.lang.String") && !nameString.equals("java.lang.Override")) {
                // Check if the class is accessible according to Ceylon's access rules
                String scopePackageName = pkgSymbol(env.info.scope.owner).toString();
                Package scopePackage = modelLoader.findPackage(scopePackageName);
                // Don't check if we failed to find it
                if (scopePackage != null) {
                    Module scopeModule = scopePackage.getModule();
                    // Ugly special case where we skip the test when we're compiling the language module itself
                    if (scopeModule != modelLoader.getLanguageModule()) {
                        String importedPackageName = modelLoader.getPackageNameForQualifiedClassName(pkgName(nameString), nameString);
                        Package importedPackage = scopeModule.getPackage(importedPackageName);
                        // Don't check if we failed to find it
                        if (importedPackage == null) {
                            return new ImportError(c, scopeModule);
                        }
                    }
                }
            }
        }
        return c;
    } catch (ClassReader.BadClassFile err) {
        throw err;
    } catch (CompletionFailure ex) {
        return typeNotFound;
    }
}
Also used : CeylonClassReader(com.redhat.ceylon.compiler.java.loader.CeylonClassReader) LocalizedString(com.sun.tools.javac.api.Formattable.LocalizedString) Package(com.redhat.ceylon.model.typechecker.model.Package) Module(com.redhat.ceylon.model.typechecker.model.Module)

Aggregations

Package (com.redhat.ceylon.model.typechecker.model.Package)47 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)18 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)17 Module (com.redhat.ceylon.model.typechecker.model.Module)16 Scope (com.redhat.ceylon.model.typechecker.model.Scope)16 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)14 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)11 ArrayList (java.util.ArrayList)10 Class (com.redhat.ceylon.model.typechecker.model.Class)8 Interface (com.redhat.ceylon.model.typechecker.model.Interface)7 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)6 Value (com.redhat.ceylon.model.typechecker.model.Value)6 PhasedUnit (com.redhat.ceylon.compiler.typechecker.context.PhasedUnit)5 Function (com.redhat.ceylon.model.typechecker.model.Function)5 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)5 Type (com.redhat.ceylon.model.typechecker.model.Type)4 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)4 CeylonCompilationUnit (com.redhat.ceylon.compiler.java.codegen.CeylonCompilationUnit)3 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)3 File (java.io.File)3