Search in sources :

Example 71 with Function

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

the class GenerateJsVisitor method generateAttributeForParameter.

void generateAttributeForParameter(Node node, Class d, Parameter p) {
    if (p.getDeclaration() instanceof Function && ModelUtil.isConstructor(p.getDeclaration())) {
        return;
    }
    final FunctionOrValue pdec = p.getModel();
    final String privname = names.valueName(pdec);
    defineAttribute(names.self(d), names.name(pdec));
    out("{");
    if (pdec.isLate()) {
        generateUnitializedAttributeReadCheck("this." + privname, names.name(p), null);
    }
    out("return this.", privname, ";}");
    if (pdec.isVariable() || pdec.isLate()) {
        final String param = names.createTempVariable();
        out(",function(", param, "){");
        // Because of this one case, we need to pass 3 args to this method
        generateImmutableAttributeReassignmentCheck(pdec, "this." + privname, names.name(p));
        out("return this.", privname, "=", param, ";}");
    } else {
        out(",undefined");
    }
    out(",");
    TypeUtils.encodeForRuntime(node, pdec, this);
    out(")");
    endLine(true);
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 72 with Function

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

the class InvocationGenerator method generateSpreadArgument.

private void generateSpreadArgument(final Tree.Primary primary, final Tree.SpreadArgument arg, Tree.Expression expr, final Parameter pd) {
    TypedDeclaration td = pd == null ? null : pd.getModel();
    int boxType = gen.boxUnboxStart(expr.getTerm(), td);
    if (boxType == 4) {
        arg.visit(gen);
        gen.out(",");
        describeMethodParameters(expr.getTerm());
        gen.out(",");
        TypeUtils.printTypeArguments(arg, arg.getTypeModel().getTypeArguments(), gen, false, arg.getTypeModel().getVarianceOverrides());
    } else if (pd == null) {
        final Declaration primDec = primary instanceof Tree.MemberOrTypeExpression ? ((Tree.MemberOrTypeExpression) primary).getDeclaration() : null;
        if (gen.isInDynamicBlock() && primary instanceof Tree.MemberOrTypeExpression && (primDec == null || primDec.isDynamic() || (primDec instanceof TypedDeclaration && ((TypedDeclaration) primDec).isDynamicallyTyped())) && arg.getTypeModel() != null && arg.getTypeModel().getDeclaration().inherits((arg.getUnit().getTupleDeclaration()))) {
            // Spread dynamic parameter
            Type tupleType = arg.getTypeModel();
            Type targ = tupleType.getTypeArgumentList().get(2);
            arg.visit(gen);
            gen.out(".$_get(0)");
            int i = 1;
            while (!targ.isSubtypeOf(arg.getUnit().getEmptyType())) {
                gen.out(",");
                arg.visit(gen);
                gen.out(".$_get(" + (i++) + ")");
                targ = targ.getTypeArgumentList().get(2);
            }
        } else {
            arg.visit(gen);
        }
    } else if (pd.isSequenced()) {
        arg.visit(gen);
        if (!arg.getUnit().isSequentialType(arg.getTypeModel())) {
            gen.out(".sequence()");
        }
    } else if (!arg.getTypeModel().isEmpty()) {
        final String specialSpreadVar = gen.getNames().createTempVariable();
        gen.out("(", specialSpreadVar, "=");
        arg.visit(gen);
        final boolean unknownSpread = arg.getTypeModel().isUnknown();
        final String get0 = unknownSpread ? "[" : ".$_get(";
        final String get1 = unknownSpread ? "]" : ")";
        if (!unknownSpread && !arg.getUnit().isSequentialType(arg.getTypeModel())) {
            gen.out(".sequence()");
        }
        gen.out(",");
        if (pd.isDefaulted()) {
            gen.out(gen.getClAlias(), "nn$(", specialSpreadVar, get0, "0", get1, ")?", specialSpreadVar, get0, "0", get1, ":undefined)");
        } else {
            gen.out(specialSpreadVar, get0, "0", get1, ")");
        }
        // Find out if there are more params
        final List<Parameter> moreParams;
        final Declaration pdd = pd.getDeclaration();
        boolean found = false;
        if (pdd instanceof Function) {
            moreParams = ((Function) pdd).getFirstParameterList().getParameters();
        } else if (pdd instanceof Class) {
            moreParams = ((Class) pdd).getParameterList().getParameters();
        } else {
            // Check the parameters of the primary (obviously a callable, so this is a Tuple)
            List<Parameter> cparms = TypeUtils.convertTupleToParameters(primary.getTypeModel().getTypeArgumentList().get(1));
            cparms.remove(0);
            moreParams = cparms;
            found = true;
        }
        if (moreParams != null) {
            int c = 1;
            for (Parameter restp : moreParams) {
                if (found) {
                    final String cs = Integer.toString(c++);
                    if (restp.isDefaulted()) {
                        gen.out(",", gen.getClAlias(), "nn$(", specialSpreadVar, get0, cs, get1, ")?", specialSpreadVar, get0, cs, get1, ":undefined");
                    } else if (restp.isSequenced()) {
                        if (c == 2) {
                            gen.out(",", specialSpreadVar, ".rest");
                        } else {
                            gen.out(",", specialSpreadVar, ".sublistFrom(", cs, ")");
                        }
                    } else {
                        gen.out(",", specialSpreadVar, get0, cs, get1);
                    }
                } else {
                    found = restp.equals(pd);
                }
            }
        }
    }
    gen.boxUnboxEnd(boxType);
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) List(java.util.List) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 73 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function 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 74 with Function

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

the class TypeGenerator method interfaceDefinition.

static void interfaceDefinition(final Tree.InterfaceDefinition that, final GenerateJsVisitor gen, InitDeferrer initDeferrer) {
    // Don't even bother with nodes that have errors
    if (errVisitor.hasErrors(that))
        return;
    final Interface d = that.getDeclarationModel();
    // If it's inside a dynamic interface, don't generate anything
    if (d.isClassOrInterfaceMember() && ((ClassOrInterface) d.getContainer()).isDynamic())
        return;
    final Interface natd = (Interface) ModelUtil.getNativeDeclaration(d, Backend.JavaScript);
    final boolean headerWithoutBackend = NativeUtil.isHeaderWithoutBackend(that, Backend.JavaScript);
    if (natd != null && (headerWithoutBackend || NativeUtil.isNativeHeader(that))) {
        // It's a native header, remember it for later when we deal with its implementation
        gen.saveNativeHeader(that);
        return;
    }
    if (!(NativeUtil.isForBackend(that, Backend.JavaScript) || headerWithoutBackend)) {
        return;
    }
    gen.comment(that);
    gen.out(GenerateJsVisitor.function, gen.getNames().name(d));
    final boolean withTargs = generateParameters(that.getTypeParameterList(), null, d, gen);
    gen.beginBlock();
    final List<Declaration> superDecs = new ArrayList<>(3);
    if (!gen.opts.isOptimize()) {
        new SuperVisitor(superDecs).visit(that.getInterfaceBody());
    }
    final Tree.SatisfiedTypes sats = that.getSatisfiedTypes();
    if (withTargs) {
        gen.out(gen.getClAlias(), "set_type_args(", gen.getNames().self(d), ",$$targs$$,", gen.getNames().name(d), ")");
        gen.endLine(true);
    }
    callSupertypes(sats == null ? null : TypeUtils.getTypes(sats.getTypes()), null, d, that, superDecs, null, null, gen);
    if (!d.isToplevel() && d.getContainer() instanceof Function && !((Function) d.getContainer()).getTypeParameters().isEmpty()) {
        gen.out(gen.getClAlias(), "set_type_args(", gen.getNames().self(d), ",", gen.getNames().typeArgsParamName((Function) d.getContainer()), ",", gen.getNames().name(d), ")");
        gen.endLine(true);
    }
    final List<Tree.Statement> stmts;
    if (NativeUtil.isForBackend(d, Backend.JavaScript)) {
        Tree.Declaration nh = gen.getNativeHeader(d);
        if (nh == null && NativeUtil.hasNativeMembers(d)) {
            nh = that;
        }
        stmts = NativeUtil.mergeStatements(that.getInterfaceBody(), nh, Backend.JavaScript);
    } else {
        stmts = that.getInterfaceBody().getStatements();
    }
    gen.visitStatements(stmts);
    // returnSelf(d);
    gen.endBlockNewLine();
    if (d.isDynamic()) {
        // Add the list of expected members here
        final List<Declaration> members = d.getMembers();
        gen.out(gen.getNames().name(d), ".dynmem$=[");
        if (members.isEmpty()) {
            gen.out("];");
        } else {
            gen.out("'");
            boolean first = true;
            for (Declaration m : members) {
                if (first)
                    first = false;
                else
                    gen.out("','");
                gen.out(gen.getNames().name(m));
            }
            gen.out("'];");
        }
    }
    // Add reference to metamodel
    gen.out(gen.getNames().name(d), ".$crtmm$=");
    TypeUtils.encodeForRuntime(that, d, that.getAnnotationList(), gen);
    gen.endLine(true);
    gen.share(d);
    initializeType(that, gen, initDeferrer);
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) SuperVisitor(org.eclipse.ceylon.compiler.js.GenerateJsVisitor.SuperVisitor) ArrayList(java.util.ArrayList) 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) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)

