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; + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java b/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java index 73e20f1..2b4f654 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java @@ -14,7 +14,19 @@ this.statements = statements; } + public void addFirstStatement(String statement) { + statements.add(0, statement); + } + 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..c66b438 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java @@ -90,6 +90,13 @@ body.addStatement(statement); } + public void addFirstStatement(String statement) { + if (body == null) { + body = new Block(); + } + body.addFirstStatement(statement); + } + public String toString() { String code = "public "; if (returnType == null) { @@ -98,12 +105,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); } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java index 1192085..37f32d7 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java @@ -56,6 +56,10 @@ public String getName() { return name; } + + public Type getOperatorType() { + return operatorType; + } public boolean isInfix() { return (operatorType == Type.INFIX); @@ -85,6 +89,10 @@ return implName; } + public void setImplName(String implName) { + this.implName = implName; + } + public Type getImplOperatorType() { return implOperatorType; } @@ -96,6 +104,10 @@ public boolean isImplMethod() { return (implOperatorType == Type.METHOD); } + + public void setImplOperatorType(Type implOperatorType) { + this.implOperatorType = implOperatorType; + } public int[] getImplParamOrder() { return implParamOrder; @@ -124,4 +136,23 @@ INFIX, METHOD } + + public Memento createMemento() { + return new Memento(implName, implOperatorType); + } + + public void setMemento(Memento memento) { + this.implName = memento.implName; + this.implOperatorType = memento.implOperatorType; + } + + public static class Memento { + private String implName; + private Type implOperatorType = Type.PREFIX; + + public Memento(String implName, Type implOperatorType) { + this.implName = implName; + this.implOperatorType = implOperatorType; + } + } }