Search in sources :

Example 26 with TypeAlias

use of org.eclipse.ceylon.model.typechecker.model.TypeAlias in project ceylon by eclipse.

the class AbstractModelLoader method setContainer.

private void setContainer(ClassMirror classMirror, Declaration d, LazyPackage pkg) {
    // add it to its package if it's not an inner class
    if (!classMirror.isInnerClass() && !classMirror.isLocalClass()) {
        d.setContainer(pkg);
        d.setScope(pkg);
        pkg.addCompiledMember(d);
        if (d instanceof LazyInterface && ((LazyInterface) d).isCeylon()) {
            setInterfaceCompanionClass(d, null, pkg);
        }
        ModelUtil.setVisibleScope(d);
    } else if (classMirror.isLocalClass() && !classMirror.isInnerClass()) {
        // set its container to the package for now, but don't add it to the package as a member because it's not
        Scope localContainer = getLocalContainer(pkg, classMirror, d);
        if (localContainer != null) {
            d.setContainer(localContainer);
            d.setScope(localContainer);
        // do not add it as member, it has already been registered by getLocalContainer
        } else {
            d.setContainer(pkg);
            d.setScope(pkg);
        }
        ((LazyElement) d).setLocal(true);
    } else if (d instanceof ClassOrInterface || d instanceof TypeAlias) {
        // we have to set that one first
        if (d instanceof Class == false || !((Class) d).isOverloaded()) {
            ClassOrInterface container = getContainer(pkg.getModule(), classMirror);
            if (d.isNativeHeader() && container.isNative()) {
                container = (ClassOrInterface) ModelUtil.getNativeHeader(container);
            } else if (d.isNativeImplementation() && // for every Java declaration, who don't have native headers
            container.isNativeHeader()) {
                container = (ClassOrInterface) ModelUtil.getNativeDeclaration(container, Backend.Java);
            }
            d.setContainer(container);
            d.setScope(container);
            if (d instanceof LazyInterface && ((LazyInterface) d).isCeylon()) {
                setInterfaceCompanionClass(d, container, pkg);
            }
            // let's not trigger lazy-loading
            ((LazyContainer) container).addMember(d);
            ModelUtil.setVisibleScope(d);
            // now we can do overloads
            if (d instanceof Class && ((Class) d).getOverloads() != null) {
                for (Declaration overload : ((Class) d).getOverloads()) {
                    overload.setContainer(container);
                    overload.setScope(container);
                    // let's not trigger lazy-loading
                    ((LazyContainer) container).addMember(overload);
                    ModelUtil.setVisibleScope(overload);
                }
            }
            // Adds extra members for annotation interop.
            if (d instanceof LazyInterface && !((LazyInterface) d).isCeylon() && ((LazyInterface) d).isAnnotationType()) {
                for (Declaration decl : makeInteropAnnotation((LazyInterface) d, container)) {
                    container.addMember(decl);
                }
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyContainer(org.eclipse.ceylon.model.loader.model.LazyContainer) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) LazyTypeAlias(org.eclipse.ceylon.model.loader.model.LazyTypeAlias) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) AnnotationProxyClass(org.eclipse.ceylon.model.loader.model.AnnotationProxyClass) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) 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)

Example 27 with TypeAlias

use of org.eclipse.ceylon.model.typechecker.model.TypeAlias in project ceylon by eclipse.

the class ClassTransformer method addAtMembers.

private void addAtMembers(ClassDefinitionBuilder classBuilder, ClassOrInterface model, Tree.ClassOrInterface def) {
    List<JCExpression> members = List.nil();
    for (Declaration member : model.getMembers()) {
        if (member instanceof ClassOrInterface == false && member instanceof TypeAlias == false) {
            continue;
        }
        TypeDeclaration innerType = (TypeDeclaration) member;
        Tree.Declaration innerTypeTree = findInnerType(def, innerType.getName());
        if (innerTypeTree != null) {
            TransformationPlan plan = errors().hasDeclarationAndMarkBrokenness(innerTypeTree);
            if (plan instanceof Drop) {
                continue;
            }
        }
        if (innerType.isAlias() && innerTypeTree != null && Decl.isAncestorLocal(innerTypeTree.getDeclarationModel()))
            // for the same reason we do not generate aliases in transform(ClassOrInterface def) let's not list them
            continue;
        JCAnnotation atMember;
        // interfaces are moved to toplevel so they can lose visibility of member types if they are local
        if (Decl.isLocal(model) && model instanceof Interface)
            atMember = makeAtMember(innerType.getName());
        else
            atMember = makeAtMember(innerType.getType());
        members = members.prepend(atMember);
    }
    classBuilder.annotations(makeAtMembers(members));
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCPrimitiveTypeTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) TransformationPlan(org.eclipse.ceylon.compiler.java.codegen.recovery.TransformationPlan) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) Drop(org.eclipse.ceylon.compiler.java.codegen.recovery.Drop)

