Search in sources :

Example 1 with Drop

use of com.redhat.ceylon.compiler.java.codegen.recovery.Drop 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 2 with Drop

use of com.redhat.ceylon.compiler.java.codegen.recovery.Drop in project ceylon-compiler by ceylon.

the class CeylonVisitor method visit.

public void visit(Tree.ClassOrInterface decl) {
    TransformationPlan plan = gen.errors().hasDeclarationAndMarkBrokenness(decl);
    if (plan instanceof Drop) {
        return;
    }
    if (skipHeaderMergeLater(decl)) {
        return;
    }
    // To accept this class it is either not native or native for this backend
    if (!acceptDeclaration(decl))
        return;
    int annots = gen.checkCompilerAnnotations(decl, defs);
    if (Decl.withinClassOrInterface(decl)) {
        if (Decl.withinInterface(decl)) {
            classBuilder.getCompanionBuilder((Interface) decl.getDeclarationModel().getContainer()).defs(gen.classGen().transform(decl));
        } else {
            classBuilder.defs(gen.classGen().transform(decl));
        }
    } else {
        appendList(gen.classGen().transform(decl));
    }
    gen.resetCompilerAnnotations(annots);
}
Also used : TransformationPlan(com.redhat.ceylon.compiler.java.codegen.recovery.TransformationPlan) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Drop(com.redhat.ceylon.compiler.java.codegen.recovery.Drop)

Example 3 with Drop

use of com.redhat.ceylon.compiler.java.codegen.recovery.Drop in project ceylon-compiler by ceylon.

the class CeylonVisitor method visit.

