Search in sources :

Example 91 with Constructor

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

the class GenerateJsVisitor method qualifiedPath.

public String qualifiedPath(final Node that, final Declaration d, final boolean inProto) {
    if (d instanceof Constructor) {
        Class c = (Class) d.getContainer();
        final String rval = qualifiedPath(that, c, inProto);
        return rval.isEmpty() ? names.name(c) : rval + "." + names.name(c);
    }
    final boolean isMember = d.isClassOrInterfaceMember();
    final boolean imported = isImported(that == null ? null : that.getUnit().getPackage(), d);
    if (!isMember && imported) {
        return names.moduleAlias(d.getUnit().getPackage().getModule());
    } else if (opts.isOptimize() && !inProto) {
        if (isMember && !(d.isParameter() && !d.isJsCaptured())) {
            TypeDeclaration id = that.getScope().getInheritingDeclaration(d);
            TypeDeclaration nd = null;
            if (id == null) {
                // a local declaration of some kind,
                // perhaps in an outer scope
                id = (TypeDeclaration) d.getContainer();
                if (id.isNativeHeader()) {
                    nd = (TypeDeclaration) ModelUtil.getNativeDeclaration(id, Backend.JavaScript);
                }
            }
            Scope scope = ModelUtil.getRealScope(that.getScope());
            if (scope instanceof Value && !(ModelUtil.getRealScope(scope) instanceof ClassOrInterface)) {
                scope = ModelUtil.getRealScope(scope.getContainer());
            }
            if ((scope != null) && (that instanceof Tree.ClassDeclaration || that instanceof Tree.InterfaceDeclaration || that instanceof Tree.Constructor)) {
                // class/interface aliases have no own "this"
                scope = scope.getContainer();
            }
            final StringBuilder path = new StringBuilder();
            final Declaration innermostDeclaration = ModelUtil.getContainingDeclarationOfScope(scope);
            while (scope != null) {
                if (scope instanceof Constructor && scope == innermostDeclaration) {
                    TypeDeclaration consCont = (TypeDeclaration) scope.getContainer();
                    if (that instanceof Tree.BaseTypeExpression) {
                        path.append(names.name(consCont));
                    } else if (d.isStatic()) {
                        path.append(names.name(consCont)).append(".$st$");
                    } else {
                        path.append(names.self(consCont));
                    }
                    if (scope == id || (nd != null && scope == nd)) {
                        break;
                    }
                    scope = consCont;
                } else if (scope instanceof TypeDeclaration) {
                    if (path.length() > 0) {
                        if (scope instanceof Constructor == false) {
                            Constructor constr = scope instanceof Class ? ((Class) scope).getDefaultConstructor() : null;
                            if ((constr == null || !ModelUtil.contains(constr, (Scope) innermostDeclaration)) && !d.isStatic()) {
                                path.append(".outer$");
                            }
                        }
                    } else if (d instanceof Constructor && ModelUtil.getContainingDeclaration(d) == scope) {
                        if (!d.getName().equals(((TypeDeclaration) scope).getName())) {
                            if (path.length() > 0) {
                                path.append('.');
                            }
                            path.append(names.name((TypeDeclaration) scope));
                        }
                    } else {
                        if (path.length() > 0) {
                            path.append('.');
                        }
                        if (d.isStatic()) {
                            if (d instanceof TypedDeclaration) {
                                TypedDeclaration orig = ((TypedDeclaration) d).getOriginalDeclaration();
                                path.append(names.name((ClassOrInterface) (orig == null ? d : orig).getContainer())).append(".$st$");
                            } else if (d instanceof TypeDeclaration) {
                                path.append(names.name((ClassOrInterface) d.getContainer())).append(".$st$");
                            }
                        } else {
                            path.append(names.self((TypeDeclaration) scope));
                        }
                    }
                } else {
                    path.setLength(0);
                }
                if (scope == id || (nd != null && scope == nd)) {
                    break;
                }
                scope = scope.getContainer();
            }
            if (id != null && path.length() == 0 && !ModelUtil.contains(id, that.getScope())) {
                // Import of toplevel object or constructor
                if (imported) {
                    path.append(names.moduleAlias(id.getUnit().getPackage().getModule())).append('.');
                }
                if (id.isAnonymous()) {
                    path.append(names.objectName(id));
                } else {
                    Import imp = findImport(that, d);
                    if (imp == null) {
                        path.append(names.name(id));
                    } else {
                        path.append(names.objectName(imp.getTypeDeclaration()));
                    }
                }
            }
            return path.toString();
        }
    } else if (d != null) {
        if (isMember && (d.isShared() || inProto || !d.isParameter() && AttributeGenerator.defineAsProperty(d))) {
            TypeDeclaration id = d instanceof TypeAlias ? (TypeDeclaration) d : that.getScope().getInheritingDeclaration(d);
            if (id == null) {
                // a local declaration of some kind,
                // perhaps in an outer scope
                id = (TypeDeclaration) d.getContainer();
                if (id.isToplevel() && !ModelUtil.contains(id, that.getScope())) {
                    // Import of toplevel object or constructor
                    final StringBuilder sb = new StringBuilder();
                    if (imported) {
                        sb.append(names.moduleAlias(id.getUnit().getPackage().getModule())).append('.');
                    }
                    sb.append(id.isAnonymous() ? names.objectName(id) : names.name(id));
                    return sb.toString();
                } else if (d instanceof Constructor) {
                    return names.name(id);
                } else {
                    // a shared local declaration
                    return names.self(id);
                }
            } else {
                // inherited by an outer scope
                return names.self(id);
            }
        }
    }
    return "";
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Import(org.eclipse.ceylon.model.typechecker.model.Import) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) 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) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 92 with Constructor

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

