Search in sources :

Example 41 with Constructor

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

the class GenerateJsVisitor method specifierStatement.

private void specifierStatement(final TypeDeclaration outer, final Tree.SpecifierStatement specStmt) {
    final Tree.Expression expr = specStmt.getSpecifierExpression().getExpression();
    final Tree.Term term = specStmt.getBaseMemberExpression();
    final Tree.StaticMemberOrTypeExpression smte = term instanceof Tree.StaticMemberOrTypeExpression ? (Tree.StaticMemberOrTypeExpression) term : null;
    if (isInDynamicBlock() && ModelUtil.isTypeUnknown(term.getTypeModel())) {
        if (smte != null && smte.getDeclaration() == null) {
            out(smte.getIdentifier().getText());
        } else {
            term.visit(this);
            if (term instanceof BaseMemberExpression) {
                Declaration dec = ((BaseMemberExpression) term).getDeclaration();
                if (dec instanceof Value) {
                    Value v = (Value) dec;
                    if (v.isMember()) {
                        // Assignment to dynamic member
                        out("_");
                    }
                }
            }
        }
        out("=");
        int box = boxUnboxStart(expr, term);
        expr.visit(this);
        if (box == 4)
            out("/*TODO: callable targs 6.1*/");
        boxUnboxEnd(box);
        out(";");
        return;
    }
    if (smte != null) {
        final Declaration bmeDecl = smte.getDeclaration();
        if (specStmt.getSpecifierExpression() instanceof LazySpecifierExpression) {
            // attr => expr;
            final boolean property = AttributeGenerator.defineAsProperty(bmeDecl);
            if (property) {
                defineAttribute(qualifiedPath(specStmt, bmeDecl), names.name(bmeDecl));
            } else {
                if (bmeDecl.isMember()) {
                    qualify(specStmt, bmeDecl);
                } else {
                    out("var ");
                }
                out(names.getter(bmeDecl, false), "=function()");
            }
            beginBlock();
            if (outer != null) {
                initSelf(specStmt);
            }
            out("return ");
            if (!isNaturalLiteral(specStmt.getSpecifierExpression().getExpression().getTerm())) {
                specStmt.getSpecifierExpression().visit(this);
            }
            out(";");
            endBlock();
            if (property) {
                out(",undefined,");
                TypeUtils.encodeForRuntime(specStmt, bmeDecl, this);
                out(")");
            }
            endLine(true);
            directAccess.remove(bmeDecl);
        } else if (outer != null) {
            // since #451 we now generate an attribute here
            if (outer instanceof Constructor || bmeDecl.isMember() && bmeDecl instanceof Value && bmeDecl.isActual()) {
                assignment(outer, bmeDecl, expr);
            }
        } else if (bmeDecl instanceof FunctionOrValue) {
            // "attr = expr;" in an initializer or method
            final FunctionOrValue moval = (FunctionOrValue) bmeDecl;
            if (moval.isVariable() || moval.isLate()) {
                // simple assignment to a variable attribute
                BmeGenerator.generateMemberAccess(smte, new GenerateCallback() {

                    @Override
                    public void generateValue() {
                        int boxType = boxUnboxStart(expr.getTerm(), moval);
                        if (isInDynamicBlock() && !ModelUtil.isTypeUnknown(moval.getType()) && ModelUtil.isTypeUnknown(expr.getTypeModel())) {
                            TypeUtils.generateDynamicCheck(expr, moval.getType(), GenerateJsVisitor.this, false, expr.getTypeModel().getTypeArguments());
                        } else {
                            expr.visit(GenerateJsVisitor.this);
                        }
                        if (boxType == 4) {
                            out(",");
                            if (moval instanceof Function) {
                                // Add parameters
                                TypeUtils.encodeParameterListForRuntime(true, specStmt, ((Function) moval).getFirstParameterList(), GenerateJsVisitor.this);
                                out(",");
                            } else {
                                // TODO extract parameters from Value
                                final Type ps = moval.getUnit().getCallableTuple(moval.getType());
                                if (ps == null || ps.isSubtypeOf(moval.getUnit().getEmptyType())) {
                                    out("[],");
                                } else {
                                    out("[/*VALUE Callable params ", ps.asString() + "*/],");
                                }
                            }
                            TypeUtils.printTypeArguments(expr, expr.getTypeModel().getTypeArguments(), GenerateJsVisitor.this, false, expr.getTypeModel().getVarianceOverrides());
                        }
                        boxUnboxEnd(boxType);
                    }
                }, qualifiedPath(smte, moval), this);
                out(";");
            } else if (moval.isMember()) {
                if (moval instanceof Function) {
                    // same as fat arrow
                    qualify(specStmt, bmeDecl);
                    if (expr.getTerm() instanceof Tree.FunctionArgument) {
                        ((Tree.FunctionArgument) expr.getTerm()).getDeclarationModel().setRefinedDeclaration(moval);
                        out(names.name(moval), "=");
                        specStmt.getSpecifierExpression().visit(this);
                        out(";");
                    } else {
                        out(names.name(moval), "=function ", names.name(moval), "(");
                        // Build the parameter list, we'll use it several times
                        final StringBuilder paramNames = new StringBuilder();
                        final List<Parameter> params = ((Function) moval).getFirstParameterList().getParameters();
                        for (Parameter p : params) {
                            if (paramNames.length() > 0)
                                paramNames.append(",");
                            paramNames.append(names.name(p));
                        }
                        out(paramNames.toString());
                        out("){");
                        for (Parameter p : params) {
                            if (p.isDefaulted()) {
                                out("if(", names.name(p), "===undefined)", names.name(p), "=");
                                qualify(specStmt, moval);
                                out(names.name(moval), "$defs$", p.getName(), "(", paramNames.toString(), ")");
                                endLine(true);
                            }
                        }
                        out("return ");
                        if (!isNaturalLiteral(specStmt.getSpecifierExpression().getExpression().getTerm())) {
                            specStmt.getSpecifierExpression().visit(this);
                        }
                        out("(", paramNames.toString(), ");}");
                        endLine(true);
                    }
                } else {
                    // declaration itself can be omitted), so generate the attribute.
                    if (opts.isOptimize()) {
                        // #451
                        out(names.self(ModelUtil.getContainingClassOrInterface(moval.getScope())), ".", names.valueName(moval), "=");
                        specStmt.getSpecifierExpression().visit(this);
                        endLine(true);
                    } else {
                        AttributeGenerator.generateAttributeGetter(null, moval, specStmt.getSpecifierExpression(), null, this, directAccess, verboseStitcher);
                    }
                }
            } else {
                // Specifier for some other attribute, or for a method.
                if (opts.isOptimize() || bmeDecl.isMember() && bmeDecl instanceof Function) {
                    qualify(specStmt, bmeDecl);
                }
                out(names.name(bmeDecl), "=");
                if (isInDynamicBlock() && ModelUtil.isTypeUnknown(expr.getTypeModel()) && !ModelUtil.isTypeUnknown(((FunctionOrValue) bmeDecl).getType())) {
                    TypeUtils.generateDynamicCheck(expr, ((FunctionOrValue) bmeDecl).getType(), this, false, expr.getTypeModel().getTypeArguments());
                } else {
                    if (expr.getTerm() instanceof Tree.FunctionArgument) {
                        Function fun = ((Tree.FunctionArgument) expr.getTerm()).getDeclarationModel();
                        if (fun.isAnonymous()) {
                            fun.setRefinedDeclaration(moval);
                        }
                    }
                    specStmt.getSpecifierExpression().visit(this);
                }
                out(";");
            }
        }
    } else if ((term instanceof Tree.ParameterizedExpression) && (specStmt.getSpecifierExpression() != null)) {
        final Tree.ParameterizedExpression paramExpr = (Tree.ParameterizedExpression) term;
        if (paramExpr.getPrimary() instanceof BaseMemberExpression) {
            // func(params) => expr;
            final BaseMemberExpression bme2 = (BaseMemberExpression) paramExpr.getPrimary();
            final Declaration bmeDecl = bme2.getDeclaration();
            if (bmeDecl.isMember()) {
                qualify(specStmt, bmeDecl);
            } else {
                out("var ");
            }
            out(names.name(bmeDecl), "=");
            FunctionHelper.singleExprFunction(paramExpr.getParameterLists(), expr, bmeDecl instanceof Scope ? (Scope) bmeDecl : null, true, true, this);
            out(";");
        }
    }
}
Also used : Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Function(org.eclipse.ceylon.model.typechecker.model.Function) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) ExtendedType(org.eclipse.ceylon.compiler.typechecker.tree.Tree.ExtendedType) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) StaticMemberOrTypeExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.StaticMemberOrTypeExpression) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) List(java.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) BaseMemberExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression) 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) LazySpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 42 with Constructor

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