public void visit(Tree.ClassBody that) {
    // Transform executable statements and declarations in the body
    // except constructors. Record how constructors delegate.
    HashMap<Constructor, CtorDelegation> delegates = new HashMap<Constructor, CtorDelegation>();
    java.util.List<Statement> stmts = getBodyStatements(that);
    HashMap<Constructor, CtorDelegation> broken = new HashMap<Constructor, CtorDelegation>();
    for (Tree.Statement stmt : stmts) {
        if (stmt instanceof Tree.Constructor) {
            Tree.Constructor ctor = (Tree.Constructor) stmt;
            Constructor ctorModel = ctor.getConstructor();
            if (gen.errors().hasDeclarationAndMarkBrokenness(ctor) instanceof Drop) {
                broken.put(ctorModel, CtorDelegation.brokenDelegation(ctorModel));
                continue;
            }
            classBuilder.getInitBuilder().constructor(ctor);
            if (ctor.getDelegatedConstructor() != null) {
                // error recovery
                if (ctor.getDelegatedConstructor().getInvocationExpression() != null) {
                    Tree.ExtendedTypeExpression p = (Tree.ExtendedTypeExpression) ctor.getDelegatedConstructor().getInvocationExpression().getPrimary();
                    Declaration delegatedDecl = p.getDeclaration();
                    delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
                }
            } else {
                // implicitly delegating to superclass initializer
                Type et = Decl.getConstructedClass(ctorModel).getExtendedType();
                if (et != null) {
                    Declaration delegatedDecl = et.getDeclaration();
                    delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
                }
            }
        } else if (stmt instanceof Tree.Enumerated) {
            Tree.Enumerated singleton = (Tree.Enumerated) stmt;
            Constructor ctorModel = singleton.getEnumerated();
            if (gen.errors().hasDeclarationAndMarkBrokenness(singleton) instanceof Drop) {
                broken.put(ctorModel, CtorDelegation.brokenDelegation(ctorModel));
                continue;
            }
            classBuilder.getInitBuilder().singleton(singleton);
            if (singleton.getDelegatedConstructor() != null) {
                Tree.ExtendedTypeExpression p = (Tree.ExtendedTypeExpression) singleton.getDelegatedConstructor().getInvocationExpression().getPrimary();
                Declaration delegatedDecl = p.getDeclaration();
                delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
            } else {
                // implicitly delegating to superclass initializer
                Type et = Decl.getConstructedClass(ctorModel).getExtendedType();
                if (et != null) {
                    Declaration delegatedDecl = et.getDeclaration();
                    delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
                }
            }
        } else {
            HasErrorException error = gen.errors().getFirstErrorInitializer(stmt);
            if (error != null) {
                append(gen.makeThrowUnresolvedCompilationError(error));
            } else {
                stmt.visit(this);
            }
        }
    }
    // Now transform constructors
    for (Tree.Statement stmt : stmts) {
        if (stmt instanceof Tree.Constructor) {
            Tree.Constructor ctor = (Tree.Constructor) stmt;
            if (gen.errors().hasDeclarationError(ctor) instanceof Drop) {
                continue;
            }
            transformConstructor(ctor, ctor.getParameterList(), ctor.getDelegatedConstructor(), ctor.getBlock(), ctor.getConstructor(), delegates);
        } else if (stmt instanceof Tree.Enumerated) {
            Tree.Enumerated ctor = (Tree.Enumerated) stmt;
            if (gen.errors().hasDeclarationError(ctor) instanceof Drop) {
                continue;
            }
            transformSingletonConstructor(delegates, ctor);
        }
    }
}
Also used : HashMap(java.util.HashMap) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Statement(com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement) Drop(com.redhat.ceylon.compiler.java.codegen.recovery.Drop) Type(com.redhat.ceylon.model.typechecker.model.Type) Statement(com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement) HasErrorException(com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException) CustomTree(com.redhat.ceylon.compiler.typechecker.tree.CustomTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 4 with Drop

use of com.redhat.ceylon.compiler.java.codegen.recovery.Drop in project ceylon-compiler by ceylon.

the class CeylonVisitor method visit.

/*
     * Compilation Unit
     */
public void visit(Tree.TypeAliasDeclaration decl) {
    TransformationPlan plan = gen.errors().hasDeclarationAndMarkBrokenness(decl);
    if (plan instanceof Drop) {
        return;
    }
    int annots = gen.checkCompilerAnnotations(decl, defs);
    if (Decl.withinClassOrInterface(decl)) {
        if (Decl.withinInterface(decl)) {
            classBuilder.getCompanionBuilder((Interface) decl.getDeclarationModel().getContainer()).defs(gen.classGen().transform(decl));
        } else {
            classBuilder.defs(gen.classGen().transform(decl));
        }
    } else {
        appendList(gen.classGen().transform(decl));
    }
    gen.resetCompilerAnnotations(annots);
}
Also used : TransformationPlan(com.redhat.ceylon.compiler.java.codegen.recovery.TransformationPlan) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Drop(com.redhat.ceylon.compiler.java.codegen.recovery.Drop)

Example 5 with Drop

use of com.redhat.ceylon.compiler.java.codegen.recovery.Drop in project ceylon-compiler by ceylon.

the class CeylonVisitor method transformConstructor.

private void transformConstructor(Tree.Declaration ctor, Tree.ParameterList parameterList, Tree.DelegatedConstructor delegatedCtor, Tree.Block block, Constructor ctorModel, Map<Constructor, CtorDelegation> delegates) {
    TransformationPlan plan = gen.errors().hasDeclarationAndMarkBrokenness(ctor);
    if (plan instanceof Drop) {
        return;
    }
    if (parameterList != null) {
        for (Parameter param : parameterList.getModel().getParameters()) {
            if (Naming.aliasConstructorParameterName(param.getModel())) {
                gen.naming.addVariableSubst(param.getModel(), gen.naming.suffixName(Suffix.$param$, param.getName()));
            }
        }
    }
    final CtorDelegation delegation = delegates.get(ctorModel);
    ListBuffer<JCStatement> stmts = ListBuffer.lb();
    boolean delegatedTo = CtorDelegation.isDelegatedTo(delegates, ctorModel);
    if (delegatedTo && !ctorModel.isAbstract()) {
        Tree.InvocationExpression chainedCtorInvocation;
        if (delegatedCtor != null) {
            chainedCtorInvocation = delegatedCtor.getInvocationExpression();
        } else {
            chainedCtorInvocation = null;
        }
        // We need to generate $delegation$ delegation constructor
        makeDelegationConstructor(ctor, parameterList, delegatedCtor, block, ctorModel, delegation, chainedCtorInvocation);
        JCStatement delegateExpr;
        if (chainedCtorInvocation != null) {
            delegateExpr = gen.expressionGen().transformConstructorDelegation(chainedCtorInvocation, delegation.isSelfDelegation() ? delegation : new CtorDelegation(ctorModel, ctorModel), chainedCtorInvocation, classBuilder, !delegation.isSelfDelegation());
        } else {
            // In this case there is no extends clause in the source code
            // so we have to construct the argument list "by hand".
            ListBuffer<JCExpression> arguments = ListBuffer.<JCExpression>lb();
            for (TypeParameter tp : ((Class) delegation.getConstructor().getContainer()).getTypeParameters()) {
                arguments.add(gen.makeReifiedTypeArgument(tp.getType()));
            }
            arguments.add(gen.naming.makeNamedConstructorName(delegation.getConstructor(), true));
            for (Parameter p : delegation.getConstructor().getFirstParameterList().getParameters()) {
                arguments.add(gen.naming.makeName(p.getModel(), Naming.NA_IDENT));
            }
            delegateExpr = gen.make().Exec(gen.make().Apply(null, gen.naming.makeThis(), arguments.toList()));
        }
        stmts.add(delegateExpr);
    } else if (delegatedCtor != null) {
        stmts.add(gen.expressionGen().transformConstructorDelegation(delegatedCtor, delegation, delegatedCtor.getInvocationExpression(), classBuilder, false));
    } else {
    // no explicit extends clause
    }
    final boolean addBody;
    if (delegatedTo && (delegation.isAbstractSelfOrSuperDelegation())) {
        if (delegation.getConstructor().isAbstract()) {
            stmts.addAll(classBuilder.getInitBuilder().copyStatementsBetween(null, ctorModel));
            addBody = true;
        } else if (delegation.getExtendingConstructor() != null && delegation.getExtendingConstructor().isAbstract()) {
            stmts.addAll(classBuilder.getInitBuilder().copyStatementsBetween(delegation.getExtendingConstructor(), ctorModel));
            addBody = true;
        } else {
            addBody = false;
        }
    } else if (delegation.isAbstractSelfDelegation()) {
        // delegating to abstract
        stmts.addAll(classBuilder.getInitBuilder().copyStatementsBetween(delegation.getExtendingConstructor(), ctorModel));
        addBody = true;
    } else if (delegation.isConcreteSelfDelegation()) {
        stmts.addAll(classBuilder.getInitBuilder().copyStatementsBetween(delegation.getExtendingConstructor(), ctorModel));
        addBody = true;
    } else {
        // super delegation
        stmts.addAll(classBuilder.getInitBuilder().copyStatementsBetween(null, ctorModel));
        addBody = true;
    }
    if (ctorModel.isAbstract() && !delegatedTo) {
        stmts.add(gen.make().Throw(gen.make().NewClass(null, List.<JCExpression>nil(), gen.make().QualIdent(gen.syms().ceylonUninvokableErrorType.tsym), List.<JCExpression>nil(), null)));
    }
    List<JCStatement> following = ctorModel.isAbstract() ? List.<JCStatement>nil() : classBuilder.getInitBuilder().copyStatementsBetween(ctorModel, null);
    if (addBody) {
        if (following.isEmpty()) {
            stmts.addAll(gen.statementGen().transformBlock(block));
        } else {
            Name label = gen.naming.aliasName(Naming.Unfix.$return$.toString());
            Transformer<JCStatement, Return> prev = gen.statementGen().returnTransformer(gen.statementGen().new ConstructorReturnTransformer(label));
            try {
                stmts.add(gen.make().Labelled(label, gen.make().DoLoop(gen.make().Block(0, gen.statementGen().transformBlock(block, true)), gen.make().Literal(false))));
            } finally {
                gen.statementGen().returnTransformer(prev);
            }
        }
    }
    ThrowVisitor visitor = new ThrowVisitor();
    block.visit(visitor);
    if (!visitor.getDefinitelyReturnsViaThrow()) {
        stmts.addAll(following);
    }
    String ctorName = !Decl.isDefaultConstructor(ctorModel) ? gen.naming.makeTypeDeclarationName(ctorModel) : null;
    classBuilder.defs(gen.classGen().makeNamedConstructor(ctor, parameterList, ctorModel, classBuilder, Strategy.generateInstantiator(ctorModel), gen.classGen().transformConstructorDeclFlags(ctorModel), false, ctorName, stmts.toList(), DeclNameFlag.QUALIFIED));
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Return(com.redhat.ceylon.compiler.typechecker.tree.Tree.Return) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Drop(com.redhat.ceylon.compiler.java.codegen.recovery.Drop) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) Name(com.sun.tools.javac.util.Name) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) CustomTree(com.redhat.ceylon.compiler.typechecker.tree.CustomTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) Class(com.redhat.ceylon.model.typechecker.model.Class) TransformationPlan(com.redhat.ceylon.compiler.java.codegen.recovery.TransformationPlan)

Aggregations

Drop (com.redhat.ceylon.compiler.java.codegen.recovery.Drop)10 TransformationPlan (com.redhat.ceylon.compiler.java.codegen.recovery.TransformationPlan)9 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)3 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)3 Interface (com.redhat.ceylon.model.typechecker.model.Interface)3 JCTree (com.sun.tools.javac.tree.JCTree)3 CustomTree (com.redhat.ceylon.compiler.typechecker.tree.CustomTree)2 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)2 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)2 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)2 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)2 SyntheticName (com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)1 HasErrorException (com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException)1 AttributeDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)1 MethodDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)1 Return (com.redhat.ceylon.compiler.typechecker.tree.Tree.Return)1 Statement (com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement)1 LazyInterface (com.redhat.ceylon.model.loader.model.LazyInterface)1 Class (com.redhat.ceylon.model.typechecker.model.Class)1 Constructor (com.redhat.ceylon.model.typechecker.model.Constructor)1