Example 28 with TypeAlias

use of org.eclipse.ceylon.model.typechecker.model.TypeAlias in project ceylon by eclipse.

the class ClassTransformer method concreteMembersFromSuperinterfaces.

/**
 * Generates companion fields ($Foo$impl) and methods
 */
private void concreteMembersFromSuperinterfaces(final Class model, ClassDefinitionBuilder classBuilder, Type satisfiedType, Set<Interface> satisfiedInterfaces) {
    satisfiedType = satisfiedType.resolveAliases();
    Interface iface = (Interface) satisfiedType.getDeclaration();
    if (satisfiedInterfaces.contains(iface) || iface.isIdentifiable()) {
        return;
    }
    // then don't instantiate it...
    if (hasImpl(iface)) {
        // ... otherwise for each satisfied interface,
        // instantiate an instance of the
        // companion class in the constructor and assign it to a
        // $Interface$impl field
        transformInstantiateCompanions(classBuilder, model, iface, satisfiedType);
    }
    if (!ModelUtil.isCeylonDeclaration(iface)) {
        // let's not try to implement CMI for Java interfaces
        return;
    }
    // For each super interface
    for (Declaration member : sortedMembers(iface.getMembers())) {
        if (member instanceof Class) {
            Class klass = (Class) member;
            final Type typedMember = satisfiedType.getTypeMember(klass, Collections.<Type>emptyList());
            if (Strategy.generateInstantiator(member) && !klass.hasConstructors() && !model.isFormal() && needsCompanionDelegate(model, typedMember) && model.getDirectMember(member.getName(), null, false) == null) {
                // instantiator method implementation
                generateInstantiatorDelegate(classBuilder, satisfiedType, iface, klass, null, model.getType(), !member.isFormal());
            }
            if (klass.hasConstructors()) {
                for (Declaration m : klass.getMembers()) {
                    if (m instanceof Constructor && Strategy.generateInstantiator(m)) {
                        Constructor ctor = (Constructor) m;
                        generateInstantiatorDelegate(classBuilder, satisfiedType, iface, klass, ctor, model.getType(), true);
                    }
                }
            }
        }
        // type aliases are on the $impl class
        if (member instanceof TypeAlias)
            continue;
        if (Strategy.onlyOnCompanion(member)) {
            // (they're just private methods on the $impl)
            continue;
        }
        if (member instanceof Function) {
            Function method = (Function) member;
            final TypedReference typedMember = satisfiedType.getTypedMember(method, typesOfTypeParameters(method.getTypeParameters()));
            Declaration sub = (Declaration) model.getMember(method.getName(), getSignatureIfRequired(typedMember), false, true);
            if (sub instanceof Function) /* && !sub.isAbstraction()*/
            {
                Function subMethod = (Function) sub;
                if (subMethod.getParameterLists().isEmpty()) {
                    continue;
                }
                java.util.List<java.util.List<Type>> producedTypeParameterBounds = producedTypeParameterBounds(typedMember, subMethod);
                // final TypedReference refinedTypedMember = model.getType().getTypedMember(subMethod, Collections.<Type>emptyList());
                final java.util.List<TypeParameter> typeParameters = subMethod.getTypeParameters();
                final java.util.List<Parameter> parameters = subMethod.getFirstParameterList().getParameters();
                boolean hasOverloads = false;
                if (!satisfiedInterfaces.contains((Interface) method.getContainer())) {
                    for (Parameter param : parameters) {
                        if (Strategy.hasDefaultParameterValueMethod(param) && CodegenUtil.getTopmostRefinedDeclaration(param.getModel()).getContainer().equals(member)) {
                            final TypedReference typedParameter = typedMember.getTypedParameter(param);
                            // If that method has a defaulted parameter,
                            // we need to generate a default value method
                            // which also delegates to the $impl
                            final MethodDefinitionBuilder defaultValueDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().defaultValueMethodBridge(), typeParameters, producedTypeParameterBounds, typedParameter.getFullType(), Naming.getDefaultedParamMethodName(method, param), parameters.subList(0, parameters.indexOf(param)), param.getModel().getTypeErased(), null, param);
                            classBuilder.method(defaultValueDelegate);
                        }
                        if (Strategy.hasDefaultParameterOverload(param)) {
                            if ((method.isDefault() || method.isShared() && !method.isFormal()) && Decl.equal(method, subMethod)) {
                                MethodDefinitionBuilder overload = new DefaultedArgumentMethodTyped(new DaoThis((Tree.AnyMethod) null, null), MethodDefinitionBuilder.method(this, subMethod), typedMember, true).makeOverload(subMethod.getFirstParameterList(), param, typeParameters);
                                classBuilder.method(overload);
                            }
                            hasOverloads = true;
                        }
                    }
                }
                // delegating to the $impl instance
                if (needsCompanionDelegate(model, typedMember)) {
                    final MethodDefinitionBuilder concreteMemberDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().methodBridge(method), typeParameters, producedTypeParameterBounds, typedMember.getType(), naming.selector(method), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), null, null);
                    classBuilder.method(concreteMemberDelegate);
                }
                if (hasOverloads && (method.isDefault() || method.isShared() && !method.isFormal()) && Decl.equal(method, subMethod)) {
                    final MethodDefinitionBuilder canonicalMethod = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().canonicalMethodBridge(), subMethod.getTypeParameters(), producedTypeParameterBounds, typedMember.getType(), Naming.selector(method, Naming.NA_CANONICAL_METHOD), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), naming.selector(method), null);
                    classBuilder.method(canonicalMethod);
                }
            }
        } else if (member instanceof Value || member instanceof Setter) {
            TypedDeclaration attr = (TypedDeclaration) member;
            final TypedReference typedMember = satisfiedType.getTypedMember(attr, null);
            if (needsCompanionDelegate(model, typedMember)) {
                Setter setter = (member instanceof Setter) ? (Setter) member : null;
                if (member instanceof Value) {
                    Value getter = (Value) member;
                    if (member instanceof JavaBeanValue) {
                        setter = ((Value) member).getSetter();
                    }
                    final MethodDefinitionBuilder getterDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().getterBridge(getter), Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typedMember.getType(), Naming.getGetterName(getter), Collections.<Parameter>emptyList(), getter.getTypeErased(), null, null);
                    classBuilder.method(getterDelegate);
                }
                if (setter != null) {
                    final MethodDefinitionBuilder setterDelegate = makeDelegateToCompanion(iface, satisfiedType.getTypedMember(setter, null), model.getType(), modifierTransformation().setterBridge(setter), Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typeFact().getAnythingType(), Naming.getSetterName(attr), Collections.<Parameter>singletonList(setter.getParameter()), setter.getTypeErased(), null, null);
                    classBuilder.method(setterDelegate);
                }
                if (Decl.isValue(member) && ((Value) attr).isVariable()) {
                    // $impl to delegate to
                    throw new BugException("assertion failed: " + member.getQualifiedNameString() + " was unexpectedly a variable value");
                }
            }
        } else {
            Reference typedMember = member instanceof TypeDeclaration ? satisfiedType.getTypeMember((TypeDeclaration) member, Collections.<Type>emptyList()) : satisfiedType.getTypedMember((TypedDeclaration) member, Collections.<Type>emptyList());
            if (needsCompanionDelegate(model, typedMember)) {
                throw new BugException("unhandled concrete interface member " + member.getQualifiedNameString() + " " + member.getClass());
            }
        }
    }
    // Add $impl instances for the whole interface hierarchy
    satisfiedInterfaces.add(iface);
    for (Type sat : iface.getSatisfiedTypes()) {
        sat = model.getType().getSupertype(sat.getDeclaration());
        concreteMembersFromSuperinterfaces(model, classBuilder, sat, satisfiedInterfaces);
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Function(org.eclipse.ceylon.model.typechecker.model.Function) JCPrimitiveTypeTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ArrayList(java.util.ArrayList) AnnotationList(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) ThrowerCatchallConstructor(org.eclipse.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Type(org.eclipse.ceylon.model.typechecker.model.Type) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) 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 29 with TypeAlias

use of org.eclipse.ceylon.model.typechecker.model.TypeAlias in project ceylon by eclipse.

the class ClassTransformer method transform.

public List<JCTree> transform(final Tree.TypeAliasDeclaration def) {
    final TypeAlias model = def.getDeclarationModel();
    // in that case
    if (Decl.isAncestorLocal(model))
        return List.nil();
    naming.clearSubstitutions(model);
    String ceylonClassName = def.getIdentifier().getText();
    final String javaClassName = Naming.quoteClassName(def.getIdentifier().getText());
    ClassDefinitionBuilder classBuilder = ClassDefinitionBuilder.klass(this, javaClassName, ceylonClassName, Decl.isLocal(model));
    // class alias
    classBuilder.getInitBuilder().modifiers(PRIVATE);
    classBuilder.annotations(makeAtTypeAlias(model.getExtendedType()));
    classBuilder.annotations(expressionGen().transformAnnotations(OutputElement.TYPE, def));
    classBuilder.isAlias(true);
    // make sure we set the container in case we move it out
    addAtContainer(classBuilder, model);
    transformTypeParameters(classBuilder, model);
    visitClassOrInterfaceDefinition(def, classBuilder);
    return classBuilder.modelAnnotations(model.getAnnotations()).modifiers(modifierTransformation().typeAlias(model)).satisfies(model.getSatisfiedTypes()).build();
}
Also used : TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias)

