Search in sources :

Example 6 with Statement

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement in project ceylon by eclipse.

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 = ModelUtil.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 = ModelUtil.getConstructedClass(ctorModel).getExtendedType();
                if (et != null) {
                    Declaration delegatedDecl = et.getDeclaration();
                    delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
                }
            }
        } else if (stmt instanceof Tree.SpecifierStatement && ((Tree.SpecifierStatement) stmt).getRefinement()) {
            HasErrorException error = gen.errors().getFirstErrorBlock(stmt);
            if (error != null) {
                classBuilder.broken();
            }
            stmt.visit(this);
        } 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(org.eclipse.ceylon.model.typechecker.model.Constructor) Statement(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Drop(org.eclipse.ceylon.compiler.java.codegen.recovery.Drop) Type(org.eclipse.ceylon.model.typechecker.model.Type) Statement(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 7 with Statement

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement in project ceylon by eclipse.

the class GenerateJsVisitor method addToPrototype.

void addToPrototype(Node node, ClassOrInterface d, List<Tree.Statement> statements) {
    final boolean isSerial = d instanceof Class && ((Class) d).isSerializable();
    boolean enter = opts.isOptimize();
    ArrayList<Parameter> plist = null;
    final boolean isAbstractNative = TypeUtils.makeAbstractNative(d);
    final String typename = names.name(d);
    final boolean overrideToString = d.getDirectMember("toString", null, true) == null;
    if (enter) {
        enter = !statements.isEmpty() | overrideToString;
        if (d instanceof Class) {
            ParameterList cpl = ((Class) d).getParameterList();
            if (cpl != null) {
                plist = new ArrayList<>(cpl.getParameters().size());
                plist.addAll(cpl.getParameters());
                enter |= !plist.isEmpty();
            }
        }
    }
    if (enter || isSerial) {
        final List<? extends Statement> prevStatements = currentStatements;
        currentStatements = statements;
        out("(function(", names.self(d), ")");
        beginBlock();
        if (enter) {
            // First of all, add an object to store statics only if needed
            for (Statement s : statements) {
            }
            // Generated attributes with corresponding parameters will remove them from the list
            if (plist != null) {
                for (Parameter p : plist) {
                    generateAttributeForParameter(node, (Class) d, p);
                }
            }
            boolean statics = false;
            InitDeferrer initDeferrer = new InitDeferrer();
            for (Statement s : statements) {
                if (!statics && s instanceof Tree.Declaration) {
                    Declaration sd = ((Tree.Declaration) s).getDeclarationModel();
                    if (sd.isStatic()) {
                        statics = true;
                        out(names.name(d), ".$st$={};");
                    }
                }
                if (!(s instanceof Tree.ClassOrInterface) && !(s instanceof Tree.AttributeDeclaration && ((Tree.AttributeDeclaration) s).getDeclarationModel().isParameter())) {
                    addToPrototype(d, s, plist, initDeferrer);
                }
            }
            for (Statement s : statements) {
                if (s instanceof Tree.ClassOrInterface) {
                    addToPrototype(d, s, plist, initDeferrer);
                } else if (s instanceof Tree.Enumerated) {
                    // Add a simple attribute which really returns the singleton from the class
                    final Tree.Enumerated vc = (Tree.Enumerated) s;
                    Value vcd = vc.getDeclarationModel();
                    defineAttribute(names.self(d), names.name(vcd));
                    out("{return ", typename, names.constructorSeparator(vcd), names.name(vcd), "();},undefined,");
                    TypeUtils.encodeForRuntime(vc, vcd, vc.getAnnotationList(), this);
                    out(");");
                }
            }
            for (String stmt : initDeferrer.deferred) {
                out(stmt);
                endLine();
            }
            if (d.isMember()) {
                ClassOrInterface coi = ModelUtil.getContainingClassOrInterface(d.getContainer());
                if (coi != null && d.inherits(coi)) {
                    out(names.self(d), ".", typename, "=", typename, ";");
                }
            }
        }
        if (isSerial && !isAbstractNative) {
            SerializationHelper.addSerializer(node, (Class) d, this);
        }
        if (overrideToString) {
            out(names.self(d), ".", "toString=function(){return this.string.valueOf();};");
        }
        endBlock();
        out(")(", typename, ".$$.prototype)");
        endLine(true);
        currentStatements = prevStatements;
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Statement(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement) AttributeDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) 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) AttributeDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)

Example 8 with Statement

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement in project ceylon by eclipse.

the class GenerateJsVisitor method generateConstructorStatements.

/**
 * Like visitStatements but for constructors, because we need to check if a statement is
 * a specifier expression and generate it regardless of lexical/prototype mode.
 */
void generateConstructorStatements(final Tree.Declaration cnstr, List<? extends Tree.Statement> stmts) {
    final List<String> oldRetainedVars = retainedVars.reset(null);
    final List<? extends Statement> prevStatements = currentStatements;
    currentStatements = stmts;
    ReturnConstructorVisitor rcv = new ReturnConstructorVisitor(cnstr);
    if (rcv.isReturns()) {
        out("(function(){");
    }
    for (Tree.Statement s2 : stmts) {
        if (s2 instanceof Tree.SpecifierStatement) {
            Tree.SpecifierStatement ss = (Tree.SpecifierStatement) s2;
            if (cnstr instanceof Tree.Constructor) {
                specifierStatement(((Tree.Constructor) cnstr).getConstructor(), ss);
            } else if (cnstr instanceof Tree.Enumerated) {
                specifierStatement(((Tree.Enumerated) cnstr).getEnumerated(), ss);
            }
        } else {
            s2.visit(this);
        }
        if (!opts.isMinify())
            beginNewLine();
        retainedVars.emitRetainedVars(this);
        // every constructor adds metamodel to that attribute
        if (!opts.isOptimize() && cnstr != null && s2 instanceof Tree.AttributeDeclaration) {
            generatedAttributes.remove(((Tree.AttributeDeclaration) s2).getDeclarationModel());
        }
    }
    if (rcv.isReturns()) {
        out("}());");
    }
    retainedVars.reset(oldRetainedVars);
    currentStatements = prevStatements;
}
Also used : AttributeDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) Statement(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Aggregations

Statement (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement)8 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)7 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)3 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)3 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)3 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)3 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)3 HashMap (java.util.HashMap)2 HasErrorException (org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException)2 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)2 AttributeDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)2 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)2 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)2 Value (org.eclipse.ceylon.model.typechecker.model.Value)2 ArrayList (java.util.ArrayList)1 Stack (java.util.Stack)1 Drop (org.eclipse.ceylon.compiler.java.codegen.recovery.Drop)1 SourceDeclarationVisitor (org.eclipse.ceylon.compiler.java.loader.SourceDeclarationVisitor)1 ClassOrInterface (org.eclipse.ceylon.compiler.typechecker.tree.Tree.ClassOrInterface)1 Declaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Declaration)1