diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerationContext.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerationContext.java index a14604e..00496f4 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerationContext.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerationContext.java @@ -1,9 +1,11 @@ package generators; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; +import code.ast.CompilationUnit; import code.ast.TypeDeclaration; import models.algebra.Type; import models.dataConstraintModel.DataConstraintModel; @@ -11,8 +13,13 @@ import models.dataConstraintModel.MapType; import models.dataConstraintModel.ResourceHierarchy; import models.dataFlowModel.DataTransferChannel; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.IFlowGraph; public class CodeGenerationContext { + protected DataTransferModel model = null; + protected IFlowGraph flowGraph = null; + protected ArrayList AST; protected HashMap> componentNames = new HashMap<>(); protected Map resourceHierarchyToComponent; protected Map componentNameToType; @@ -27,6 +34,51 @@ this.langSpec = langSpec; this.platformSpec = platformSpec; } + + public void init(DataTransferModel model, IFlowGraph flowGraph) { + this.setModel(model); + this.setFlowGraph(flowGraph); + this.AST = new ArrayList<>(); + } + + public void setModel(DataTransferModel model) { + this.model = model; + } + + public DataTransferModel getModel() { + return this.model; + } + + public void setFlowGraph(IFlowGraph flowGraph) { + this.flowGraph = flowGraph; + } + + public IFlowGraph getFlowGraph() { + return this.flowGraph; + } + + public CompilationUnit createCompilationUnit(ResourceHierarchy resourceHierarchy, TypeDeclaration component) { + CompilationUnit cu = langSpec.newCompilationUnit(component); + if (!platformSpec.isMonolithic() && resourceHierarchy.getParent() == null) { + // For each root node, add platform specific imports. + ((RestApiSpecific) platformSpec).addPlatformSpecificImports(cu); + } + addCompilationUnit(cu); + resourceHierarchyToComponent.put(resourceHierarchy, component); + return cu; + } + + public void addCompilationUnit(CompilationUnit compilationUnit) { + this.AST.add(compilationUnit); + } + + public TypeDeclaration getComponent(ResourceHierarchy res) { + return resourceHierarchyToComponent.get(res); + } + + public ArrayList getAST() { + return this.AST; + } public String getComponentName(ResourceHierarchy res, ILanguageSpecific langSpec) { String name = res.getResourceName(); @@ -100,16 +152,7 @@ } } } - - public void putComponent(ResourceHierarchy res, TypeDeclaration component) { - resourceHierarchyToComponent.put(res, component); - } - - public TypeDeclaration getComponent(ResourceHierarchy res) { - return resourceHierarchyToComponent.get(res); - } - - + public String getOrPutUpdateMethodName(ResourceHierarchy srcRes, DataTransferChannel ch, ResourceHierarchy dstRes) { Map> dstResUpdatesMethods = updateMethods.getOrDefault(dstRes, new HashMap<>()); updateMethods.put(dstRes, dstResUpdatesMethods); diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java index fa3ad27..6a2a75d 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -30,11 +30,9 @@ import models.dataConstraintModel.PairType; import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; -import models.dataConstraintModel.Selector; import models.dataConstraintModel.TupleType; import models.dataFlowModel.ChannelNode; import models.dataFlowModel.DataFlowEdge; -import models.dataFlowModel.DataFlowGraph; import models.dataFlowModel.DataTransferChannel; import models.dataFlowModel.DataTransferModel; import models.dataFlowModel.IFlowGraph; @@ -109,7 +107,7 @@ * @return source codes */ public ArrayList generateCode(DataTransferModel model, IFlowGraph flowGraph) { - ArrayList codes = new ArrayList<>(); + this.generationContext.init(model, flowGraph); Map> dependedRootComponentGraph = null; Collection> components = null; @@ -127,12 +125,12 @@ } // Generate the other components. - generateCodeFromFlowGraph(model, flowGraph, components, codes, dependedRootComponentGraph); + generateCodeFromFlowGraph(components, dependedRootComponentGraph); - return codes; + return generationContext.getAST(); } - public abstract void generateCodeFromFlowGraph(DataTransferModel model, IFlowGraph flowGraph, Collection> components, ArrayList codes, Map> dependedRootComponentGraph); + public abstract void generateCodeFromFlowGraph(Collection> components, Map> dependedRootComponentGraph); private static Map> getDependedRootComponentGraph(DataTransferModel model) { Map> dependedComponentGraph = new HashMap<>(); @@ -451,9 +449,9 @@ mainComponent.addMethod(accessor); } - protected void declareFieldsToReferenceResources(DataTransferModel model, ResourceNode resourceNode, TypeDeclaration component, MethodDeclaration constructor, final List depends) { + protected void declareFieldsToReferenceResources(ResourceNode resourceNode, TypeDeclaration component, MethodDeclaration constructor, final List depends) { Set refs = new HashSet<>(); - for (Channel ch : model.getChannels()) { + for (Channel ch : generationContext.getModel().getChannels()) { DataTransferChannel c = (DataTransferChannel) ch; if (resourceNode.getOutSideResource(c) != null) { for (ResourcePath res: c.getReferenceResources()) { diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 36a2680..99045a0 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -58,8 +58,7 @@ super(platformSpec, langSpec); } - public void generateCodeFromFlowGraph(DataTransferModel model, IFlowGraph flowGraph, Collection> components, ArrayList codes, - Map> dependedRootComponentGraph) { + public void generateCodeFromFlowGraph(Collection> components, Map> dependedRootComponentGraph) { constructorParams = new HashMap<>(); Map resourceConstructors = new HashMap<>(); @@ -77,7 +76,7 @@ mainComponent = langSpec.newTypeDeclaration(getMainTypeName()); mainConstructor = mainComponent.createConstructor(); CompilationUnit mainCU = langSpec.newCompilationUnit(mainComponent); - codes.add(mainCU); + generationContext.addCompilationUnit(mainCU); } // For each components (1st pass). @@ -99,13 +98,7 @@ // For each root node, add component annotations. ((RestApiSpecific) platformSpec).addComponentAnnotations(component, resourceNode.getResourceName()); } - generationContext.putComponent(resourceHierarchy, component); - CompilationUnit cu = langSpec.newCompilationUnit(component); - if (!platformSpec.isMonolithic() && resourceHierarchy.getParent() == null) { - // For each root node, add platform specific imports. - ((RestApiSpecific) platformSpec).addPlatformSpecificImports(cu); - } - codes.add(cu); + CompilationUnit cu = generationContext.createCompilationUnit(resourceHierarchy, component); if (platformSpec.isMonolithic()) { // For monolithic applications (components are tightly coupled and must be built together). @@ -120,7 +113,7 @@ } // Declare the fields to refer to reference resources. - declareFieldsToReferenceResources(model, resourceNode, component, constructor, depends); + declareFieldsToReferenceResources(resourceNode, component, constructor, depends); if (constructor.getParameters() == null || constructor.getParameters().size() == 0) { component.removeMethod(constructor); @@ -142,13 +135,8 @@ declareAccessorInMainComponent(mainComponent, resourceNode, stateGetter); } } - if (component != null) { - if (generationContext.getComponent(resourceHierarchy) == null) { - generationContext.putComponent(resourceHierarchy, component); - } - // (#1) Declare the getter methods in this resource to obtain the descendant resources. (complementary to #2) - declareDescendantGetterMethods(resourceNode, component, descendantGetters); - } + // (#1) Declare the getter methods in this resource to obtain the descendant resources. (complementary to #2) + declareDescendantGetterMethods(resourceNode, component, descendantGetters); } } @@ -209,7 +197,7 @@ // Declare input methods in this component and the main component. if (!generatedResources.contains(resourceHierarchy)) { Map.Entry, Map>>> initStatementsAndInputUpdates - = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, rootComponent, model, priorMemberForInputChannel); + = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, rootComponent, priorMemberForInputChannel); if (component == null) { // Constructor statements were not added to any component because no component had been generated. for (String statement: initStatementsAndInputUpdates.getKey()) { @@ -227,7 +215,7 @@ } // Add constructor parameters to the ancestor components. - for (ResourceNode root: ((DataFlowGraph) flowGraph).getRootResourceNodes()) { + for (ResourceNode root: ((DataFlowGraph) generationContext.getFlowGraph()).getRootResourceNodes()) { addConstructorParameters(root.getResourceHierarchy(), resourceConstructors); } @@ -2071,12 +2059,12 @@ } private Map.Entry, Map>>> declareInputMethodsInThisAndMainComponents(ResourceNode resourceNode, TypeDeclaration component, - TypeDeclaration parentComponent, TypeDeclaration mainComponent, TypeDeclaration rootComponent, DataTransferModel model, Map priorMemberForInputChannel) { + TypeDeclaration parentComponent, TypeDeclaration mainComponent, TypeDeclaration rootComponent, Map priorMemberForInputChannel) { // Declare input methods. String resName = resourceNode.getResourceName(); List constructorStatements = new ArrayList<>(); Map>> inputStatements = new HashMap<>(); - for (Channel ch: model.getInputChannels()) { + for (Channel ch: generationContext.getModel().getInputChannels()) { for (ChannelMember cm : ((DataTransferChannel) ch).getOutputChannelMembers()) { if (!cm.isOutside()) { if (priorMemberForInputChannel.get(ch) == null) {