diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java index 85c9ad1..abb4dba 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -477,14 +477,11 @@ } // Declare a mediate getter method to return multiple values. String getterMethodName = "get"; - List compTypes = new ArrayList<>(); for (ResourceNode rn: resourcesToReturn) { getterMethodName += langSpec.toComponentName(rn.getIdentifierTemplate().getResourceName()); - IdentifierTemplate rId = rn.getIdentifierTemplate(); - compTypes.add(rId.getResourceStateType()); } getterMethodName += "Values"; - Type returnType = TypeInference.createNewTupleType(compTypes, DataConstraintModel.typeTuple); + Type returnType = createReturnType(resourcesToReturn); MethodDeclaration mediateGetter = langSpec.newMethodDeclaration(getterMethodName, returnType); component.addMethod(mediateGetter); @@ -544,7 +541,15 @@ Node dstNode = outEdge.getDestination(); MethodDeclaration calleeMethod = declareAndFillUpdateAndInputMethods(dstNode, outEdge, node, dataFlowInform, componentMap, langSpec); // Add a statement to call the destination method. - addInvocationInResourceUpdate(node, updateOrInput, calleeMethod, ((ObjectNode) dstNode).getName(), langSpec); + addInvocationInResourceUpdate(node, updateOrInput, calleeMethod, ((ObjectNode) dstNode).getName(), dataFlowInform.get(outEdge).get(PushPullValue.PULL), langSpec); + } + + if (resourcesToReturn != null && resourcesToReturn.size() > 0) { + // Set the return type and add a return statement. + Type returnType = createReturnType(resourcesToReturn); + updateOrInput.setReturnType(returnType); + String returnValue = createReturnValue(resourcesToReturn, node, returnType, langSpec); + updateOrInput.addStatement(langSpec.getReturnStatement(returnValue) + langSpec.getStatementDelimiter()); } return updateOrInput; } else if (node instanceof EntryPointObjectNode) { @@ -562,7 +567,7 @@ } } // Add a statement to call the destination method. - addInvocationInMediatorUpdate(input, calleeMethod, ((ObjectNode) dstNode).getName(), dataFlowInform, langSpec); + addInvocationInMediatorUpdate(input, calleeMethod, ((ObjectNode) dstNode).getName(), dataFlowInform.get(outEdge).get(PushPullValue.PULL), langSpec); } return input; } else { @@ -589,12 +594,49 @@ component.addMethod(updateOrInput); } // Add a statement to call the destination method. - addInvocationInMediatorUpdate(updateOrInput, calleeMethod, ((ObjectNode) dstNode).getName(), dataFlowInform, langSpec); + addInvocationInMediatorUpdate(updateOrInput, calleeMethod, ((ObjectNode) dstNode).getName(), dataFlowInform.get(outEdge).get(PushPullValue.PULL), langSpec); + } + if (resourcesToReturn != null && resourcesToReturn.size() > 0) { + // Set the return type and add a return statement. + Type returnType = createReturnType(resourcesToReturn); + updateOrInput.setReturnType(returnType); + String returnValue = createReturnValue(resourcesToReturn, node, returnType, langSpec); + updateOrInput.addStatement(langSpec.getReturnStatement(returnValue) + langSpec.getStatementDelimiter()); } return updateOrInput; } } + private static String createReturnValue(List resourcesToReturn, Node node, Type returnType, ILanguageSpecific langSpec) { + List params = new ArrayList<>(); + for (ResourceNode rn: resourcesToReturn) { + IdentifierTemplate rId = rn.getIdentifierTemplate(); + if (rId.getResourceName().equals(((ObjectNode) node).getName())) { + params.add(langSpec.getFieldAccessor(fieldOfResourceState)); + } else { + params.add(rId.getResourceName()); + } + } + if (params.size() == 1) { + return params.iterator().next(); + } else { + return langSpec.getConstructorInvocation(returnType.getImplementationTypeName(), params); + } + } + + private static Type createReturnType(List resourcesToReturn) { + if (resourcesToReturn.size() == 1) { + return resourcesToReturn.iterator().next().getIdentifierTemplate().getResourceStateType(); + } + List compTypes = new ArrayList<>(); + for (ResourceNode rn: resourcesToReturn) { + IdentifierTemplate rId = rn.getIdentifierTemplate(); + compTypes.add(rId.getResourceStateType()); + } + Type returnType = TypeInference.createNewTupleType(compTypes, DataConstraintModel.typeTuple); + return returnType; + } + private static MethodDeclaration getUpdateMethod(Edge inEdge, TypeDeclaration component, Map>> dataFlowInform, ILanguageSpecific langSpec) { List passedResoueces = dataFlowInform.get(inEdge).get(PushPullValue.PUSH); @@ -737,7 +779,7 @@ return input; } - private static void addInvocationInResourceUpdate(Node node, MethodDeclaration resourceUpdateMethod, MethodDeclaration calleeMethod, String dstNodeName, ILanguageSpecific langSpec) { + private static void addInvocationInResourceUpdate(Node node, MethodDeclaration resourceUpdateMethod, MethodDeclaration calleeMethod, String dstNodeName, List returnedResources, ILanguageSpecific langSpec) { List params = new ArrayList<>(); params.add(langSpec.getFieldAccessor(fieldOfResourceState)); if (calleeMethod.getParameters() != null) { @@ -767,25 +809,65 @@ // params.add(refVarName); // } // } - resourceUpdateMethod.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstNodeName), - calleeMethod.getName(), - params) + langSpec.getStatementDelimiter()); // this.dst.updateSrc(value, refParams); - + if (calleeMethod.getReturnType() == null || langSpec.isVoidType(calleeMethod.getReturnType())) { + resourceUpdateMethod.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstNodeName), + calleeMethod.getName(), + params) + langSpec.getStatementDelimiter()); // this.dst.updateSrc(value, refParams); + } else { + String targetVarName = null; + if (returnedResources.size() == 1) { + ResourceNode targetNode = returnedResources.get(0); + targetVarName = targetNode.getIdentifierTemplate().getResourceName(); + } else { + targetVarName = getMultipleResourcesVarName(returnedResources, langSpec); + } + resourceUpdateMethod.addStatement( + langSpec.getVariableDeclaration(calleeMethod.getReturnType().getInterfaceTypeName(), targetVarName) + + langSpec.getAssignment() + + langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstNodeName), + calleeMethod.getName(), + params) + langSpec.getStatementDelimiter()); // ResType res = this.dst.updateSrc(value, refParams); + } } - - private static void addInvocationInMediatorUpdate(MethodDeclaration resourceUpdateMethod, MethodDeclaration calleeMethod, String dstNodeName, Map>> dataFlowInform, ILanguageSpecific langSpec) { - Map> referredResources = new HashMap<>(); + private static void addInvocationInMediatorUpdate(MethodDeclaration resourceUpdateMethod, MethodDeclaration calleeMethod, String dstNodeName, List returnedResources, ILanguageSpecific langSpec) { List params = new ArrayList<>(); if (calleeMethod.getParameters() != null) { for (VariableDeclaration v: calleeMethod.getParameters()) { params.add(v.getName()); } } - resourceUpdateMethod.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstNodeName), - calleeMethod.getName(), - params) + langSpec.getStatementDelimiter()); // this.dst.updateSrc(value, refParams); - + if (calleeMethod.getReturnType() == null || langSpec.isVoidType(calleeMethod.getReturnType())) { + resourceUpdateMethod.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstNodeName), + calleeMethod.getName(), + params) + langSpec.getStatementDelimiter()); // this.dst.updateSrc(value, refParams); + } else { + String targetVarName = null; + if (returnedResources.size() == 1) { + ResourceNode targetNode = returnedResources.get(0); + targetVarName = targetNode.getIdentifierTemplate().getResourceName(); + } else { + targetVarName = getMultipleResourcesVarName(returnedResources, langSpec); + } + resourceUpdateMethod.addStatement( + langSpec.getVariableDeclaration(calleeMethod.getReturnType().getInterfaceTypeName(), targetVarName) + + langSpec.getAssignment() + + langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstNodeName), + calleeMethod.getName(), + params) + langSpec.getStatementDelimiter()); // ResType res = this.dst.updateSrc(value, refParams); + } + } + + private static String getMultipleResourcesVarName(List resources, ILanguageSpecific langSpec) { + String varName = null; + for (ResourceNode rn: resources) { + if (varName == null) { + varName = rn.getIdentifierTemplate().getResourceName(); + } else { + varName += langSpec.toComponentName(rn.getIdentifierTemplate().getResourceName()); + } + } + return varName; } private static void updateMainComponent(DataTransferModel model, TypeDeclaration mainType, MethodDeclaration mainConstructor, Node componentNode,