private void rewriteFuncRefs(final List<ImFuncRef> funcRefs, Set<ImFunction> affectedFuncs) {
    // rewrite funcrefs
    for (ImFuncRef fr : funcRefs) {
      ImFunction f = fr.getFunc();
      if (!affectedFuncs.contains(f)) {
        continue;
      }

      ImFunction bridgeFunc =
          JassIm.ImFunction(
              f.getTrace(),
              "bridge_" + f.getName(),
              f.getParameters().copy(),
              (ImType) f.getReturnType().copy(),
              JassIm.ImVars(),
              JassIm.ImStmts(),
              f.getFlags());
      prog.getFunctions().add(bridgeFunc);

      // remove statcktrace var from params
      bridgeFunc.getParameters().remove(getStackTraceVar(bridgeFunc));

      ImStmt stmt;
      ImExprs args = JassIm.ImExprs(str("\n   " + fr.attrTrace().attrSource().printShort()));
      ImFunctionCall call = JassIm.ImFunctionCall(fr.attrTrace(), f, args, true, CallType.NORMAL);
      if (bridgeFunc.getReturnType() instanceof ImVoid) {
        stmt = call;
      } else {
        stmt = JassIm.ImReturn(fr.attrTrace(), call);
      }
      bridgeFunc.getBody().add(stmt);

      fr.setFunc(bridgeFunc);
    }
  }
 private void passStacktraceParams(
     final Multimap<ImFunction, ImFunctionCall> calls, Set<ImFunction> affectedFuncs) {
   // pass the stacktrace parameter at all cals
   for (ImFunction f : affectedFuncs) {
     for (ImFunctionCall call : calls.get(f)) {
       ImFunction caller = call.getNearestFunc();
       ImExpr stExpr;
       if (isMainOrConfig(caller)) {
         stExpr = str("   " + f.getName());
       } else {
         ImVar stackTraceVar = getStackTraceVar(caller);
         WPos source = call.attrTrace().attrSource();
         String callPos;
         if (source.getFile().startsWith("<")) {
           callPos = "";
         } else {
           callPos = "\n   " + source.printShort();
         }
         stExpr =
             JassIm.ImOperatorCall(
                 WurstOperator.PLUS,
                 JassIm.ImExprs(str(callPos), JassIm.ImVarAccess(stackTraceVar)));
       }
       call.getArguments().add(stExpr);
     }
   }
 }
 private ImVar getStackTraceVar(ImFunction f) {
   if (!f.getParameters().isEmpty()) {
     ImVar v = f.getParameters().get(f.getParameters().size() - 1);
     if (v.getName().equals(WURST_STACK_TRACE)) {
       return v;
     }
   }
   throw new Error("no stacktrace var found in: " + f.getName());
 }
 private void addStackTraceParams(Set<ImFunction> affectedFuncs) {
   // add parameter to affected functions
   for (ImFunction f : affectedFuncs) {
     if (isMainOrConfig(f)) {
       continue;
     }
     f.getParameters()
         .add(
             JassIm.ImVar(
                 f.getTrace(),
                 WurstTypeString.instance().imTranslateType(),
                 WURST_STACK_TRACE,
                 false));
   }
 }
  private void translateInterfaceFuncDef(
      InterfaceDef interfaceDef, List<ClassDef> instances, FuncDef funcDef) {
    AstElement trace = funcDef;
    ImFunction f = translator.getDynamicDispatchFuncFor(funcDef);
    Map<ClassDef, FuncDef> instances2 = translator.getClassesWithImplementation(instances, funcDef);
    if (instances2.size() > 0) {
      int maxTypeId = translator.getMaxTypeId(instances);
      f.getBody()
          .addAll(
              translator.createDispatch(instances2, funcDef, f, maxTypeId, new TypeIdGetterImpl()));
    }
    if (!funcDef.attrHasEmptyBody()) {
      // TODO add default implementation
      f.getBody().addAll(translator.translateStatements(f, funcDef.getBody()));
    } else {
      // create dynamic message when not matched:
      String msg =
          "ERROR: invalid type for interface dispatch when calling "
              + interfaceDef.getName()
              + "."
              + funcDef.getName();

      f.getBody()
          .add(
              JassIm.ImFunctionCall(
                  trace, translator.getDebugPrintFunc(), ImExprs(ImStringVal(msg))));
      if (!(funcDef.attrTyp() instanceof WurstTypeVoid)) {
        // add return statement
        ImType type = f.getReturnType();
        ImExpr def = translator.getDefaultValueForJassType(type);
        f.getBody().add(JassIm.ImReturn(trace, def));
      }
    }
  }
Esempio n. 6
0
 public String getMessage() {
   StringBuilder sb = new StringBuilder();
   sb.append("... when calling " + f.getName() + "(");
   boolean first = true;
   for (ILconst arg : args) {
     if (!first) {
       sb.append(", ");
     }
     sb.append(arg);
     first = false;
   }
   sb.append(")");
   return sb.toString();
 }
Esempio n. 7
0
  private void translateInterfaceFuncDef(FuncDef f) {
    ImMethod imMeth = translator.getMethodFor(f);
    ImFunction imFunc = translator.getFuncFor(f);
    imClass.getMethods().add(imMeth);

    // translate implementation
    if (f.attrHasEmptyBody()) {
      imMeth.setIsAbstract(true);
    } else {
      // there is a default implementation
      imFunc.getBody().addAll(translator.translateStatements(imFunc, f.getBody()));
    }

    List<ClassDef> subClasses = Lists.newArrayList(translator.getInterfaceInstances(interfaceDef));
    // TODO also add extended interfaces

    // set sub methods
    Map<ClassDef, FuncDef> subClasses2 = translator.getClassesWithImplementation(subClasses, f);
    for (Entry<ClassDef, FuncDef> subE : subClasses2.entrySet()) {
      ClassDef subC = subE.getKey();
      ImmutableCollection<WurstTypeInterface> interfaces = subC.attrImplementedInterfaces();

      Map<TypeParamDef, WurstTypeBoundTypeParam> typeBinding =
          interfaces
              .stream()
              .filter(t -> t.getDef() == interfaceDef)
              .map(t -> t.getTypeArgBinding())
              .findFirst()
              .orElse(Collections.emptyMap());

      FuncDef subM = subE.getValue();
      ImMethod m = translator.getMethodFor(subM);

      ImClass mClass = translator.getClassFor(subC);
      OverrideUtils.addOverride(translator, f, mClass, m, subM, typeBinding);
    }
  }
 private boolean isMainOrConfig(ImFunction f) {
   return f.getName().equals("main") || f.getName().equals("config");
 }