diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java new file mode 100644 index 0000000..c27b6b3 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java @@ -0,0 +1,113 @@ +package algorithms; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import code.ast.MethodDeclaration; +import code.ast.TypeDeclaration; +import models.Edge; +import models.Node; +import models.algebra.InvalidMessage; +import models.algebra.ParameterizedIdentifierIsFutureWork; +import models.algebra.Symbol; +import models.algebra.UnificationFailed; +import models.algebra.ValueUndefined; +import models.dataConstraintModel.ChannelMember; +import models.dataFlowModel.DataFlowModel; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; +import models.dataFlowModel.ResourceDependency; +import models.dataFlowModel.ResourceDependencyGraph; +import models.dataFlowModel.ResourceNode; + +public class MethodBodyGenerator { + public static ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model, ArrayList types) { + Symbol floor = model.getSymbol("floor"); + Symbol.Memento floorMem = null; + if (floor != null) { + floorMem = floor.createMemento(); + floor.setImplName("(int)Math.floor"); + floor.setImplOperatorType(Symbol.Type.PREFIX); + } + Symbol sum = model.getSymbol("sum"); + Symbol.Memento sumMem = null; + if (sum != null) { + sumMem = sum.createMemento(); + sum.setImplName("stream().mapToInt(x->x).sum"); + sum.setImplOperatorType(Symbol.Type.METHOD); + } + + // Create a map from type names (lower case) to their types. + Map typeMap = new HashMap<>(); + for (TypeDeclaration type: types) { + typeMap.put(type.getTypeName().toLowerCase(), type); + } + + // Generate the body of each update or getter method. + try { + for (Edge e: graph.getEdges()) { + ResourceDependency d = (ResourceDependency) e; + PushPullAttribute pushPull = (PushPullAttribute) d.getAttribute(); + ResourceNode src = (ResourceNode) d.getSource(); + ResourceNode dst = (ResourceNode) d.getDestination(); + String srcResourceName = src.getIdentifierTemplate().getResourceName(); + String dstResourceName = dst.getIdentifierTemplate().getResourceName(); + TypeDeclaration srcType = typeMap.get(srcResourceName); + TypeDeclaration dstType = typeMap.get(dstResourceName); + for (ChannelMember out: d.getChannelGenerator().getOutputChannelMembers()) { + if (out.getIdentifierTemplate() == dst.getIdentifierTemplate()) { + if (pushPull.getOptions().get(0) == PushPullValue.PUSH) { + // push + MethodDeclaration update = getUpdateMethod(dstType); + String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, CodeGenerator.pushAccessor).toImplementation(); + update.addFirstStatement(dstResourceName + " = " + curState + ";"); + MethodDeclaration getter = getGetterMethod(dstType); + getter.addStatement("return " + dstResourceName + ";"); + // src side + MethodDeclaration srcUpdate = getUpdateMethod(srcType); + if (srcUpdate != null) srcUpdate.addStatement(dstResourceName + ".update(" + srcResourceName + ");"); + } else { + // pull or push/pull + MethodDeclaration getter = getGetterMethod(dstType); + String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, CodeGenerator.pullAccessor).toImplementation(); + getter.addStatement("return " + curState + ";"); + } + } + } + } + for (Node n: graph.getNodes()) { + ResourceNode resource = (ResourceNode) n; + TypeDeclaration type = typeMap.get(resource.getIdentifierTemplate().getResourceName()); + MethodDeclaration getter = getGetterMethod(type); + if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { + getter.addStatement("return " + resource.getIdentifierTemplate().getResourceName() + ";"); + } + } + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e1) { + e1.printStackTrace(); + } + + if (floor != null) floor.setMemento(floorMem); + if (sum != null) sum.setMemento(sumMem); + return types; + } + + private static MethodDeclaration getUpdateMethod(TypeDeclaration dstType) { + for (MethodDeclaration m: dstType.getMethods()) { + if (m.getName().startsWith("update")) return m; + if (m.getName().startsWith("set")) return m; + } + return null; + } + + private static MethodDeclaration getGetterMethod(TypeDeclaration dstType) { + for (MethodDeclaration m: dstType.getMethods()) { + if (m.getName().startsWith("get")) return m; + } + return null; + } + +}