Beispiel #1
0
 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, ");");
 }
Beispiel #2
0
  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("())");
  }
Beispiel #3
0
 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(")");
 }
Beispiel #4
0
  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(";");
    }
  }
Beispiel #5
0
  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);
          }
        }
      }
    }
  }