diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java new file mode 100644 index 0000000..21a2454 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/MethodBodyGenerator.java @@ -0,0 +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 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; + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java b/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java index 73e20f1..abea107 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java @@ -17,4 +17,12 @@ public void addStatement(String statement) { statements.add(statement); } + + public String toString() { + String code = ""; + for (String statement: statements) { + code += (statement + "\n"); + } + return code; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java index 434fee8..038dc6a 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/FieldDeclaration.java @@ -5,6 +5,7 @@ public class FieldDeclaration extends BodyDeclaration { private Type type; private String fieldName; + private String initializer; public FieldDeclaration(Type type, String fieldName) { this.type = type; @@ -26,8 +27,19 @@ public void setName(String fieldName) { this.fieldName = fieldName; } + + public String getInitializer() { + return initializer; + } + + public void setInitializer(String initializer) { + this.initializer = initializer; + } public String toString() { - return type.getImplementationTypeName() + " " + fieldName + ";\n"; + if (initializer == null) { + return type.getImplementationTypeName() + " " + fieldName + ";\n"; + } + return type.getImplementationTypeName() + " " + fieldName + " = " + initializer + ";\n"; } } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java index e2f02ea..f7b9c4f 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java @@ -98,12 +98,14 @@ code += returnType.getImplementationTypeName() + " "; } code += (name + "("); - String delimitar = ""; - for (VariableDeclaration parameter: parameters) { - code = code + delimitar + parameter.toString(); - delimitar = ", "; + if (parameters != null) { + String delimitar = ""; + for (VariableDeclaration parameter: parameters) { + code = code + delimitar + parameter.toString(); + delimitar = ", "; + } } - code += ") {"; + code += ") {\n"; if (body != null) { code += CodeUtil.insertTab(body.toString()); } diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/PrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/PrototypeGenerateAction.java index d1e4e86..f5f090e 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/PrototypeGenerateAction.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/PrototypeGenerateAction.java @@ -2,8 +2,7 @@ import java.awt.event.ActionEvent; -import algorithms.CodeGenerator; -import algorithms.DataStorageDecision; +import algorithms.*; import code.ast.*; import graphicalrefactor.editor.Editor; import models.dataFlowModel.DataFlowModel; @@ -24,9 +23,9 @@ ResourceDependencyGraph graph = editor.getResourceGraph(); DataFlowModel model = editor.getModel(); DataStorageDecision.run(graph); - editor.setCodes(CodeGenerator.doGenerate(graph,model)); - for(String str:CodeGenerator.getCodes(editor.getCodes())) { - System.out.println(str); + editor.setCodes(MethodBodyGenerator.doGenerate(graph, model, CodeGenerator.doGenerate(graph, model))); + for (TypeDeclaration type: editor.getCodes()) { + System.out.println(type); } }