diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java index 8f76137..21a2454 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java @@ -1,14 +1,88 @@ 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.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 codes) { - return codes; + public static ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model, ArrayList types) { + // 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(); + TypeDeclaration dstType = typeMap.get(dst.getIdentifierTemplate().getResourceName()); + 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.addStatement(dst.getIdentifierTemplate().getResourceName() + " = " + curState + ";"); + MethodDeclaration getter = getGetterMethod(dstType); + getter.addStatement("return " + dst.getIdentifierTemplate().getResourceName() + ";"); + } 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(); + } + 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; } }