Search in sources :

Example 26 with Declaration

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

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))
            // 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(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) TypeAlias(com.redhat.ceylon.model.typechecker.model.TypeAlias) 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) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) TransformationPlan(com.redhat.ceylon.compiler.java.codegen.recovery.TransformationPlan) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(com.redhat.ceylon.model.loader.model.LazyInterface) Interface(com.redhat.ceylon.model.typechecker.model.Interface) Drop(com.redhat.ceylon.compiler.java.codegen.recovery.Drop)

Example 27 with Declaration

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

the class ClassTransformer method addAmbiguousMembers.

private void addAmbiguousMembers(ClassDefinitionBuilder classBuilder, Interface model) {
    // only if we refine more than one interface
    java.util.List<Type> satisfiedTypes = model.getSatisfiedTypes();
    if (satisfiedTypes.size() <= 1)
        return;
    Set<Interface> satisfiedInterfaces = new HashSet<Interface>();
    for (Type interfaceDecl : model.getSatisfiedTypes()) {
        collectInterfaces((Interface) interfaceDecl.getDeclaration(), satisfiedInterfaces);
    }
    Set<Interface> ambiguousInterfaces = new HashSet<Interface>();
    for (Interface satisfiedInterface : satisfiedInterfaces) {
        if (isInheritedWithDifferentTypeArguments(satisfiedInterface, model.getType()) != null) {
            ambiguousInterfaces.add(satisfiedInterface);
        }
    }
    Set<String> treated = new HashSet<String>();
    for (Interface ambiguousInterface : ambiguousInterfaces) {
        for (Declaration member : ambiguousInterface.getMembers()) {
            String name = member.getName();
            // skip if already handled
            if (treated.contains(name))
                continue;
            // skip if it's implemented directly
            if (model.getDirectMember(name, null, false) != null) {
                treated.add(name);
                continue;
            }
            // find if we have different implementations in two direct interfaces
            LOOKUP: for (int i = 0; i < satisfiedTypes.size(); i++) {
                Type firstInterface = satisfiedTypes.get(i);
                Declaration member1 = firstInterface.getDeclaration().getMember(name, null, false);
                // if we can't find it in this interface, move to the next
                if (member1 == null)
                    continue;
                // try to find member in other interfaces
                for (int j = i + 1; j < satisfiedTypes.size(); j++) {
                    Type secondInterface = satisfiedTypes.get(j);
                    Declaration member2 = secondInterface.getDeclaration().getMember(name, null, false);
                    // if we can't find it in this interface, move to the next
                    if (member2 == null)
                        continue;
                    // we have it in two separate interfaces
                    Reference typedMember1 = firstInterface.getTypedReference(member1, Collections.<Type>emptyList());
                    Reference typedMember2 = secondInterface.getTypedReference(member2, Collections.<Type>emptyList());
                    Type type1 = simplifyType(typedMember1.getType());
                    Type type2 = simplifyType(typedMember2.getType());
                    if (!type1.isExactly(type2)) {
                        // treat it and stop looking for other interfaces
                        addAmbiguousMember(classBuilder, model, name);
                        break LOOKUP;
                    }
                }
            }
            // that member has no conflict
            treated.add(name);
        }
    }
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) Reference(com.redhat.ceylon.model.typechecker.model.Reference) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) 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) HashSet(java.util.HashSet)

Example 28 with Declaration

use of com.redhat.ceylon.model.typechecker.model.Declaration 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 29 with Declaration

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

the class ClassTransformer method transformSpecifiedMethodBody.

