diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 4e2ffbf..9750602 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -53,6 +53,7 @@ Map resourceConstructors = new HashMap<>(); List> getters = new ArrayList<>(); List> inputs = new ArrayList<>(); + List> updates = new ArrayList<>(); List> fields = new ArrayList<>(); List> constructorParams = new ArrayList<>(); List> constructorStatements = new ArrayList<>(); @@ -101,9 +102,23 @@ // Declare the getter methods in this resource to obtain the children resources. declareChildGetterMethod(resourceNode, component, langSpec); - - // Declare cache fields and update methods in this resource. - List updates = declareCacheFieldsAndUpdateMethods(resourceNode, component, langSpec); + } + + // Declare cache fields and update methods in this resource. + Map.Entry, Map.Entry, List>> updatesAndCacheFieldsAndInitStatements = declareCacheFieldsAndUpdateMethods(resourceNode, component, langSpec); + if (component == null) { + // updates were not added to any component because no component had been generated. + for (MethodDeclaration update: updatesAndCacheFieldsAndInitStatements.getKey()) { + updates.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), update)); + } + // Cache fields were not added to any component because no component had been generated. + for (FieldDeclaration field: updatesAndCacheFieldsAndInitStatements.getValue().getKey()) { + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), field)); + } + // Constructor statements were not added to any component because no component had been generated. + for (String statement: updatesAndCacheFieldsAndInitStatements.getValue().getValue()) { + constructorStatements.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), statement)); + } } // Declare the state field and reference fields in the parent component. @@ -145,6 +160,11 @@ resourceComponents.get(entry.getKey()).addMethod(entry.getValue()); } + // Add leaf update methods to the parent components. + for (Map.Entry entry: updates) { + resourceComponents.get(entry.getKey()).addMethod(entry.getValue()); + } + // Add leaf reference fields to the parent components. for (Map.Entry entry: fields) { resourceComponents.get(entry.getKey()).addField(entry.getValue()); @@ -505,10 +525,12 @@ } } - private List declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, TypeDeclaration component, ILanguageSpecific langSpec) { + private Map.Entry, Map.Entry, List>> declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, TypeDeclaration component, ILanguageSpecific langSpec) { // Declare cash fields and update methods in the component. String resComponentName = langSpec.toComponentName(resourceNode.getResourceName()); List updateMethods = new ArrayList<>(); + List cacheFields = new ArrayList<>(); + List constructorStatements = new ArrayList<>(); for (Edge chToRes: resourceNode.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataTransferChannel ch = ((ChannelNode) resToCh.getDestination()).getChannel(); @@ -537,8 +559,11 @@ } } MethodDeclaration update = langSpec.newMethodDeclaration(updateMethodName + srcResComponentName, false, null, vars); - component.addMethod(update); - updateMethods.add(update); + if (component != null) { + component.addMethod(update); + } else { + updateMethods.add(update); + } // Add a statement to update the state field if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { @@ -575,7 +600,11 @@ srcRes.getResourceStateType(), srcRes.getResourceName(), langSpec.getFieldInitializer(srcRes.getResourceStateType(), srcRes.getResourceHierarchy().getInitialValue())); - component.addField(cacheField); + if (component != null) { + component.addField(cacheField); + } else { + cacheFields.add(cacheField); + } } // Update the cache field. @@ -625,10 +654,15 @@ } String[] sideEffects = new String[] {""}; String outsideAccessor = outsideExp.toImplementation(sideEffects); - update.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. + String updateReference = langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter(); + update.addStatement(updateReference); // Update the reference field. // Update constructor. - MethodDeclaration constructor = getConstructor(component); - constructor.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // initialize the reference field. + if (component != null) { + MethodDeclaration constructor = getConstructor(component); + constructor.addStatement(updateReference); // Initialize the reference field. + } else { + constructorStatements.add(updateReference); + } } } } @@ -725,10 +759,15 @@ } String[] sideEffects = new String[] {""}; String outsideAccessor = outsideExp.toImplementation(sideEffects); - update.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. + String updateReference = langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter(); + update.addStatement(updateReference); // Update the reference field. // Update constructor. - MethodDeclaration constructor = getConstructor(component); - constructor.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // initialize the reference field. + if (component != null) { + MethodDeclaration constructor = getConstructor(component); + constructor.addStatement(updateReference); // Initialize the reference field. + } else { + constructorStatements.add(updateReference); + } } } } @@ -746,7 +785,7 @@ } } } - return updateMethods; + return new AbstractMap.SimpleEntry<>(updateMethods, new AbstractMap.SimpleEntry<>(cacheFields, constructorStatements)); } private Map.Entry, List> declareInputMethodsInThisAndMainComponents(ResourceNode resourceNode, TypeDeclaration component,