Example 75 with Function

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

the class AbstractModelLoader method addConstructorMethorOrValue.

protected FunctionOrValue addConstructorMethorOrValue(Class klass, ClassMirror classMirror, MethodMirror ctor, Constructor constructor, boolean isNativeHeader) {
    boolean isCeylon = classMirror.getAnnotation(CEYLON_CEYLON_ANNOTATION) != null;
    if (ctor.getAnnotation(CEYLON_ENUMERATED_ANNOTATION) != null) {
        klass.setEnumerated(true);
        Value v = new Value();
        v.setName(constructor.getName());
        v.setType(constructor.getType());
        v.setContainer(klass);
        v.setScope(klass);
        v.setUnit(klass.getUnit());
        v.setVisibleScope(constructor.getVisibleScope());
        // read annotations from the getter method
        setNonLazyDeclarationProperties(v, ctor, ctor, classMirror, isCeylon);
        setAnnotations(v, ctor, isNativeHeader);
        klass.addMember(v);
        return v;
    } else {
        setParameters(constructor, classMirror, ctor, true, klass, false);
        klass.setConstructors(true);
        Function f = new Function();
        f.setName(constructor.getName());
        f.setType(constructor.getType());
        f.addParameterList(constructor.getParameterList());
        f.setContainer(klass);
        f.setScope(klass);
        f.setUnit(klass.getUnit());
        f.setVisibleScope(constructor.getVisibleScope());
        // read annotations from the constructor
        setNonLazyDeclarationProperties(f, ctor, ctor, classMirror, isCeylon);
        setAnnotations(f, ctor, isNativeHeader);
        klass.addMember(f);
        return f;
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction) JavaParameterValue(org.eclipse.ceylon.model.loader.model.JavaParameterValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) LazyValue(org.eclipse.ceylon.model.loader.model.LazyValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue)

Aggregations

Function (org.eclipse.ceylon.model.typechecker.model.Function)167 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)71 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)70 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)69 Type (org.eclipse.ceylon.model.typechecker.model.Type)68 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)62 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)57 Value (org.eclipse.ceylon.model.typechecker.model.Value)50 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)46 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)43 Class (org.eclipse.ceylon.model.typechecker.model.Class)39 ArrayList (java.util.ArrayList)32 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)29 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)26 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)23 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)23 TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)23 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)23 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)22 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)21