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)); } } }
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 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); } }