List<JCStatement> transformSpecifiedMethodBody(Tree.MethodDeclaration def, SpecifierExpression specifierExpression) {
    final Function model = def.getDeclarationModel();
    List<JCStatement> body;
    Tree.MethodDeclaration methodDecl = def;
    boolean isLazy = specifierExpression instanceof Tree.LazySpecifierExpression;
    boolean returnNull = false;
    JCExpression bodyExpr;
    Tree.Term term = null;
    if (specifierExpression != null && specifierExpression.getExpression() != null) {
        term = Decl.unwrapExpressionsUntilTerm(specifierExpression.getExpression());
        HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(term);
        if (error != null) {
            return List.<JCStatement>of(this.makeThrowUnresolvedCompilationError(error));
        }
    }
    if (!isLazy && term instanceof Tree.FunctionArgument) {
        // Function specified with lambda: Don't bother generating a 
        // Callable, just transform the expr to use as the method body.
        Tree.FunctionArgument fa = (Tree.FunctionArgument) term;
        Type resultType = model.getType();
        returnNull = isAnything(resultType) && fa.getExpression().getUnboxed();
        final java.util.List<Tree.Parameter> lambdaParams = fa.getParameterLists().get(0).getParameters();
        final java.util.List<Tree.Parameter> defParams = def.getParameterLists().get(0).getParameters();
        List<Substitution> substitutions = List.nil();
        for (int ii = 0; ii < lambdaParams.size(); ii++) {
            substitutions = substitutions.append(naming.addVariableSubst((TypedDeclaration) lambdaParams.get(ii).getParameterModel().getModel(), defParams.get(ii).getParameterModel().getName()));
        }
        bodyExpr = gen().expressionGen().transformExpression(fa.getExpression(), returnNull ? BoxingStrategy.INDIFFERENT : CodegenUtil.getBoxingStrategy(model), resultType);
        for (Substitution subs : substitutions) {
            subs.close();
        }
    } else if (!isLazy && typeFact().isCallableType(term.getTypeModel())) {
        returnNull = isAnything(term.getTypeModel()) && term.getUnboxed();
        Function method = methodDecl.getDeclarationModel();
        boolean lazy = specifierExpression instanceof Tree.LazySpecifierExpression;
        boolean inlined = CodegenUtil.canOptimiseMethodSpecifier(term, method);
        Invocation invocation;
        if ((lazy || inlined) && term instanceof Tree.MemberOrTypeExpression && ((Tree.MemberOrTypeExpression) term).getDeclaration() instanceof Functional) {
            Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) term).getDeclaration();
            Reference producedReference = ((Tree.MemberOrTypeExpression) term).getTarget();
            invocation = new MethodReferenceSpecifierInvocation(this, (Tree.MemberOrTypeExpression) term, primaryDeclaration, producedReference, method, specifierExpression);
        } else if (!lazy && !inlined) {
            // must be a callable we stored
            String name = naming.getMethodSpecifierAttributeName(method);
            invocation = new CallableSpecifierInvocation(this, method, naming.makeUnquotedIdent(name), term, term);
        } else if (isCeylonCallableSubtype(term.getTypeModel())) {
            invocation = new CallableSpecifierInvocation(this, method, expressionGen().transformExpression(term), term, term);
        } else {
            throw new BugException(term, "unhandled primary: " + term == null ? "null" : term.getNodeType());
        }
        invocation.handleBoxing(true);
        invocation.setErased(CodegenUtil.hasTypeErased(term) || getReturnTypeOfCallable(term.getTypeModel()).isNothing());
        bodyExpr = expressionGen().transformInvocation(invocation);
    } else {
        bodyExpr = expressionGen().transformExpression(model, term);
        // The innermost of an MPL method declared void needs to return null
        returnNull = Decl.isUnboxedVoid(model) && Decl.isMpl(model);
    }
    if (!Decl.isUnboxedVoid(model) || Decl.isMpl(model) || Strategy.useBoxedVoid(model)) {
        if (returnNull) {
            body = List.<JCStatement>of(make().Exec(bodyExpr), make().Return(makeNull()));
        } else {
            body = List.<JCStatement>of(make().Return(bodyExpr));
        }
    } else {
        body = List.<JCStatement>of(make().Exec(bodyExpr));
    }
    return body;
}
Also used : JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Function(com.redhat.ceylon.model.typechecker.model.Function) FunctionArgument(com.redhat.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) Substitution(com.redhat.ceylon.compiler.java.codegen.Naming.Substitution) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) 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) FunctionArgument(com.redhat.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) Reference(com.redhat.ceylon.model.typechecker.model.Reference) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) Functional(com.redhat.ceylon.model.typechecker.model.Functional) Type(com.redhat.ceylon.model.typechecker.model.Type) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) HasErrorException(com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter)