Example 30 with TypeAlias

use of org.eclipse.ceylon.model.typechecker.model.TypeAlias in project ceylon by eclipse.

the class ExpressionTransformer method makeTypeParameterDeclaration.

/**
 * Makes an expression equivalent to the result of {@code `given T`}
 * @param node
 * @param declaration
 * @return
 */
JCExpression makeTypeParameterDeclaration(Node node, TypeParameter declaration) {
    Scope container = declaration.getContainer();
    if (container instanceof Declaration) {
        JCExpression containerExpr;
        Declaration containerDeclaration = (Declaration) container;
        if (containerDeclaration instanceof ClassOrInterface || containerDeclaration instanceof TypeAlias) {
            JCExpression metamodelCall = makeTypeDeclarationLiteral((TypeDeclaration) containerDeclaration);
            JCExpression metamodelCast = makeJavaType(typeFact().getLanguageModuleDeclarationTypeDeclaration("GenericDeclaration").getType(), JT_NO_PRIMITIVES);
            containerExpr = make().TypeCast(metamodelCast, metamodelCall);
        } else if (containerDeclaration.isToplevel()) {
            containerExpr = makeTopLevelValueOrFunctionDeclarationLiteral(containerDeclaration);
        } else {
            containerExpr = makeMemberValueOrFunctionDeclarationLiteral(node, containerDeclaration);
        }
        // now it must be a ClassOrInterfaceDeclaration or a FunctionDeclaration, both of which have the method we need
        return at(node).Apply(null, makeSelect(containerExpr, "getTypeParameterDeclaration"), List.of(ceylonLiteral(declaration.getName())));
    } else {
        return makeErroneous(node, "compiler bug: " + container + " is not a supported type parameter container");
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Aggregations

TypeAlias (org.eclipse.ceylon.model.typechecker.model.TypeAlias)32 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)23 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)20 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)16 Class (org.eclipse.ceylon.model.typechecker.model.Class)15 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)14 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)13 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)13 Type (org.eclipse.ceylon.model.typechecker.model.Type)12 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)11 Function (org.eclipse.ceylon.model.typechecker.model.Function)10 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)9 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)9 ArrayList (java.util.ArrayList)8 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)8 Value (org.eclipse.ceylon.model.typechecker.model.Value)8 NothingType (org.eclipse.ceylon.model.typechecker.model.NothingType)6 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)5 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)5 Package (org.eclipse.ceylon.model.typechecker.model.Package)5