void outputMetamodelAndReturn(GenerateJsVisitor gen, Type t) { gen.out(name, ".$crtmm$=function(){return{", MetamodelGenerator.KEY_PARAMS, ":"); TypeUtils.encodeParameterListForRuntime(true, n, params.getModel(), gen); if (t != null) { // Add the type to the innermost method gen.out(",", MetamodelGenerator.KEY_TYPE, ":"); TypeUtils.typeNameOrList(n, t, gen, false); } gen.out("};};return ", gen.getClAlias(), "jsc$3(0,", name, ");"); }
static void objectArgument(final Tree.ObjectArgument that, final GenerateJsVisitor gen) { final Class c = (Class) that.getDeclarationModel().getTypeDeclaration(); gen.out("(function()"); gen.beginBlock(); gen.out("//ObjectArgument ", that.getIdentifier().getText()); gen.location(that); gen.endLine(); gen.out(GenerateJsVisitor.function, gen.getNames().name(c), "()"); gen.beginBlock(); gen.instantiateSelf(c); gen.referenceOuter(c); Tree.ExtendedType xt = that.getExtendedType(); final Tree.ClassBody body = that.getClassBody(); final Tree.SatisfiedTypes sts = that.getSatisfiedTypes(); final List<Declaration> superDecs = new ArrayList<Declaration>(3); if (!gen.opts.isOptimize()) { new GenerateJsVisitor.SuperVisitor(superDecs).visit(that.getClassBody()); } TypeGenerator.callSupertypes( sts == null ? null : TypeUtils.getTypes(sts.getTypes()), xt == null ? null : xt.getType(), c, that, superDecs, xt == null ? null : xt.getInvocationExpression(), xt == null ? null : c.getParameterList(), gen); body.visit(gen); gen.out("return ", gen.getNames().self(c), ";"); gen.endBlock(false, true); // Add reference to metamodel gen.out(gen.getNames().name(c), ".$crtmm$="); TypeUtils.encodeForRuntime(that, c, gen); gen.endLine(true); TypeGenerator.typeInitialization( xt, sts, c, new GenerateJsVisitor.PrototypeInitCallback() { @Override public void addToPrototypeCallback() { gen.addToPrototype(that, c, body.getStatements()); } }, gen, null, null); gen.out("return ", gen.getNames().name(c), "(new ", gen.getNames().name(c), ".$$);"); gen.endBlock(); gen.out("())"); }
static void generateCallable( final Tree.QualifiedMemberOrTypeExpression that, String name, final GenerateJsVisitor gen) { final Declaration d = that.getDeclaration(); if (that.getPrimary() instanceof Tree.BaseTypeExpression) { // it's a static method ref if (name == null) { name = gen.memberAccess(that, ""); } if (TypeUtils.isConstructor(d)) { Constructor cd = TypeUtils.getConstructor(d); final boolean hasTargs = BmeGenerator.hasTypeParameters((Tree.BaseTypeExpression) that.getPrimary()); if (hasTargs) { if (that.getDirectlyInvoked()) { gen.out( gen.qualifiedPath(that, cd), gen.getNames().constructorSeparator(cd), gen.getNames().name(cd)); } else { BmeGenerator.printGenericMethodReference( gen, (Tree.BaseTypeExpression) that.getPrimary(), "0", gen.qualifiedPath(that, cd) + gen.getNames().constructorSeparator(cd) + gen.getNames().name(cd)); } } else { gen.qualify(that, cd); gen.out(gen.getNames().name(cd)); if (cd.isValueConstructor()) { gen.out("()"); } } } else if (d.isStatic()) { BmeGenerator.generateStaticReference(that, d, gen); } else { gen.out("function(x){return "); if (BmeGenerator.hasTypeParameters(that)) { BmeGenerator.printGenericMethodReference(gen, that, "x", "x." + name); } else { gen.out(gen.getClAlias(), "jsc$3(x,x.", name, ")"); } gen.out(";}"); } return; } if (d.isToplevel() && d instanceof Function) { // Just output the name gen.out(gen.getNames().name(d)); return; } String primaryVar = gen.createRetainedTempVar(); gen.out("(", primaryVar, "="); that.getPrimary().visit(gen); if (!(that.getStaticMethodReferencePrimary() && !TypeUtils.isConstructor(that.getDeclaration()))) { gen.out(","); final String member = (name == null) ? gen.memberAccess(that, primaryVar) : (primaryVar + "." + name); if (that.getDeclaration() instanceof Function && !((Function) that.getDeclaration()).getTypeParameters().isEmpty()) { // Function ref with type parameters BmeGenerator.printGenericMethodReference(gen, that, primaryVar, member); } else { if (that.getUnit().isOptionalType(that.getPrimary().getTypeModel())) { gen.out( gen.getClAlias(), "jsc$3(", primaryVar, ",", gen.getClAlias(), "nn$(", primaryVar, ")?", member, ":null)"); } else { gen.out(gen.getClAlias(), "jsc$3(", primaryVar, ",", member, ")"); } } } gen.out(")"); }
static void methodDefinition( final Tree.MethodDefinition that, final GenerateJsVisitor gen, final boolean needsName, final boolean verboseStitcher) { final Function d = that.getDeclarationModel(); if (TypeUtils.isNativeExternal(d)) { if (gen.stitchNative(d, that)) { if (verboseStitcher) { gen.spitOut( "Stitching in native method " + d.getQualifiedNameString() + ", ignoring Ceylon definition"); } if (d.isShared()) { gen.share(d); } return; } } if (that.getParameterLists().size() == 1) { if (needsName) { gen.out(GenerateJsVisitor.function, gen.getNames().name(d)); } else { gen.out("function"); } Tree.ParameterList paramList = that.getParameterLists().get(0); paramList.visit(gen); gen.beginBlock(); if (d.getContainer() instanceof TypeDeclaration) { gen.initSelf(that); } addParentMethodTypeParameters(d, gen); gen.initParameters(paramList, null, d); gen.visitStatements(that.getBlock().getStatements()); gen.endBlock(); } else { List<MplData> metas = new ArrayList<>(that.getParameterLists().size()); for (Tree.ParameterList paramList : that.getParameterLists()) { final MplData mpl = new MplData(); mpl.n = that; metas.add(mpl); if (metas.size() == 1) { if (needsName) { gen.out(GenerateJsVisitor.function, gen.getNames().name(d)); } else { gen.out("function"); } } else { mpl.name = gen.getNames().createTempVariable(); mpl.params = paramList; gen.out("var ", mpl.name, "=function"); } paramList.visit(gen); gen.beginBlock(); if (metas.size() == 1 && d.getContainer() instanceof TypeDeclaration) { gen.initSelf(that); } gen.initParameters(paramList, null, d); } gen.visitStatements(that.getBlock().getStatements()); closeMPL(metas, d.getType(), gen); gen.endBlock(); } if (!gen.share(d)) { gen.out(";"); } }
static void methodDeclaration( TypeDeclaration outer, Tree.MethodDeclaration that, GenerateJsVisitor gen, boolean verboseStitcher) { final Function m = that.getDeclarationModel(); if (that.getSpecifierExpression() != null) { // method(params) => expr if (outer == null) { // Not in a prototype definition. Null to do here if it's a // member in prototype style. if (gen.opts.isOptimize() && m.isMember()) { return; } gen.comment(that); gen.initDefaultedParameters(that.getParameterLists().get(0), that); if (!(gen.opts.isOptimize() && m.isClassOrInterfaceMember()) && TypeUtils.isNativeExternal(m)) { if (gen.stitchNative(m, that)) { if (verboseStitcher) { gen.spitOut( "Stitching in native method " + m.getQualifiedNameString() + ", ignoring Ceylon declaration"); } if (m.isShared()) { gen.share(m); } return; } } gen.out(m.isToplevel() ? GenerateJsVisitor.function : "var "); } else { // prototype definition gen.comment(that); gen.initDefaultedParameters(that.getParameterLists().get(0), that); if (m.isStatic()) { gen.out(gen.getNames().name(outer), ".$st$."); } else { gen.out(gen.getNames().self(outer), "."); } } gen.out(gen.getNames().name(m)); if (!m.isToplevel()) gen.out("="); if (TypeUtils.isNativeExternal(m)) { if (gen.stitchNative(m, that)) { if (verboseStitcher) { gen.spitOut( "Stitching in native method " + m.getQualifiedNameString() + ", ignoring Ceylon declaration"); } if (m.isShared()) { gen.share(m); } return; } } singleExprFunction( that.getParameterLists(), that.getSpecifierExpression().getExpression(), m, true, !m.isToplevel(), gen); gen.endLine(true); if (outer != null) { if (m.isStatic()) { gen.out(gen.getNames().name(outer), ".$st$."); } else { gen.out(gen.getNames().self(outer), "."); } } gen.out(gen.getNames().name(m), ".$crtmm$="); TypeUtils.encodeMethodForRuntime(that, gen); gen.endLine(true); gen.share(m); } else if (outer == null // don't do the following in a prototype definition && m == that.getScope()) { // Check for refinement of simple param declaration if (m.getContainer() instanceof Class && m.isClassOrInterfaceMember()) { // Declare the method just by pointing to the param function final String name = gen.getNames().name(((Class) m.getContainer()).getParameter(m.getName())); if (name != null) { gen.out( gen.getNames().self((Class) m.getContainer()), ".", gen.getNames().name(m), "=", name); gen.endLine(true); } } else if (m.getContainer() instanceof Function) { // Declare the function just by forcing the name we used in the param list final String name = gen.getNames().name(((Function) m.getContainer()).getParameter(m.getName())); gen.getNames().forceName(m, name); } // Only the first paramlist can have defaults gen.initDefaultedParameters(that.getParameterLists().get(0), that); if (!(gen.opts.isOptimize() && m.isClassOrInterfaceMember()) && TypeUtils.isNativeExternal(m)) { if (gen.stitchNative(m, that)) { if (verboseStitcher) { gen.spitOut( "Stitching in native method " + m.getQualifiedNameString() + ", ignoring Ceylon declaration"); } if (m.isShared()) { gen.share(m); } } } } else if (m == that.getScope() && m.getContainer() instanceof TypeDeclaration && m.isMember() && (m.isFormal() || TypeUtils.isNativeExternal(m))) { gen.out( gen.getNames().self((TypeDeclaration) m.getContainer()), ".", gen.getNames().name(m), "="); if (m.isFormal()) { gen.out("{$fml:1,$crtmm$:"); TypeUtils.encodeForRuntime(that, m, gen); gen.out("};"); } else if (TypeUtils.isNativeExternal(m)) { if (gen.stitchNative(m, that)) { if (verboseStitcher) { gen.spitOut( "Stitching in native method " + m.getQualifiedNameString() + ", ignoring Ceylon declaration"); } if (m.isShared()) { gen.share(m); } } } } }