Example 30 with Declaration

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

the class ClassTransformer method addWriteReplace.

/**
     * Adds a write replace method which replaces value constructor instances 
     * with a SerializationProxy
     * @param model
     * @param classBuilder
     */
protected void addWriteReplace(final Class model, ClassDefinitionBuilder classBuilder) {
    MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, "writeReplace");
    mdb.resultType(null, make().Type(syms().objectType));
    mdb.modifiers(PRIVATE | FINAL);
    ListBuffer<JCStatement> stmts = ListBuffer.<JCStatement>lb();
    SyntheticName name = naming.synthetic(Unfix.$name$);
    stmts.add(makeVar(FINAL, name, make().Type(syms().stringType), null));
    if (model.hasEnumerated()) {
        JCStatement tail;
        if (Decl.hasOnlyValueConstructors(model)) {
            tail = make().Throw(statementGen().makeNewEnumeratedTypeError("Instance not of any constructor"));
        } else {
            tail = make().Return(naming.makeThis());
        }
        for (Declaration member : model.getMembers()) {
            if (Decl.isValueConstructor(member)) {
                Value val = (Value) member;
                tail = make().If(make().Binary(JCTree.EQ, naming.makeThis(), naming.getValueConstructorFieldName(val).makeIdent()), make().Block(0, List.<JCStatement>of(make().Exec(make().Assign(name.makeIdent(), make().Literal(Naming.getGetterName(member)))))), tail);
            }
        }
        stmts.add(tail);
    } else if (model.isAnonymous()) {
        stmts.add(make().Exec(make().Assign(name.makeIdent(), make().Literal(Naming.getGetterName((Value) model.getContainer().getDirectMember(model.getName(), null, false))))));
    } else {
        throw new BugException("Unsupported need for writeReplace()");
    }
    // final String name;
    // if(this == instA) {
    //    name = "getInstA";
    // } // ... else { throw new 
    // return new SerializationProxy(outer, Foo.clazz, name);
    List<JCExpression> args = List.<JCExpression>of(name.makeIdent());
    if (model.isMember()) {
        ClassOrInterface outer = (ClassOrInterface) model.getContainer();
        args = args.prepend(makeClassLiteral(outer.getType()));
        args = args.prepend(naming.makeQualifiedThis(naming.makeTypeDeclarationExpression(null, outer, DeclNameFlag.QUALIFIED)));
    } else {
        args = args.prepend(makeClassLiteral(model.getType()));
    }
    stmts.add(make().Return(make().NewClass(null, null, make().QualIdent(syms().ceylonSerializationProxyType.tsym), args, null)));
    mdb.body(stmts.toList());
    classBuilder.method(mdb);
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) 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)

Aggregations

Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)107 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)95 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)80 Type (com.redhat.ceylon.model.typechecker.model.Type)34 Function (com.redhat.ceylon.model.typechecker.model.Function)33 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)30 Class (com.redhat.ceylon.model.typechecker.model.Class)28 Value (com.redhat.ceylon.model.typechecker.model.Value)28 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)27 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)27 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)24 AttributeDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)22 JCTree (com.sun.tools.javac.tree.JCTree)22 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)21 MethodDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)20 Interface (com.redhat.ceylon.model.typechecker.model.Interface)20 Scope (com.redhat.ceylon.model.typechecker.model.Scope)20 Package (com.redhat.ceylon.model.typechecker.model.Package)17 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)17 ArrayList (java.util.ArrayList)16