the class Constructors method classStatementsBetweenConstructors.

/**
 * Gather all class initializer statements that are between two constructors (or just before
 * the second constructor, if the first one is null), including the statements from the
 * second constructor
 */
static List<? extends Tree.Statement> classStatementsBetweenConstructors(final Tree.ClassDefinition cdef, final Tree.DelegatedConstructor dc, final Tree.Declaration c2, final GenerateJsVisitor gen) {
    List<Tree.Statement> origs = cdef.getClassBody().getStatements();
    if (NativeUtil.isForBackend(cdef.getDeclarationModel(), Backend.JavaScript)) {
        Tree.Declaration nh = gen.getNativeHeader(cdef.getDeclarationModel());
        if (nh == null && NativeUtil.hasNativeMembers(cdef.getDeclarationModel())) {
            nh = cdef;
        }
        origs = NativeUtil.mergeStatements(cdef.getClassBody(), nh, Backend.JavaScript);
    }
    ArrayList<Tree.Statement> stmts = new ArrayList<>(origs.size());
    // Find the constructor
    Tree.Constructor c1 = null;
    if (dc != null) {
        TypeDeclaration xtd = (TypeDeclaration) ((Tree.ExtendedTypeExpression) dc.getInvocationExpression().getPrimary()).getDeclaration();
        if (xtd instanceof Class && xtd == cdef.getDeclarationModel()) {
            // It's the default constructor
            for (Tree.Statement st : origs) {
                if (st instanceof Tree.Constructor && ((Tree.Constructor) st).getDeclarationModel().getName() == null) {
                    c1 = (Tree.Constructor) st;
                    break;
                }
            }
        } else {
            for (Tree.Statement st : origs) {
                if (st instanceof Tree.Constructor && TypeUtils.getConstructor(((Tree.Constructor) st).getDeclarationModel()) == xtd) {
                    c1 = (Tree.Constructor) st;
                    break;
                }
            }
        }
    }
    boolean go = false;
    for (Tree.Statement st : origs) {
        if (st == c1 || c1 == null) {
            go = true;
        }
        if (st == c2) {
            if (c2 instanceof Tree.Constructor) {
                stmts.addAll(((Tree.Constructor) c2).getBlock().getStatements());
            } else if (c2 instanceof Tree.Enumerated) {
                stmts.addAll(((Tree.Enumerated) c2).getBlock().getStatements());
            }
            return stmts;
        }
        if (go && st instanceof Tree.Constructor == false) {
            stmts.add(st);
        }
    }
    // Never happen!
    return null;
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ArrayList(java.util.ArrayList) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 93 with Constructor

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

the class Constructors method classConstructor.

static void classConstructor(final Tree.Constructor that, final Tree.ClassDefinition cdef, final List<Tree.Constructor> constructors, final GenerateJsVisitor gen) {
    gen.comment(that);
    final Constructor d = TypeUtils.getConstructor(that.getDeclarationModel());
    final Class container = cdef.getDeclarationModel();
    final String fullName = gen.getNames().name(container) + gen.getNames().constructorSeparator(d) + gen.getNames().name(d);
    if (!TypeUtils.isNativeExternal(d) || !gen.stitchNative(d, that)) {
        generateConstructor(that, cdef, constructors, fullName, gen);
    }
    // Add reference to metamodel
    gen.out(fullName, ".$crtmm$=");
    TypeUtils.encodeForRuntime(that, d, that.getAnnotationList(), gen);
    gen.endLine(true);
    gen.out(gen.getNames().name(container), ".", fullName, "=", fullName);
    gen.endLine(true);
    if (gen.outerSelf(container)) {
        gen.out(".", fullName, "=", fullName);
        gen.endLine(true);
    }
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Class(org.eclipse.ceylon.model.typechecker.model.Class)

Example 94 with Constructor

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

the class BmeGenerator method generateBme.

static void generateBme(final Tree.BaseMemberExpression bme, final GenerateJsVisitor gen, boolean nonNull) {
    final boolean forInvoke = bme.getDirectlyInvoked();
    Declaration decl = bme.getDeclaration();
    if (decl != null) {
        String name = decl.getName();
        Package pkg = decl.getUnit().getPackage();
        // map Ceylon true/false/null directly to JS true/false/null
        if (pkg.isLanguagePackage()) {
            if ("true".equals(name) || "false".equals(name) || "null".equals(name)) {
                gen.out(name);
                return;
            }
        }
        if (ModelUtil.isConstructor(decl)) {
            Constructor cd = TypeUtils.getConstructor(decl);
            Declaration cdc = (Declaration) cd.getContainer();
            if (!gen.qualify(bme, cd)) {
                gen.out(gen.getNames().name(cdc), gen.getNames().constructorSeparator(decl));
            }
            if (decl instanceof Value) {
                gen.out(gen.getNames().name(decl));
            } else {
                gen.out(gen.getNames().name(cd));
            }
            if (!forInvoke && decl instanceof Value) {
                gen.out("()");
            }
            return;
        }
    }
    String exp = gen.memberAccess(bme, null);
    if (decl == null && gen.isInDynamicBlock()) {
        if ("undefined".equals(exp)) {
            gen.out(exp);
        } else if (nonNull) {
            gen.out("(typeof ", exp, "==='undefined'||", exp, "===null?");
            gen.generateThrow(null, "Undefined or null reference: " + exp, bme);
            gen.out(":", exp, ")");
        } else {
            gen.out(exp);
        }
    } else {
        final boolean isCallable = !forInvoke && (decl instanceof Functional || bme.getUnit().getCallableDeclaration().equals(bme.getTypeModel().getDeclaration()));
        final boolean hasTparms = hasTypeParameters(bme);
        if (isCallable && (decl.isParameter() || (decl.isToplevel() && !hasTparms))) {
            // Callables passed as arguments are already wrapped in JsCallable
            gen.out(exp);
            return;
        }
        String who = isCallable && decl.isMember() ? gen.getMember(bme, null) : null;
        if (who == null || who.isEmpty()) {
            // We may not need to wrap this in certain cases
            ClassOrInterface cont = ModelUtil.getContainingClassOrInterface(bme.getScope());
            who = cont == null ? "0" : gen.getNames().self(cont);
        }
        if (isCallable && (who != null || hasTparms)) {
            if (hasTparms) {
                // Function refs with type arguments must be passed as a special function
                printGenericMethodReference(gen, bme, who, exp);
            } else {
                // Member methods must be passed as JsCallables
                gen.out(gen.getClAlias(), "jsc$3(", who, ",", exp, ")");
            }
        } else {
            gen.out(exp);
        }
    }
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Value(org.eclipse.ceylon.model.typechecker.model.Value) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Package(org.eclipse.ceylon.model.typechecker.model.Package)

Example 95 with Constructor

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

the class BmeGenerator method generateBte.

static void generateBte(final Tree.BaseTypeExpression that, final GenerateJsVisitor gen, final boolean forceReference) {
    Declaration d = that.getDeclaration();
    if (d == null && gen.isInDynamicBlock()) {
        // It's a native js type but will be wrapped in dyntype() call
        String id = that.getIdentifier().getText();
        gen.out("(typeof ", id, "==='undefined'?");
        gen.generateThrow(null, "Undefined type " + id, that);
        gen.out(":", id, ")");
    } else {
        boolean wrap = false;
        String pname = null;
        List<Parameter> params = null;
        if ((forceReference || !that.getDirectlyInvoked()) && d instanceof TypeDeclaration) {
            if (d.isParameterized()) {
                wrap = true;
                pname = gen.getNames().createTempVariable();
                gen.out("function(");
                if (d instanceof Class) {
                    params = ((Class) d).getParameterList().getParameters();
                } else if (d instanceof Constructor) {
                    params = ((Constructor) d).getFirstParameterList().getParameters();
                }
                for (int i = 0; i < params.size(); i++) {
                    if (i > 0)
                        gen.out(",");
                    gen.out(pname, "$", Integer.toString(i));
                }
                gen.out("){return ");
            }
        }
        if (d instanceof Constructor) {
            // this happens with classes that have a default constructor with the same name as the type
            if (gen.getNames().name(d).equals(gen.getNames().name((TypeDeclaration) d.getContainer()))) {
                gen.qualify(that, (TypeDeclaration) d.getContainer());
            } else {
                gen.qualify(that, d);
            }
        } else {
            if (d instanceof Class && d.isDynamic()) {
                gen.out("new ");
            }
            gen.qualify(that, d);
        }
        gen.out(gen.getNames().name(d));
        if (wrap) {
            gen.out("(");
            for (int i = 0; i < params.size(); i++) {
                gen.out(pname, "$", Integer.toString(i), ",");
            }
            List<Type> targs = that.getTypeArguments() == null ? null : that.getTypeArguments().getTypeModels();
            TypeUtils.printTypeArguments(that, TypeUtils.matchTypeParametersWithArguments(d.getTypeParameters(), targs), gen, false, null);
            gen.out(");}");
        }
    }
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) 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) 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