the class MetamodelHelper method generateOpenType.

static void generateOpenType(final Tree.MetaLiteral that, final Declaration d, final GenerateJsVisitor gen, boolean compilingLanguageModule) {
    final Module m = d.getUnit().getPackage().getModule();
    final boolean isConstructor = ModelUtil.isConstructor(d) || that instanceof Tree.NewLiteral;
    if (d instanceof TypeParameter == false) {
        if (compilingLanguageModule) {
            gen.out("$init$");
        } else {
            gen.out(gen.getClAlias());
        }
    }
    if (d instanceof org.eclipse.ceylon.model.typechecker.model.Interface) {
        gen.out("OpenInterface$jsint");
    } else if (isConstructor) {
        if (TypeUtils.getConstructor(d).isValueConstructor()) {
            gen.out("OpenValueConstructor$jsint");
        } else {
            gen.out("OpenCallableConstructor$jsint");
        }
    } else if (d instanceof Class) {
        gen.out("openClass$jsint");
    } else if (d instanceof Function) {
        gen.out("OpenFunction$jsint");
    } else if (d instanceof Value) {
        gen.out("OpenValue$jsint");
    } else if (d instanceof org.eclipse.ceylon.model.typechecker.model.IntersectionType) {
        gen.out("OpenIntersection");
    } else if (d instanceof org.eclipse.ceylon.model.typechecker.model.UnionType) {
        gen.out("OpenUnion");
    } else if (d instanceof TypeParameter) {
        generateOpenType(that, ((TypeParameter) d).getDeclaration(), gen, compilingLanguageModule);
        gen.out(".getTypeParameterDeclaration('", d.getName(), "')");
        return;
    } else if (d instanceof org.eclipse.ceylon.model.typechecker.model.NothingType) {
        gen.out("NothingType");
    } else if (d instanceof TypeAlias) {
        gen.out("OpenAlias$jsint(");
        if (compilingLanguageModule) {
            gen.out(")(");
        }
        if (d.isMember()) {
            // Make the chain to the top-level container
            ArrayList<Declaration> parents = new ArrayList<>(2);
            Declaration pd = (Declaration) d.getContainer();
            while (pd != null) {
                parents.add(0, pd);
                pd = pd.isMember() ? (Declaration) pd.getContainer() : null;
            }
            for (Declaration _d : parents) {
                gen.out(gen.getNames().name(_d), ".$$.prototype.");
            }
        }
        gen.out(gen.getNames().name(d), ")");
        return;
    }
    // TODO optimize for local declarations
    if (compilingLanguageModule) {
        gen.out("()");
    }
    gen.out("(", gen.getClAlias());
    final String pkgname = d.getUnit().getPackage().getNameAsString();
    if (Objects.equals(that.getUnit().getPackage().getModule(), d.getUnit().getPackage().getModule())) {
        gen.out("lmp$(ex$,'");
    } else {
        // TODO use $ for language module as well
        gen.out("fmp$('", m.getNameAsString(), "','", m.getVersion(), "','");
    }
    gen.out("ceylon.language".equals(pkgname) ? "$" : pkgname, "'),");
    if (d.isMember() || isConstructor) {
        if (isConstructor) {
            final Class actualClass;
            final String constrName;
            if (d instanceof Class) {
                actualClass = (Class) d;
                constrName = "$c$";
            } else {
                actualClass = (Class) d.getContainer();
                if (d instanceof Constructor && ((Constructor) d).isValueConstructor()) {
                    constrName = gen.getNames().name(actualClass.getDirectMember(d.getName(), null, false));
                } else {
                    constrName = gen.getNames().name(d);
                }
            }
            if (gen.isImported(that.getUnit().getPackage(), actualClass)) {
                gen.out(gen.getNames().moduleAlias(actualClass.getUnit().getPackage().getModule()), ".");
            }
            if (actualClass.isMember()) {
                outputPathToDeclaration(that, actualClass, gen);
            }
            gen.out(gen.getNames().name(actualClass), gen.getNames().constructorSeparator(d), constrName, ")");
            return;
        } else {
            outputPathToDeclaration(that, d, gen);
        }
    }
    if (d instanceof Value || d.isParameter()) {
        if (!d.isMember())
            gen.qualify(that, d);
        if (d.isStatic() && d instanceof Value && ((Value) d).getType().getDeclaration().isAnonymous()) {
            gen.out(gen.getNames().name(d), ")");
        } else {
            gen.out(gen.getNames().getter(d, true), ")");
        }
    } else {
        if (d.isAnonymous()) {
            final String oname = gen.getNames().objectName(d);
            if (d.isToplevel()) {
                gen.qualify(that, d);
            }
            gen.out("$init$", oname);
            if (!d.isToplevel()) {
                gen.out("()");
            }
        } else {
            if (!d.isMember())
                gen.qualify(that, d);
            gen.out(gen.getNames().name(d));
        }
        gen.out(")");
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ArrayList(java.util.ArrayList) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Function(org.eclipse.ceylon.model.typechecker.model.Function) Value(org.eclipse.ceylon.model.typechecker.model.Value) 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) Module(org.eclipse.ceylon.model.typechecker.model.Module)

Example 43 with Constructor

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

the class Singletons method valueConstructor.

static void valueConstructor(final Tree.ClassDefinition cdef, final Tree.Enumerated that, final GenerateJsVisitor gen) {
    final Value d = that.getDeclarationModel();
    final Constructor c = that.getEnumerated();
    final Tree.DelegatedConstructor dc = that.getDelegatedConstructor();
    final TypeDeclaration td = (TypeDeclaration) c.getContainer();
    final String objvar = gen.getNames().createTempVariable();
    final String selfvar = gen.getNames().self(td);
    final String typevar = gen.getNames().name(td);
    final String singvar = gen.getNames().name(d);
    final boolean nested = cdef.getDeclarationModel().isClassOrInterfaceMember();
    final String constructorName = typevar + gen.getNames().constructorSeparator(c) + singvar;
    gen.out(nested ? "this." : "var ", objvar, "=undefined;function ", constructorName, "(){if(", nested ? "this." : "", objvar, "===undefined){");
    if (dc == null) {
        gen.out("$init$", typevar, "();");
    }
    if (nested) {
        gen.out("var ", selfvar, "=");
    } else {
        gen.out(objvar, "=");
    }
    gen.out("new ", typevar, ".$$;");
    if (td.isClassOrInterfaceMember()) {
        gen.out(nested ? selfvar : objvar, ".outer$=this;");
    }
    if (dc != null) {
        Tree.InvocationExpression invoke = dc.getInvocationExpression();
        invoke.getPrimary().visit(gen);
        gen.out("(");
        // For now, only positional invocations are allowed here
        gen.getInvoker().generatePositionalArguments(invoke.getPrimary(), invoke.getPositionalArgumentList(), invoke.getPositionalArgumentList().getPositionalArguments(), false, false);
        if (!invoke.getPositionalArgumentList().getPositionalArguments().isEmpty()) {
            gen.out(",");
        }
        if (!dc.getType().getTypeModel().getTypeArguments().isEmpty()) {
            TypeUtils.printTypeArguments(dc, dc.getType().getTypeModel().getTypeArguments(), gen, false, dc.getType().getTypeModel().getVarianceOverrides());
            gen.out(",");
        }
        gen.out(nested ? selfvar : objvar, ")");
        gen.endLine(true);
    }
    if (!nested) {
        gen.out("var ", selfvar, "=", objvar, ";");
    }
    ClassGenerator.addFunctionTypeArguments(cdef.getDeclarationModel(), objvar, gen);
    ClassGenerator.callSupertypes(cdef, cdef.getDeclarationModel(), typevar, gen);
    List<? extends Tree.Statement> stmts = Constructors.classStatementsBetweenConstructors(cdef, null, that, gen);
    if (!stmts.isEmpty()) {
        gen.generateConstructorStatements(that, stmts);
    }
    stmts = Constructors.classStatementsAfterConstructor(cdef, that);
    if (!stmts.isEmpty()) {
        gen.visitStatements(stmts);
    }
    if (nested) {
        gen.out("this.", objvar, "=", selfvar, ";");
    }
    gen.out("}return ", nested ? "this." : "", objvar, ";};", constructorName, ".$crtmm$=");
    TypeUtils.encodeForRuntime(that, that.getDeclarationModel(), that.getAnnotationList(), gen);
    gen.out(";");
    if (td.isClassOrInterfaceMember()) {
        gen.outerSelf(td);
        gen.out(".", constructorName, "=", constructorName, ";");
    } else if (td.isShared()) {
        gen.out("ex$.", constructorName, "=", constructorName, ";");
    }
    gen.out(gen.getNames().name(td), ".", constructorName, "=", constructorName);
    gen.endLine(true);
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Value(org.eclipse.ceylon.model.typechecker.model.Value) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 44 with Constructor

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

the class TypeGenerator method callSuperclass.

static void callSuperclass(final Tree.SimpleType extendedType, final Tree.InvocationExpression invocation, final Class d, final ParameterList plist, final Node that, final boolean pseudoAbstractConstructor, final List<Declaration> superDecs, final GenerateJsVisitor gen) {
    TypeDeclaration typeDecl = extendedType.getDeclarationModel();
    if (invocation != null) {
        Tree.PositionalArgumentList argList = invocation.getPositionalArgumentList();
        final String qpath;
        if (typeDecl instanceof Constructor) {
            final String path = gen.qualifiedPath(that, (TypeDeclaration) typeDecl.getContainer(), false);
            if (path.isEmpty()) {
                qpath = gen.getNames().name((TypeDeclaration) typeDecl.getContainer());
            } else {
                qpath = path + "." + gen.getNames().name((TypeDeclaration) typeDecl.getContainer());
            }
        } else {
            if (typeDecl.isStatic()) {
                Declaration _cont = ModelUtil.getContainingDeclaration(typeDecl);
                String qp = gen.qualifiedPath(that, _cont, false);
                qpath = qp + (qp.isEmpty() ? "" : ".") + gen.getNames().name(_cont);
            } else {
                qpath = gen.qualifiedPath(that, typeDecl, false);
            }
        }
        if (pseudoAbstractConstructor) {
            if (typeDecl instanceof Constructor) {
                gen.out(gen.memberAccessBase(extendedType, typeDecl, false, qpath), "$$a(");
            } else {
                gen.out(gen.memberAccessBase(extendedType, typeDecl, false, qpath), gen.getNames().constructorSeparator(typeDecl), "$c$$$a(");
            }
        } else {
            gen.out(gen.memberAccessBase(extendedType, typeDecl, false, qpath), (gen.opts.isOptimize() && (gen.getSuperMemberScope(extendedType) != null)) ? ".call(this," : "(");
        }
        gen.getInvoker().generatePositionalArguments(invocation.getPrimary(), argList, argList.getPositionalArguments(), false, false);
        if (argList.getPositionalArguments().size() > 0) {
            gen.out(",");
        }
        // There may be defaulted args we must pass as undefined
        if (plist != null && plist.getParameters().size() > argList.getPositionalArguments().size()) {
            for (int i = argList.getPositionalArguments().size(); i < plist.getParameters().size(); i++) {
                org.eclipse.ceylon.model.typechecker.model.Parameter p = plist.getParameters().get(i);
                if (p.isSequenced()) {
                    gen.out(gen.getClAlias(), "empty(),");
                } else {
                    gen.out("undefined,");
                }
            }
        }
        // If the supertype has type arguments, add them to the call
        List<TypeParameter> typeParams;
        if (typeDecl instanceof Constructor) {
            // Output the type arguments to the constructor,
            // UNLESS you're in the same class, then just pass the type arguments object
            typeParams = ((Class) typeDecl.getContainer()).getTypeParameters();
            if (typeParams != null && !typeParams.isEmpty()) {
                typeParams = null;
                if (ModelUtil.contains(d, typeDecl)) {
                    gen.out("$$targs$$,");
                } else {
                    TypeUtils.printTypeArguments(that, extendedType.getTypeModel().getQualifyingType().getTypeArguments(), gen, false, null);
                    gen.out(",");
                }
            }
        } else {
            typeParams = typeDecl.getTypeParameters();
        }
        if (typeParams != null && !typeParams.isEmpty()) {
            List<Type> typeArgs = null;
            if (extendedType.getTypeArgumentList() != null) {
                typeArgs = extendedType.getTypeArgumentList().getTypeModels();
            }
            TypeUtils.printTypeArguments(that, TypeUtils.matchTypeParametersWithArguments(typeParams, typeArgs), gen, false, null);
            gen.out(",");
        }
        gen.out(gen.getNames().self(d), ")");
        gen.endLine(true);
    }
    copySuperMembers(typeDecl, superDecs, d, gen);
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Type(org.eclipse.ceylon.model.typechecker.model.Type) StaticType(org.eclipse.ceylon.compiler.typechecker.tree.Tree.StaticType) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 45 with Constructor

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

the class Constructors method generateConstructor.

private static void generateConstructor(final Tree.Constructor that, final Tree.ClassDefinition cdef, final List<Tree.Constructor> constructors, final String fullName, final GenerateJsVisitor gen) {
    final Constructor d = TypeUtils.getConstructor(that.getDeclarationModel());
    final Class container = cdef.getDeclarationModel();
    final Tree.DelegatedConstructor delcons = that.getDelegatedConstructor();
    final TypeDeclaration superdec;
    final ParameterList superplist;
    final boolean callAbstract;
    if (delcons == null) {
        superdec = null;
        superplist = null;
        callAbstract = false;
    } else {
        superdec = delcons.getType().getDeclarationModel();
        /**
         * Is the delegated constructor is within the same class we call its abstract version
         */
        callAbstract = superdec instanceof Class ? superdec == container : ((Constructor) superdec).getContainer() == container;
        superplist = superdec instanceof Class ? ((Class) superdec).getParameterList() : ((Constructor) superdec).getFirstParameterList();
    }
    gen.out("function ", fullName, "$$a");
    final boolean withTargs = TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
    final String me = gen.getNames().self(container);
    gen.beginBlock();
    gen.initParameters(that.getParameterList(), container, null);
    if (delcons != null) {
        TypeGenerator.callSuperclass(delcons.getType(), delcons.getInvocationExpression(), container, superplist, that, callAbstract, null, gen);
    }
    // If there's a delegated constructor, run the statements after that one and before this one
    gen.generateConstructorStatements(that, classStatementsBetweenConstructors(cdef, delcons, that, gen));
    gen.out("return ", me, ";");
    gen.endBlockNewLine(true);
    gen.out("function ", fullName);
    TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
    gen.beginBlock();
    if (!d.isAbstract()) {
        gen.out("$init$", gen.getNames().name(container), "();");
        gen.endLine();
        gen.declareSelf(container);
        gen.referenceOuter(container);
    }
    gen.initParameters(that.getParameterList(), container, null);
    if (!d.isAbstract()) {
        // Call common initializer
        gen.out(gen.getNames().name(container), "$$c(");
        if (withTargs) {
            gen.out("$$targs$$,");
        }
        gen.out(me, ");");
        gen.endLine();
    }
    gen.out(fullName, "$$a");
    TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
    gen.endLine(true);
    if (d.isNative()) {
        gen.stitchConstructorHelper(cdef, "_cons_before");
    }
    gen.visitStatements(classStatementsAfterConstructor(cdef, that));
    if (d.isNative()) {
        gen.stitchConstructorHelper(cdef, "_cons_after");
    }
    gen.out("return ", me, ";");
    gen.endBlockNewLine(true);
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Aggregations

Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)95 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)65 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)48 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)47 Type (org.eclipse.ceylon.model.typechecker.model.Type)45 Class (org.eclipse.ceylon.model.typechecker.model.Class)42 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)42 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)27 Value (org.eclipse.ceylon.model.typechecker.model.Value)27 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)26 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)25 Function (org.eclipse.ceylon.model.typechecker.model.Function)23 ModelUtil.isConstructor (org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor)21 ArrayList (java.util.ArrayList)20 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)19 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)17 AnalyzerUtil.unwrapAliasedTypeConstructor (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor)16 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)14 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)14