diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java index 92b552b..754c104 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java @@ -65,9 +65,9 @@ } ControlFlowGraph controlFlowGraph = editor.getControlFlowGraph(); if (controlFlowGraph != null) { - editor.setCodes(CodeGenerator.doGenerate(model, controlFlowGraph, new JavaSpecific())); + editor.setCodes(CodeGenerator.generateCode(model, controlFlowGraph, new JavaSpecific())); } else { - editor.setCodes(CodeGenerator.doGenerate(model, dataFlowgraph, new JavaSpecific())); + editor.setCodes(CodeGenerator.generateCode(model, dataFlowgraph, new JavaSpecific())); } ModelExtension.recoverModel(model); for (CompilationUnit file : editor.getCodes()) { diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java index 6b1890c..86f5e35 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -23,6 +23,7 @@ import models.algebra.UnificationFailed; import models.algebra.ValueUndefined; import models.algebra.Variable; +import models.controlFlowModel.ControlFlowGraph; import models.controlFlowModel.EntryPointObjectNode; import models.controlFlowModel.ObjectNode; import models.controlFlowModel.StatefulObjectNode; @@ -30,6 +31,7 @@ import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.IdentifierTemplate; import models.dataFlowModel.DataFlowEdge; +import models.dataFlowModel.DataFlowGraph; import models.dataFlowModel.DataTransferChannelGenerator; import models.dataFlowModel.DataTransferModel; import models.dataFlowModel.IFlowGraph; @@ -72,8 +74,10 @@ * @param langSpec specified language * @return source codes */ - static public ArrayList doGenerate(DataTransferModel model, IFlowGraph flowGraph, ILanguageSpecific langSpec) { + static public ArrayList generateCode(DataTransferModel model, IFlowGraph flowGraph, ILanguageSpecific langSpec) { ArrayList codes = new ArrayList<>(); + + // Sort the all components. ArrayList components = determineComponentOrder(flowGraph); // Add the main component. @@ -85,72 +89,11 @@ CompilationUnit mainCU = langSpec.newCompilationUnit(mainComponent); codes.add(mainCU); - // For each of other components. - for (Node componentNode: components) { - // Declare this component. - String componentName = null; - if (componentNode instanceof ResourceNode) { - componentName = langSpec.toComponentName(((ResourceNode) componentNode).getIdentifierTemplate().getResourceName()); - } else if (componentNode instanceof ObjectNode) { - componentName = langSpec.toComponentName(((ObjectNode) componentNode).getName()); - } - TypeDeclaration component = langSpec.newTypeDeclaration(componentName); - - // Declare the constructor and the fields to refer to other resources (to the callee components). - MethodDeclaration constructor = null; - List depends = new ArrayList<>(); - if (componentNode instanceof ResourceNode) { - // For data-flow graph - constructor = declareConstructorAndFieldsToReferToResources((ResourceNode) componentNode, component, depends, langSpec); - } else if (componentNode instanceof ObjectNode) { - // For control-flow graph - constructor = declareConstructorAndFieldsToCalleeComponents((ObjectNode) componentNode, component, depends, langSpec); - } - - // Update the main component for this component. - updateMainComponent(model, mainComponent, mainConstructor, componentNode, depends, langSpec); - - if (componentNode instanceof ResourceNode || componentNode instanceof StatefulObjectNode) { - // For this resource. - ResourceNode resourceNode = null; - if (componentNode instanceof ResourceNode) { - // For data-flow graph - resourceNode = (ResourceNode) componentNode; - } else if (componentNode instanceof StatefulObjectNode) { - // For control-flow graph - resourceNode = ((StatefulObjectNode) componentNode).getResource(); - } - IdentifierTemplate resId = resourceNode.getIdentifierTemplate(); - Type resStateType = resId.getResourceStateType(); - - // Declare the field in this resource to store the state. - if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { - FieldDeclaration stateField = langSpec.newFieldDeclaration(resStateType, fieldOfResourceState, langSpec.getFieldInitializer(resStateType, resId.getInitialValue())); - component.addField(stateField); - } - - // Declare the getter method in this resource to obtain the state. - MethodDeclaration getter = declareGetterMethod(resourceNode, component, resStateType, langSpec); - - // Declare the accessor method in the main component to call the getter method. - declareAccessorInMainComponent(mainComponent, resId, langSpec); - - // Declare the fields to refer to reference resources. - declareFieldsToReferenceResources(model, resourceNode, component, constructor, depends, langSpec); - - // Declare cache fields and update methods in this resource. - List updates = declareCacheFieldsAndUpdateMethods(resourceNode, component, langSpec); - - // Declare input methods in this component and the main component. - List inputs = declareInputMethodsInThisAndMainComponents(resourceNode, component, mainComponent, model, langSpec); - } - if (constructor.getParameters() == null) { - component.removeMethod(constructor); - } - - // Add compilation unit for this component. - CompilationUnit cu = langSpec.newCompilationUnit(component); - codes.add(cu); + // Generate the other components. + if (flowGraph instanceof DataFlowGraph) { + generateCodeFromDataFlowGraph(model, components, mainComponent, mainConstructor, codes, langSpec); + } else if (flowGraph instanceof ControlFlowGraph) { + generateCodeFromControlFlowGraph(model, (ControlFlowGraph) flowGraph, components, mainComponent, mainConstructor, codes, langSpec); } return codes; @@ -174,7 +117,17 @@ // a caller is before the callee for (Edge e: curNode.getInEdges()) { if (!(e.getSource() instanceof EntryPointObjectNode)) { - topologicalSort(allNodes, e.getSource(), visited, orderedList); + if (!(e instanceof DataFlowEdge) || ((PushPullAttribute)((DataFlowEdge) e).getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + topologicalSort(allNodes, e.getSource(), visited, orderedList); + } + } + } + if (curNode instanceof ResourceNode) { + for (Edge e: curNode.getOutEdges()) { + DataFlowEdge de = (DataFlowEdge) e; + if (((PushPullAttribute) de.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { + topologicalSort(allNodes, e.getDestination(), visited, orderedList); + } } } // For reference resources. @@ -207,6 +160,108 @@ orderedList.add(0, curNode); } + private static void generateCodeFromDataFlowGraph(DataTransferModel model, ArrayList components, + TypeDeclaration mainComponent, MethodDeclaration mainConstructor, ArrayList codes, ILanguageSpecific langSpec) { + // For each of other components. + for (Node componentNode: components) { + // Declare this resource. + ResourceNode resourceNode = (ResourceNode) componentNode; + String resourceName = langSpec.toComponentName(resourceNode.getIdentifierTemplate().getResourceName()); + TypeDeclaration component = langSpec.newTypeDeclaration(resourceName); + + // Declare the constructor and the fields to refer to other resources. + List depends = new ArrayList<>(); + MethodDeclaration constructor = declareConstructorAndFieldsToReferToResources(resourceNode, component, depends, langSpec); + + // Update the main component for this component. + updateMainComponent(model, mainComponent, mainConstructor, componentNode, depends, langSpec); + + IdentifierTemplate resId = resourceNode.getIdentifierTemplate(); + Type resStateType = resId.getResourceStateType(); + + // Declare the field in this resource to store the state. + if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { + FieldDeclaration stateField = langSpec.newFieldDeclaration(resStateType, fieldOfResourceState, langSpec.getFieldInitializer(resStateType, resId.getInitialValue())); + component.addField(stateField); + } + + // Declare the getter method in this resource to obtain the state. + MethodDeclaration getter = declareGetterMethod(resourceNode, component, resStateType, langSpec); + + // Declare the accessor method in the main component to call the getter method. + declareAccessorInMainComponent(mainComponent, resId, langSpec); + + // Declare the fields to refer to reference resources. + declareFieldsToReferenceResources(model, resourceNode, component, constructor, depends, langSpec); + + // Declare cache fields and update methods in this resource. + List updates = declareCacheFieldsAndUpdateMethods(resourceNode, component, langSpec); + + // Declare input methods in this component and the main component. + List inputs = declareInputMethodsInThisAndMainComponents(resourceNode, component, mainComponent, model, langSpec); + + if (constructor.getParameters() == null) { + component.removeMethod(constructor); + } + + // Add compilation unit for this component. + CompilationUnit cu = langSpec.newCompilationUnit(component); + codes.add(cu); + } + } + + private static void generateCodeFromControlFlowGraph(DataTransferModel model, ControlFlowGraph controlFlowGraph, ArrayList components, + TypeDeclaration mainComponent, MethodDeclaration mainConstructor, ArrayList codes, ILanguageSpecific langSpec) { + // For each of other components. + for (Node componentNode: components) { + // Declare this component. + String componentName = langSpec.toComponentName(((ObjectNode) componentNode).getName()); + TypeDeclaration component = langSpec.newTypeDeclaration(componentName); + + // Declare the constructor and the fields to refer to other resources (to the callee components). + List depends = new ArrayList<>(); + MethodDeclaration constructor = declareConstructorAndFieldsToCalleeComponents((ObjectNode) componentNode, component, depends, langSpec); + + // Update the main component for this component. + updateMainComponent(model, mainComponent, mainConstructor, componentNode, depends, langSpec); + + if (componentNode instanceof StatefulObjectNode) { + // For this resource. + ResourceNode resourceNode = ((StatefulObjectNode) componentNode).getResource(); + IdentifierTemplate resId = resourceNode.getIdentifierTemplate(); + Type resStateType = resId.getResourceStateType(); + + // Declare the field in this resource to store the state. + if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { + FieldDeclaration stateField = langSpec.newFieldDeclaration(resStateType, fieldOfResourceState, langSpec.getFieldInitializer(resStateType, resId.getInitialValue())); + component.addField(stateField); + } + + // Declare the getter method in this resource to obtain the state. + MethodDeclaration getter = declareGetterMethod(resourceNode, component, resStateType, langSpec); + + // Declare the accessor method in the main component to call the getter method. + declareAccessorInMainComponent(mainComponent, resId, langSpec); + + // Declare the fields to refer to reference resources. + declareFieldsToReferenceResources(model, resourceNode, component, constructor, depends, langSpec); + + // Declare cache fields and update methods in this resource. + List updates = declareCacheFieldsAndUpdateMethods(resourceNode, component, langSpec); + + // Declare input methods in this component and the main component. + List inputs = declareInputMethodsInThisAndMainComponents(resourceNode, component, mainComponent, model, langSpec); + } + if (constructor.getParameters() == null) { + component.removeMethod(constructor); + } + + // Add compilation unit for this component. + CompilationUnit cu = langSpec.newCompilationUnit(component); + codes.add(cu); + } + } + private static void updateMainComponent(DataTransferModel model, TypeDeclaration mainType, MethodDeclaration mainConstructor, Node componentNode, List depends, ILanguageSpecific langSpec) { // Declare the field to refer to each object in the main type. ResourceNode resNode = null;