diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 1fd7a65..51abab3 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -60,7 +60,7 @@ Map resourceConstructors = new HashMap<>(); List> constructorParams = new ArrayList<>(); List> constructorStatements = new ArrayList<>(); - Map> updateStatements = new HashMap<>(); + Map>> updateStatements = new HashMap<>(); Map> descendantGetters = new HashMap<>(); // For each components (1st pass). @@ -131,14 +131,14 @@ } // Declare cache fields and update methods in this resource. - Map.Entry, Map>> initStatementsAndUpdateUpdates = declareCacheFieldsAndUpdateMethods(resourceNode, component, parentComponent, langSpec); + Map.Entry, Map>>> initStatementsAndUpdateUpdates = declareCacheFieldsAndUpdateMethods(resourceNode, component, parentComponent, langSpec); if (component == null) { // Constructor statements were not added to any component because no component had been generated. for (String statement: initStatementsAndUpdateUpdates.getKey()) { constructorStatements.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), statement)); } } - for (Map.Entry> entry: initStatementsAndUpdateUpdates.getValue().entrySet()) { + for (Map.Entry>> entry: initStatementsAndUpdateUpdates.getValue().entrySet()) { updateStatements.put(entry.getKey(), entry.getValue()); } @@ -156,14 +156,14 @@ } // Declare input methods in this component and the main component. - Map.Entry, Map>> initStatementsAndInputUpdates = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, model, langSpec); + Map.Entry, Map>>> initStatementsAndInputUpdates = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, model, langSpec); if (component == null) { // Constructor statements were not added to any component because no component had been generated. for (String statement: initStatementsAndInputUpdates.getKey()) { constructorStatements.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), statement)); } } - for (Map.Entry> entry: initStatementsAndInputUpdates.getValue().entrySet()) { + for (Map.Entry>> entry: initStatementsAndInputUpdates.getValue().entrySet()) { updateStatements.put(entry.getKey(), entry.getValue()); } } @@ -181,14 +181,10 @@ // Add update statements. for (MethodDeclaration method: updateStatements.keySet()) { Expression updateExp = updateStatements.get(method).getKey(); - ResourceHierarchy descendantRes = updateStatements.get(method).getValue(); - Set children; - do { - if (JavaCodeGenerator.generatesComponent(descendantRes)) break; - children = descendantRes.getChildren(); - } while (children != null && children.size() == 1 && (descendantRes = children.iterator().next()) != null); - TypeDeclaration descendanttComponent = resourceComponents.get(descendantRes); - addUpdateStatementWithConstructorInvocationToMethod(method, updateExp, descendantRes, descendanttComponent, langSpec); + ResourceHierarchy resource = updateStatements.get(method).getValue().getKey(); + ResourceHierarchy descendantRes = updateStatements.get(method).getValue().getValue(); + TypeDeclaration descendantComponent = resourceComponents.get(descendantRes); + addUpdateStatementWithConstructorInvocationToMethod(method, updateExp, resource, descendantRes, descendantComponent, langSpec); } } @@ -237,7 +233,7 @@ return params; } - private void addUpdateStatementWithConstructorInvocationToMethod(MethodDeclaration method, Expression exp, ResourceHierarchy descendantRes, TypeDeclaration descendantComponent, ILanguageSpecific langSpec) { + private void addUpdateStatementWithConstructorInvocationToMethod(MethodDeclaration method, Expression exp, ResourceHierarchy resource, ResourceHierarchy descendantRes, TypeDeclaration descendantComponent, ILanguageSpecific langSpec) { Type replacedJsonType = descendantRes.getResourceStateType(); String replacingClassName = getComponentName(descendantRes, langSpec); Type descendantType = new Type(replacingClassName, replacingClassName); @@ -290,7 +286,7 @@ } } // Replace the type of the state field. - Type fieldType = getImplStateType(descendantRes.getParent(), langSpec); + Type fieldType = getImplStateType(resource, langSpec); if (exp instanceof Term) { ((Term) exp).setType(fieldType); for (Map.Entry varEnt: ((Term) exp).getVariables().entrySet()) { @@ -809,11 +805,11 @@ } } - private Map.Entry, Map>> declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, ILanguageSpecific langSpec) { + private Map.Entry, Map>>> declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, ILanguageSpecific langSpec) { // Declare cash fields and update methods in the component. String resComponentName = getComponentName(resourceNode.getResourceHierarchy(), langSpec); List constructorStatements = new ArrayList<>(); - Map> updateStatements = new HashMap<>(); + Map>> updateStatements = new HashMap<>(); for (Edge chToRes: resourceNode.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataTransferChannel ch = ((ChannelNode) resToCh.getDestination()).getChannel(); @@ -918,12 +914,17 @@ // Replace Json constructor with a constructor of the child resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { - ResourceHierarchy childRes = outRes.getChildren().iterator().next(); - Type childStateType = childRes.getResourceStateType(); - if (DataConstraintModel.typeJson.isAncestorOf(childStateType)) { - updateStatements.put(update, new AbstractMap.SimpleEntry<>(updateExp, childRes)); - break; - } + ResourceHierarchy descendantRes = outRes; + Set children = descendantRes.getChildren(); + do { + descendantRes = children.iterator().next(); + if (generatesComponent(descendantRes)) { + updateStatements.put(update, new AbstractMap.SimpleEntry<>(updateExp, new AbstractMap.SimpleEntry<>(outRes, descendantRes))); + updateExp = null; + break; + } + children = descendantRes.getChildren(); + } while (children != null && children.size() == 1); } // Add statements to the update method. String[] sideEffects = new String[] {""}; @@ -1264,15 +1265,15 @@ return new AbstractMap.SimpleEntry<>(constructorStatements, updateStatements); } - private Map.Entry, Map>> declareInputMethodsInThisAndMainComponents(ResourceNode resourceNode, TypeDeclaration component, + private Map.Entry, Map>>> declareInputMethodsInThisAndMainComponents(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, TypeDeclaration mainComponent, DataTransferModel model, ILanguageSpecific langSpec) { // Declare input methods. String resName = resourceNode.getResourceName(); String resComponentName = langSpec.toComponentName(resName); List constructorStatements = new ArrayList<>(); - Map> inputStatements = new HashMap<>(); - for (Channel ch : model.getInputChannels()) { - for (ChannelMember out : ((DataTransferChannel) ch).getOutputChannelMembers()) { + Map>> inputStatements = new HashMap<>(); + for (Channel ch: model.getInputChannels()) { + for (ChannelMember out: ((DataTransferChannel) ch).getOutputChannelMembers()) { if (resourceNode.getInSideResources().contains(out.getResource())) { Expression message = out.getStateTransition().getMessageExpression(); MethodDeclaration input = null; @@ -1532,15 +1533,20 @@ // Add a statement to update the state field to the input method. try { Expression updateExp = ((DataTransferChannel) ch).deriveUpdateExpressionOf(out, getRefAccessor()).getKey(); - // Replace Json constructor with a constructor of the child resource. + // Replace Json constructor with a constructor of a descendant resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { - ResourceHierarchy childRes = outRes.getChildren().iterator().next(); - Type childStateType = childRes.getResourceStateType(); - if (DataConstraintModel.typeJson.isAncestorOf(childStateType)) { - inputStatements.put(input, new AbstractMap.SimpleEntry<>(updateExp, childRes)); - updateExp = null; - } + ResourceHierarchy descendantRes = outRes; + Set children = descendantRes.getChildren(); + do { + descendantRes = children.iterator().next(); + if (generatesComponent(descendantRes)) { + inputStatements.put(input, new AbstractMap.SimpleEntry<>(updateExp, new AbstractMap.SimpleEntry<>(outRes, descendantRes))); + updateExp = null; + break; + } + children = descendantRes.getChildren(); + } while (children != null && children.size() == 1); } // Add statements to the input method. if (updateExp != null) {