diff --git a/AlgebraicDataflowArchitectureModel/models/VotingSystem.model b/AlgebraicDataflowArchitectureModel/models/VotingSystem.model index ff425db..b0ce8f8 100644 --- a/AlgebraicDataflowArchitectureModel/models/VotingSystem.model +++ b/AlgebraicDataflowArchitectureModel/models/VotingSystem.model @@ -1,5 +1,5 @@ channel Signup { - out accounts(acDB:Map, signUp(aid:Str, name:Str)) = insert(acDB, aid, {"name": name, "vote": null}) + out accounts(acDB:Map, signUp(aid:Str, name:Str)) = insert(acDB, aid, {"name": name, "vote": ""}) } channel Cast(aid:Str) { diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java index adfd094..1ecb903 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java @@ -59,13 +59,13 @@ exist = true; } } + CodeGeneratorFromDataFlowGraph codeGenerator = new CodeGeneratorFromDataFlowGraph(); if (!exist) { - JavaCodeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. + codeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. } else { - JavaCodeGenerator.resetMainTypeName(); // use the default main type's name. + codeGenerator.resetMainTypeName(); // use the default main type's name. } -// editor.setCodes(JavaMethodBodyGenerator.doGenerate(graph, model, JavaCodeGenerator.doGenerate(graph, model))); - editor.setCodes(new CodeGeneratorFromDataFlowGraph().generateCode(model, graph, new StandaloneSpecific(), langSpec)); + editor.setCodes(codeGenerator.generateCode(model, graph, new StandaloneSpecific(), langSpec)); ModelExtension.recoverModel(model); for (CompilationUnit file : editor.getCodes()) { System.out.println(file); diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/JerseyPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/JerseyPrototypeGenerateAction.java index 1b64345..b9ab7e0 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/actions/JerseyPrototypeGenerateAction.java +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/JerseyPrototypeGenerateAction.java @@ -56,13 +56,14 @@ exist = true; } } + CodeGeneratorFromDataFlowGraph codeGenerator = new CodeGeneratorFromDataFlowGraph(); if (!exist) { - JerseyCodeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. + codeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. } else { - JerseyCodeGenerator.resetMainTypeName(); // use the default main type's name. + codeGenerator.resetMainTypeName(); // use the default main type's name. } // editor.setCodes(JerseyMethodBodyGenerator.doGenerate(graph, model, JerseyCodeGenerator.doGenerate(graph, model))); - editor.setCodes(new CodeGeneratorFromDataFlowGraph().generateCode(model, graph, new JerseySpecific(), langSpec)); + editor.setCodes(codeGenerator.generateCode(model, graph, new JerseySpecific(), langSpec)); ModelExtension.recoverModel(model); for (CompilationUnit file : editor.getCodes()) { System.out.println(file); diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java b/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java index 97ac135..a7a07d9 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java @@ -44,20 +44,20 @@ return strings; } - public void addFirstStatement(String code) { - if (code != null) { + public void addFirstStatement(String statement) { + if (statement != null) { this.addFirstStatement(new Statement() { @Override public String toString() { - return code; + return statement; } }); } } - public void addStatement(String code) { - if (code != null) { - this.addStatement(new PlainStatement(code)); + public void addStatement(String statement) { + if (statement != null) { + this.addStatement(new PlainStatement(statement)); } } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java index b541ce6..503768e 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java @@ -89,6 +89,13 @@ this.body = body; } + public void addStatement(Statement statement) { + if (body == null) { + body = new Block(); + } + body.addStatement(statement); + } + public void addStatement(String statement) { if (body == null) { body = new Block(); @@ -96,6 +103,13 @@ body.addStatement(statement); } + public void addFirstStatement(Statement statement) { + if (body == null) { + body = new Block(); + } + body.addFirstStatement(statement); + } + public void addFirstStatement(String statement) { if (body == null) { body = new Block(); diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/ParameterizedType.java b/AlgebraicDataflowArchitectureModel/src/code/ast/ParameterizedType.java index dbb16e2..ca7d269 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/ParameterizedType.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/ParameterizedType.java @@ -70,6 +70,23 @@ this.typeArguments = typeArguments; } + + /** + * Replace all type arguments and their descendant types that match the replacedType with the replacingType. + * @param replacedType the type to be replaced + * @param replacingType the type to replace with + */ + public void replaceSubTypes(Type replacedType, Type replacingType) { + for (int i = 0; i < typeArguments.size(); i++) { + Type typeArgment = typeArguments.get(i); + if (typeArgment.equals(replacedType)) { + typeArguments.set(i, replacingType); + } else if (typeArgment instanceof ParameterizedType) { + ((ParameterizedType) typeArgment).replaceSubTypes(replacedType, replacingType); + } + } + } + @Override public String toString() { if (typeArguments.isEmpty()) { diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclarationStatement.java b/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclarationStatement.java index c384ffa..bdc0ad4 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclarationStatement.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclarationStatement.java @@ -28,6 +28,10 @@ public List getFragments() { return fragments; } + + public void addFragment(VariableDeclaration fragment) { + this.fragments.add(fragment); + } public void setFragments(List fragments) { this.fragments = fragments; diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java index 4359e3b..e8208ea 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -10,12 +10,7 @@ import java.util.Set; import java.util.Stack; -import code.ast.Block; -import code.ast.CompilationUnit; -import code.ast.FieldDeclaration; -import code.ast.MethodDeclaration; -import code.ast.TypeDeclaration; -import code.ast.VariableDeclaration; +import code.ast.*; import models.Edge; import models.Node; import models.algebra.Constant; @@ -29,9 +24,13 @@ import models.dataConstraintModel.Channel; import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.ListType; +import models.dataConstraintModel.MapType; +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; @@ -59,97 +58,32 @@ public static final String presenter = "presenter"; public static final Type presenterType = new Type("SwingPresenter", new code.ast.SimpleType("SwingPresenter")); private static String mainTypeName = null; - private static HashMap> componentNames = new HashMap<>(); - protected Map resourceHierarchyToComponent; - protected Map>> updateMethods; + protected CodeGenerationContext generationContext = null; protected ILanguageSpecific langSpec = null; protected IPlatformSpecific platformSpec = null; - - public CodeGenerator() { - componentNames.clear(); - } - - public static String getMainTypeName() { + + public String getMainTypeName() { return mainTypeName; } - public static void setMainTypeName(String mainTypeName) { + public void setMainTypeName(String mainTypeName) { CodeGenerator.mainTypeName = mainTypeName; } - public static void resetMainTypeName() { + public void resetMainTypeName() { CodeGenerator.mainTypeName = null; } - public static String getComponentName(ResourceHierarchy res, ILanguageSpecific langSpec) { - String name = res.getResourceName(); - if (res.getNumParameters() > 0) { - if (name.length() > 3 && name.endsWith("ies")) { - name = name.substring(0, name.length() - 3) + "y"; - } else if (name.length() > 1 && name.endsWith("s")) { - name = name.substring(0, name.length() - 1); - } else { - name += "Element"; - } - } - String componentName = langSpec.toComponentName(name); - if (!generatesComponent(res)) return componentName; - // To avoid generating multiple components with the same name. - HashMap resToName = componentNames.get(componentName); - if (resToName == null) { - resToName = new HashMap<>(); - resToName.put(res, componentName); - componentNames.put(componentName, resToName); - return componentName; - } - if (resToName.get(res) == null) { - componentName += resToName.size(); - resToName.put(res, componentName); - return componentName; - } - return resToName.get(res); + public String getComponentName(ResourceHierarchy res, ILanguageSpecific langSpec) { + return generationContext.getComponentName(res, langSpec); } - public static Type getImplStateType(ResourceHierarchy res, ILanguageSpecific langSpec) { - Set children = res.getChildren(); - if (children == null || children.size() == 0) { - // leaf resource. - return res.getResourceStateType(); - } else { - ResourceHierarchy child = children.iterator().next(); - if (children.size() == 1 && child.getNumParameters() > 0) { - // map or list. - if (DataConstraintModel.typeList.isAncestorOf(res.getResourceStateType())) { - // list. - if (generatesComponent(child)) { - return langSpec.newListType(getComponentName(child, langSpec)); - } else { - return langSpec.newListType(getImplStateType(child, langSpec).getInterfaceTypeName()); - } - } else if (DataConstraintModel.typeMap.isAncestorOf(res.getResourceStateType())) { - // map. - if (generatesComponent(child)) { - return langSpec.newMapType(DataConstraintModel.typeString, getComponentName(child, langSpec)); - } else { - return langSpec.newMapType(DataConstraintModel.typeString, getImplStateType(child, langSpec).getInterfaceTypeName()); - } - } - return null; - } else { - // class - return res.getResourceStateType(); - } - } + public Type getImplStateType(ResourceHierarchy res, ILanguageSpecific langSpec) { + return generationContext.getImplStateType(res, langSpec); } - public static boolean generatesComponent(ResourceHierarchy res) { - if (res.getParent() == null) return true; - if (res.getChildren() == null || res.getChildren().size() == 0) return false; - if (res.getNumParameters() > 0 && res.getChildren().size() == 1 && res.getChildren().iterator().next().getNumParameters() > 0) return false; - if (res.getChildren().size() == 1 && res.getChildren().iterator().next().getNumParameters() > 0 - && (res.getChildren().iterator().next().getChildren() == null || res.getChildren().iterator().next().getChildren().size() == 0)) return false; - return true; -// return res.getParent() == null || !(res.getChildren() == null || res.getChildren().size() == 0); + public boolean generatesComponent(ResourceHierarchy res) { + return generationContext.generatesComponent(res); } /** @@ -163,8 +97,7 @@ public ArrayList generateCode(DataTransferModel model, DataFlowGraph flowGraph, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { this.langSpec = langSpec; this.platformSpec = platformSpec; - this.updateMethods = new HashMap<>(); - this.resourceHierarchyToComponent = new HashMap<>(); + this.generationContext = new CodeGenerationContext(langSpec, platformSpec); ArrayList codes = new ArrayList<>(); Map> dependedRootComponentGraph = null; @@ -313,7 +246,7 @@ String componentName = langSpec.toComponentName(nodeName); // Declare a field to refer each object. if (langSpec.declareField()) { - FieldDeclaration refField = langSpec.newFieldDeclaration(new Type(componentName, componentName), nodeName); + FieldDeclaration refField = langSpec.newFieldDeclaration(generationContext.getOrCreateComponentType(componentName), nodeName); mainType.addField(refField); } // Add a statement to instantiate each object to the main constructor. @@ -346,10 +279,10 @@ String dstNodeName = langSpec.toVariableName(dstComponentName); if (langSpec.declareField()) { // Declare a field to refer to another component. - component.addField(langSpec.newFieldDeclaration(new Type(dstComponentName, dstComponentName), dstNodeName)); + component.addField(langSpec.newFieldDeclaration(generationContext.getOrCreateComponentType(dstComponentName), dstNodeName)); } // Initialize the field to refer to another component. - constructor.addParameter(langSpec.newVariableDeclaration(new Type(dstComponentName, dstComponentName), dstNodeName)); + constructor.addParameter(langSpec.newVariableDeclaration(generationContext.getOrCreateComponentType(dstComponentName), dstNodeName)); constructor.getBody().addStatement(langSpec.getFieldAccessor(dstNodeName) + langSpec.getAssignment() + dstNodeName + langSpec.getStatementDelimiter()); } return dstRes; @@ -506,8 +439,8 @@ if (!refs.contains(res) && !depends.contains(res.getResourceHierarchy())) { refs.add(res); String refResName = langSpec.toComponentName(res.getLeafResourceName()); - component.addField(langSpec.newFieldDeclaration(new Type(refResName, refResName), res.getLeafResourceName())); - constructor.addParameter(langSpec.newVariableDeclaration(new Type(refResName, refResName), res.getLeafResourceName())); + component.addField(langSpec.newFieldDeclaration(generationContext.getOrCreateComponentType(refResName), res.getLeafResourceName())); + constructor.addParameter(langSpec.newVariableDeclaration(generationContext.getOrCreateComponentType(refResName), res.getLeafResourceName())); constructor.getBody().addStatement(langSpec.getFieldAccessor(res.getLeafResourceName()) + langSpec.getAssignment() + res.getLeafResourceName() + langSpec.getStatementDelimiter()); } } @@ -516,25 +449,7 @@ } protected String getUpdateMethodName(ResourceHierarchy srcRes, ResourceHierarchy dstRes, DataTransferChannel ch) { - Map> dstResUpdatesMethods = updateMethods.getOrDefault(dstRes, new HashMap<>()); - updateMethods.put(dstRes, dstResUpdatesMethods); - Map dstResFromSrcResUpdatesMethods = dstResUpdatesMethods.getOrDefault(srcRes, new HashMap<>()); - dstResUpdatesMethods.put(srcRes, dstResFromSrcResUpdatesMethods); - String updateMethodName = dstResFromSrcResUpdatesMethods.get(ch); - if (updateMethodName == null) { - String srcResComponentName = getComponentName(srcRes, langSpec); - String dstResComponentName = getComponentName(dstRes, langSpec); - if (generatesComponent(dstRes)) { - updateMethodName = updateMethodPrefix + from + srcResComponentName; - } else if (dstRes.getParent() != null) { - updateMethodName = updateMethodPrefix + dstResComponentName + from + srcResComponentName; - } - if (dstResFromSrcResUpdatesMethods.size() > 0) { - updateMethodName += dstResFromSrcResUpdatesMethods.size() + 1; // To avoid declaring the method multiply. - } - dstResFromSrcResUpdatesMethods.put(ch, updateMethodName); - } - return updateMethodName; + return generationContext.getOrPutUpdateMethodName(srcRes, ch, dstRes); } protected MethodDeclaration getConstructor(TypeDeclaration component) { @@ -744,109 +659,126 @@ return resPath.getResourceHierarchy().toResourcePath(params); } - protected void generatePullDataTransfer(MethodDeclaration methodBody, String fromResourceName, String fromResourcePath, Type fromResourceType, boolean doesAddFirst, - IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + protected void generatePullDataTransfer(MethodDeclaration method, Block block, String fromResourceName, String fromResourcePath, Type fromResourceType, + boolean doesAddFirst, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + if (block == null) { + block = method.getBody(); + } RestApiSpecific restApiSpec = (RestApiSpecific) platformSpec; String varName = new String(fromResourceName); - String respTypeName = fromResourceType.getInterfaceTypeName(); + Type respType = fromResourceType; String respImplTypeName = fromResourceType.getImplementationTypeName(); - String respConverter = ""; + String responseConverter = ""; if (DataConstraintModel.typeList.isAncestorOf(fromResourceType) && fromResourceType != DataConstraintModel.typeList) { - Type compType = TypeInference.getListComponentType(fromResourceType); - if (DataConstraintModel.typeTuple.isAncestorOf(compType)) { - varName += "_json"; - String mapTypeName = convertFromEntryToMapType(compType, langSpec); - respTypeName = langSpec.newListType(mapTypeName).getInterfaceTypeName(); - respConverter += langSpec.getVariableDeclaration(fromResourceType.getInterfaceTypeName(), fromResourceName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(fromResourceType.getImplementationTypeName(), null) + langSpec.getStatementDelimiter() + "\n"; - respConverter += langSpec.getForStatementForCollection("i", mapTypeName, varName) + "\n"; - respConverter += "\t" + langSpec.getMethodInvocation(fromResourceName, DataConstraintModel.append.getImplName(), List.of(getCodeForConversionFromMapToTuple(compType, "i", langSpec))) + langSpec.getStatementDelimiter() + "\n"; - respConverter += langSpec.getEndForStatement("i") ; - restApiSpec.addJsonException(methodBody); - } else if (DataConstraintModel.typeMap.isAncestorOf(compType)) { - // To do. + if (fromResourceType instanceof ListType) { + Type compType = ((ListType) fromResourceType).getElementType(); + if (compType != null && DataConstraintModel.typeTuple.isAncestorOf(compType)) { + varName += "_list"; + Type mapType = convertFromEntryToMapType(compType, langSpec); + respType = langSpec.newListType(mapType); + responseConverter += langSpec.newVariableDeclaration(fromResourceType, fromResourceName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(fromResourceType.getImplementationTypeName(), null) + langSpec.getStatementDelimiter() + "\n"; + EnhancedForStatement forStatement = langSpec.getForStatementForCollection(langSpec.newVariableDeclaration(mapType, "i"), varName); + Block forBlock = new Block(); + forBlock.addStatement(langSpec.getMethodInvocation(fromResourceName, DataConstraintModel.append.getImplName(), List.of(getCodeForConversionFromMapToTuple(compType, "i", langSpec))) + langSpec.getStatementDelimiter()); + forStatement.setBody(forBlock); + responseConverter += forStatement; + restApiSpec.addJsonException(method); + } else if (compType != null && DataConstraintModel.typeMap.isAncestorOf(compType)) { + // To do. + } } } else if (DataConstraintModel.typeTuple.isAncestorOf(fromResourceType)) { varName += "_json"; - respTypeName = convertFromEntryToMapType(fromResourceType, langSpec); - respConverter += langSpec.getVariableDeclaration(fromResourceType.getInterfaceTypeName(), fromResourceName) + langSpec.getAssignment() + getCodeForConversionFromMapToTuple(fromResourceType, varName, langSpec) + langSpec.getStatementDelimiter(); + respType = convertFromEntryToMapType(fromResourceType, langSpec); + responseConverter += langSpec.newVariableDeclaration(fromResourceType, fromResourceName) + langSpec.getAssignment() + getCodeForConversionFromMapToTuple(fromResourceType, varName, langSpec) + langSpec.getStatementDelimiter(); respImplTypeName = "HashMap"; } else if (DataConstraintModel.typePair.isAncestorOf(fromResourceType)) { varName += "_json"; - respTypeName = convertFromEntryToMapType(fromResourceType, langSpec); - respConverter += langSpec.getVariableDeclaration(fromResourceType.getInterfaceTypeName(), fromResourceName) + langSpec.getAssignment() + getCodeForConversionFromMapToPair(fromResourceType, varName, langSpec) + langSpec.getStatementDelimiter(); + respType = convertFromEntryToMapType(fromResourceType, langSpec); + responseConverter += langSpec.newVariableDeclaration(fromResourceType, fromResourceName) + langSpec.getAssignment() + getCodeForConversionFromMapToPair(fromResourceType, varName, langSpec) + langSpec.getStatementDelimiter(); respImplTypeName = "HashMap"; } else if (DataConstraintModel.typeMap.isAncestorOf(fromResourceType)) { varName += "_json"; - respTypeName = convertFromEntryToMapType(fromResourceType, langSpec); - respConverter += langSpec.getVariableDeclaration(fromResourceType.getInterfaceTypeName(), fromResourceName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(fromResourceType.getImplementationTypeName(), null) + langSpec.getStatementDelimiter() + "\n"; - respConverter += getCodeForConversionFromMapToMap(fromResourceType, varName, fromResourceName, langSpec); + respType = convertFromEntryToMapType(fromResourceType, langSpec); + responseConverter += langSpec.newVariableDeclaration(fromResourceType, fromResourceName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(fromResourceType.getImplementationTypeName(), null) + langSpec.getStatementDelimiter() + "\n"; + responseConverter += getCodeForConversionFromMapToMap(fromResourceType, varName, fromResourceName, langSpec); respImplTypeName = "HashMap"; } if (doesAddFirst) { - if (respConverter.length() > 0) { - methodBody.addFirstStatement(respConverter); + if (responseConverter.length() > 0) { + block.addFirstStatement(responseConverter); } - methodBody.addFirstStatement(langSpec.getVariableDeclaration(respTypeName, varName) + langSpec.getAssignment() + restApiSpec.getHttpMethodCallWithResponseStatement(restApiSpec.getBaseURL(), fromResourcePath, getterPrefix, respImplTypeName)); + block.addFirstStatement(langSpec.newVariableDeclaration(respType, varName) + langSpec.getAssignment() + restApiSpec.getHttpMethodCallWithResponseStatement(restApiSpec.getBaseURL(), fromResourcePath, getterPrefix, respImplTypeName)); } else { - methodBody.addStatement(langSpec.getVariableDeclaration(respTypeName, varName) + langSpec.getAssignment() + restApiSpec.getHttpMethodCallWithResponseStatement(restApiSpec.getBaseURL(), fromResourcePath, getterPrefix, respImplTypeName)); - if (respConverter.length() > 0) { - methodBody.addStatement(respConverter); + block.addStatement(langSpec.newVariableDeclaration(respType, varName) + langSpec.getAssignment() + restApiSpec.getHttpMethodCallWithResponseStatement(restApiSpec.getBaseURL(), fromResourcePath, getterPrefix, respImplTypeName)); + if (responseConverter.length() > 0) { + block.addStatement(responseConverter); } } } - protected String convertFromEntryToMapType(Type type, ILanguageSpecific langSpec) { - String mapTypeName = null; + protected Type convertFromEntryToMapType(Type type, ILanguageSpecific langSpec) { + Type mapType = null; if (DataConstraintModel.typePair.isAncestorOf(type)) { - Type compType = TypeInference.getPairComponentType(type); - String wrapperType = DataConstraintModel.getWrapperType(compType); - if (wrapperType != null) { - mapTypeName = langSpec.newMapType(DataConstraintModel.typeString, wrapperType).getInterfaceTypeName(); - } else { - mapTypeName = langSpec.newMapType(DataConstraintModel.typeString, compType.getInterfaceTypeName()).getInterfaceTypeName(); + if (type instanceof PairType) { + Type compType = ((PairType) type).getComponentType(); + String wrapperType = DataConstraintModel.getWrapperType(compType); + if (wrapperType != null) { + mapType = langSpec.newMapType(DataConstraintModel.typeString, wrapperType); + } else { + mapType = langSpec.newMapType(DataConstraintModel.typeString, compType); + } } } else if (DataConstraintModel.typeMap.isAncestorOf(type)) { - List compTypes = TypeInference.getMapComponentTypes(type); - String wrapperType = DataConstraintModel.getWrapperType(compTypes.get(1)); - if (wrapperType != null) { - mapTypeName = langSpec.newMapType(DataConstraintModel.typeString, wrapperType).getInterfaceTypeName(); - } else { - mapTypeName = langSpec.newMapType(DataConstraintModel.typeString, compTypes.get(1).getInterfaceTypeName()).getInterfaceTypeName(); + if (type instanceof MapType) { + Type keyType = ((MapType) type).getKeyType(); + Type valType = ((MapType) type).getValueType(); + String wrapperType = DataConstraintModel.getWrapperType(valType); + if (wrapperType != null) { + mapType = langSpec.newMapType(DataConstraintModel.typeString, wrapperType); + } else { + mapType = langSpec.newMapType(DataConstraintModel.typeString, valType.getInterfaceTypeName()); + } } } else { - mapTypeName = type.getInterfaceTypeName(); - mapTypeName = mapTypeName.replace(DataConstraintModel.typeTuple.getInterfaceTypeName(), DataConstraintModel.typeMap.getInterfaceTypeName()); - for (int idx = mapTypeName.indexOf("<", 0); idx >= 0; idx = mapTypeName.indexOf("<", idx + 1)) { // Java specific - int to = mapTypeName.indexOf(",", idx); // Java specific - if (to > idx) { - mapTypeName = mapTypeName.substring(0, idx + 1) + DataConstraintModel.typeString.getInterfaceTypeName() + mapTypeName.substring(to); // All elements except for the last one have the string type. + if (type instanceof TupleType) { + // Tuple (Map.Entry>> ==> Map>>) + List compTypes = ((TupleType) type).getComponentTypes(); + mapType = compTypes.get(compTypes.size() - 1); + for (int i = compTypes.size() - 2; i >= 0; i--) { + Type compType = compTypes.get(i); + mapType = langSpec.newMapType(DataConstraintModel.typeString, mapType); } } } - return mapTypeName; + return mapType; } protected String getCodeForConversionFromMapToTuple(Type tupleType, String mapVar, ILanguageSpecific langSpec) { String decoded = "$x"; - List elementsTypes = TypeInference.getTupleComponentTypes(tupleType); String elementBase = mapVar; - for (Type elmType: elementsTypes.subList(0, elementsTypes.size() - 1)) { - elementBase = langSpec.getFirstEntryFromMapExp(elementBase); // elementBase.entrySet().iterator().next() - if (elmType == DataConstraintModel.typeBoolean - || elmType == DataConstraintModel.typeInt - || elmType == DataConstraintModel.typeLong - || elmType == DataConstraintModel.typeFloat - || elmType == DataConstraintModel.typeDouble) { - String getKey = langSpec.getMethodInvocation(elementBase, DataConstraintModel.fst.getImplName()); // elementBase.getKey() - String elmVal = langSpec.getStringToValueExp(elmType.getImplementationTypeName(), getKey); // Integer.parseInt(elementBase.getKey()) - decoded = decoded.replace("$x", langSpec.getPairExp(elmVal, "$x")); // new AbstractMap.SimpleEntry<>(Integer.parseInt(elementBase.getKey()), $x) - } else if (elmType == DataConstraintModel.typeString) { - String getKey = langSpec.getMethodInvocation(elementBase, DataConstraintModel.fst.getImplName()); // elementBase.getKey() - decoded = decoded.replace("$x", langSpec.getPairExp(getKey, "$x")); // new AbstractMap.SimpleEntry<>(elementBase.getKey(), $x) - } else { - // To do. + if (tupleType instanceof TupleType) { + List componentsTypes = ((TupleType) tupleType).getComponentTypes(); + if (componentsTypes != null) { + for (Type elmType: componentsTypes.subList(0, componentsTypes.size() - 1)) { + elementBase = langSpec.getFirstEntryFromMapExp(elementBase); // elementBase.entrySet().iterator().next() + if (elmType == DataConstraintModel.typeBoolean + || elmType == DataConstraintModel.typeInt + || elmType == DataConstraintModel.typeLong + || elmType == DataConstraintModel.typeFloat + || elmType == DataConstraintModel.typeDouble) { + String getKey = langSpec.getMethodInvocation(elementBase, DataConstraintModel.fst.getImplName()); // elementBase.getKey() + String elmVal = langSpec.getStringToValueExp(elmType.getImplementationTypeName(), getKey); // Integer.parseInt(elementBase.getKey()) + decoded = decoded.replace("$x", langSpec.getPairExp(elmVal, "$x")); // new AbstractMap.SimpleEntry<>(Integer.parseInt(elementBase.getKey()), $x) + } else if (elmType == DataConstraintModel.typeString) { + String getKey = langSpec.getMethodInvocation(elementBase, DataConstraintModel.fst.getImplName()); // elementBase.getKey() + decoded = decoded.replace("$x", langSpec.getPairExp(getKey, "$x")); // new AbstractMap.SimpleEntry<>(elementBase.getKey(), $x) + } else { + // To do. + } + elementBase = langSpec.getMethodInvocation(elementBase, DataConstraintModel.snd.getImplName()); // elementBase.getValue() + } } - elementBase = langSpec.getMethodInvocation(elementBase, DataConstraintModel.snd.getImplName()); // elementBase.getValue() } decoded = decoded.replace("$x", elementBase); return decoded; @@ -860,22 +792,24 @@ } protected String getCodeForConversionFromMapToMap(Type mapType, String mapVal, String mapVar, ILanguageSpecific langSpec) { - List elementsTypes = TypeInference.getMapComponentTypes(mapType); - Type keyType = elementsTypes.get(0); -// Type valType = elementsTypes.get(1); String decoded = ""; - if (keyType == DataConstraintModel.typeBoolean - || keyType == DataConstraintModel.typeInt - || keyType == DataConstraintModel.typeLong - || keyType == DataConstraintModel.typeFloat - || keyType == DataConstraintModel.typeDouble) { - String keyVal = langSpec.getStringToValueExp(keyType.getImplementationTypeName(), "k"); - String getInvocation = langSpec.getMethodInvocation(mapVal, DataConstraintModel.lookup.getImplName(), List.of(keyVal)); - decoded += langSpec.getForStatementForMap("k", DataConstraintModel.typeString.getInterfaceTypeName(), mapVal) + "\n"; - decoded += "\t" + langSpec.getMethodInvocation(mapVar, DataConstraintModel.insert.getImplName(), List.of(keyVal, getInvocation)) + langSpec.getStatementDelimiter() + "\n"; - decoded += langSpec.getEndForStatement("k"); - } else if (keyType == DataConstraintModel.typeString) { - decoded += mapVar + langSpec.getAssignment() + mapVal + langSpec.getStatementDelimiter(); + if (mapType instanceof MapType) { + Type keyType = ((MapType) mapType).getKeyType(); + if (keyType == DataConstraintModel.typeBoolean + || keyType == DataConstraintModel.typeInt + || keyType == DataConstraintModel.typeLong + || keyType == DataConstraintModel.typeFloat + || keyType == DataConstraintModel.typeDouble) { + String keyVal = langSpec.getStringToValueExp(keyType.getImplementationTypeName(), "k"); + String getInvocation = langSpec.getMethodInvocation(mapVal, DataConstraintModel.lookup.getImplName(), List.of(keyVal)); + EnhancedForStatement forStatement = langSpec.getForStatementForMap("k", mapVal); + Block forBlock = new Block(); + forBlock.addStatement(langSpec.getMethodInvocation(mapVar, DataConstraintModel.insert.getImplName(), List.of(keyVal, getInvocation)) + langSpec.getStatementDelimiter()); + forStatement.setBody(forBlock); + decoded += forStatement; + } else if (keyType == DataConstraintModel.typeString) { + decoded += mapVar + langSpec.getAssignment() + mapVal + langSpec.getStatementDelimiter(); + } } return decoded; } @@ -1076,7 +1010,7 @@ if (getter == null && generatesComponent(curPath.getResourceHierarchy())) { // root resource String fieldName = langSpec.toVariableName(typeName); - getter = new Field(fieldName, new Type(typeName, typeName)); + getter = new Field(fieldName, generationContext.getOrCreateComponentType(typeName)); } else { if (generatesComponent(curPath.getResourceHierarchy())) { if (arity == 2) { @@ -1195,7 +1129,7 @@ if (getter == null && fromRes == null) { // root resource String fieldName = langSpec.toVariableName(typeName); - getter = new Field(fieldName, new Type(typeName, typeName)); + getter = new Field(fieldName, generationContext.getOrCreateComponentType(typeName)); } else { if (generatesComponent(curPath.getResourceHierarchy())) { if (arity == 2) { diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 5e406be..b6f023a 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -12,14 +12,7 @@ import java.util.Set; import java.util.Stack; -import code.ast.Annotation; -import code.ast.Block; -import code.ast.CodeUtil; -import code.ast.CompilationUnit; -import code.ast.FieldDeclaration; -import code.ast.MethodDeclaration; -import code.ast.TypeDeclaration; -import code.ast.VariableDeclaration; +import code.ast.*; import models.Edge; import models.Node; import models.algebra.Constant; @@ -40,6 +33,7 @@ import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.JsonAccessor; import models.dataConstraintModel.JsonTerm; +import models.dataConstraintModel.ListType; import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; import models.dataConstraintModel.Selector; @@ -88,7 +82,7 @@ // A component will be generated for this resource. String resourceName = getComponentName(resourceHierarchy, langSpec); Type resStateType = getImplStateType(resourceHierarchy, langSpec); - component = resourceHierarchyToComponent.get(resourceHierarchy); + component = generationContext.getComponent(resourceHierarchy); List depends = new ArrayList<>(); if (component == null) { // Add compilation unit for this component. @@ -97,7 +91,7 @@ // For each root node, add component annotations. ((RestApiSpecific) platformSpec).addComponentAnnotations(component, resourceNode.getResourceName()); } - resourceHierarchyToComponent.put(resourceHierarchy, component); + generationContext.putComponent(resourceHierarchy, component); CompilationUnit cu = langSpec.newCompilationUnit(component); if (!platformSpec.isMonolithic() && resourceHierarchy.getParent() == null) { // For each root node, add platform specific imports. @@ -141,8 +135,8 @@ } } if (component != null) { - if (resourceHierarchyToComponent.get(resourceHierarchy) == null) { - resourceHierarchyToComponent.put(resourceHierarchy, component); + 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); @@ -163,12 +157,12 @@ TypeDeclaration parentComponent = null; TypeDeclaration rootComponent = null; if (generatesComponent(resourceHierarchy)) { - component = resourceHierarchyToComponent.get(resourceHierarchy); + component = generationContext.getComponent(resourceHierarchy); } if (resourceHierarchy.getParent() != null) { - parentComponent = resourceHierarchyToComponent.get(resourceHierarchy.getParent()); + parentComponent = generationContext.getComponent(resourceHierarchy.getParent()); } - rootComponent = resourceHierarchyToComponent.get(resourceHierarchy.getRoot()); + rootComponent = generationContext.getComponent(resourceHierarchy.getRoot()); // Declare cache fields and update methods in this resource, and an update accessor method in the type of root resource. Map.Entry, Map>>> initStatementsAndUpdateUpdates @@ -238,7 +232,7 @@ Expression updateExp = updateStatements.get(method).getKey(); ResourceHierarchy resource = updateStatements.get(method).getValue().getKey(); ResourceHierarchy descendantRes = updateStatements.get(method).getValue().getValue(); - TypeDeclaration descendantComponent = resourceHierarchyToComponent.get(descendantRes); + TypeDeclaration descendantComponent = generationContext.getComponent(descendantRes); addUpdateStatementWithConstructorInvocationToMethod(method, updateExp, resource, descendantRes, descendantComponent); } } @@ -289,12 +283,12 @@ if (params.size() > 0) { MethodDeclaration constructor = resourceConstructors.get(resource); if (constructor == null) { - if (resourceHierarchyToComponent.get(resource) != null) { + if (generationContext.getComponent(resource) != null) { String resourceName = getComponentName(resource, langSpec); constructor = langSpec.newMethodDeclaration(resourceName, true, null, null); Block body = new Block(); constructor.setBody(body); - resourceHierarchyToComponent.get(resource).addMethod(constructor); + generationContext.getComponent(resource).addMethod(constructor); resourceConstructors.put(resource, constructor); } } @@ -313,13 +307,13 @@ constructor.addParameter(param); constructor.getBody().addStatement(langSpec.getFieldAccessor(langSpec.toVariableName(param.getName())) + langSpec.getAssignment() + langSpec.toVariableName(param.getName()) + langSpec.getStatementDelimiter()); boolean existsField = false; - for (FieldDeclaration field: resourceHierarchyToComponent.get(resource).getFields()) { + for (FieldDeclaration field: generationContext.getComponent(resource).getFields()) { if (field.getName().equals(param.getName())) { existsField = true; } } if (!existsField) { - resourceHierarchyToComponent.get(resource).addField(langSpec.newFieldDeclaration(param.getType(), param.getName())); + generationContext.getComponent(resource).addField(langSpec.newFieldDeclaration(param.getType(), param.getName())); } } } @@ -333,14 +327,16 @@ // Replace each json term in exp with the corresponding constructor invocation. Type replacedJsonType = descendantRes.getResourceStateType(); String replacingClassName = getComponentName(descendantRes, langSpec); - Type descendantType = new Type(replacingClassName, replacingClassName); + Type descendantType = generationContext.getOrCreateComponentType(replacingClassName); Map subTerms = ((Term) exp).getSubTerms(Term.class); Iterator> termEntItr = subTerms.entrySet().iterator(); while (termEntItr.hasNext()) { + // For each sub-term of exp Entry termEnt = termEntItr.next(); Term jsonTerm = termEnt.getValue(); if (jsonTerm.getType() != null) { if (jsonTerm.getType().equals(replacedJsonType)) { + // a json sub-term to replace if (jsonTerm instanceof JsonTerm || jsonTerm.getSymbol().equals(DataConstraintModel.addMember)) { MethodDeclaration childConstructor = getConstructor(descendantComponent); List params = new ArrayList<>(); @@ -367,17 +363,24 @@ } } } - ((Term) exp).replaceSubTerm(termEnt.getKey(), new Constant(langSpec.getConstructorInvocation(replacingClassName, params))); + ((Term) exp).replaceSubTerm(termEnt.getKey(), new Constant(langSpec.getConstructorInvocation(replacingClassName, params))); // dummy algebraic expression subTerms = ((Term) exp).getSubTerms(Term.class); termEntItr = subTerms.entrySet().iterator(); } else { jsonTerm.setType(descendantType); } } else { + // not any sub-term to replace, but its type should be rewritten Type oldType = jsonTerm.getType(); - Type newType = new Type(oldType.getTypeName(), - oldType.getImplementationTypeName().replace(replacedJsonType.getInterfaceTypeName(), replacingClassName), - oldType.getInterfaceTypeName().replace(replacedJsonType.getInterfaceTypeName(), replacingClassName)); + Type.ITypeImpl newImplementationType = oldType.getImplementationType(); + Type.ITypeImpl newInterfaceType = oldType.getInterfaceType(); + if (newImplementationType instanceof ParameterizedType) { + ((code.ast.ParameterizedType) newImplementationType).replaceSubTypes((code.ast.Type) replacedJsonType.getImplementationType(), (code.ast.Type) descendantType.getImplementationType()); + } + if (newInterfaceType instanceof ParameterizedType) { + ((code.ast.ParameterizedType) newInterfaceType).replaceSubTypes((code.ast.Type) replacedJsonType.getInterfaceType(), (code.ast.Type) descendantType.getInterfaceType()); + } + Type newType = new Type(oldType.getTypeName(), newImplementationType, newInterfaceType); for (Type parent: oldType.getParentTypes()) { newType.addParentType(parent); } @@ -539,7 +542,7 @@ Type childType = null; if (generatesComponent(c)) { // The child has a component. - childType = new Type(childTypeName, childTypeName); + childType = generationContext.getOrCreateComponentType(childTypeName); String fieldName = c.getResourceName(); FieldDeclaration stateField = langSpec.newFieldDeclaration(childType, fieldName, langSpec.getConstructorInvocation(childTypeName, new ArrayList<>())); component.addField(stateField); @@ -606,8 +609,8 @@ dstRes = dstRes.getParent(); } String dstResName = getComponentName(dstRes, langSpec); - FieldDeclaration refFieldForPush = langSpec.newFieldDeclaration(new Type(dstResName, dstResName), langSpec.toVariableName(dstResName)); - VariableDeclaration refVarForPush = langSpec.newVariableDeclaration(new Type(dstResName, dstResName), langSpec.toVariableName(dstResName)); + FieldDeclaration refFieldForPush = langSpec.newFieldDeclaration(generationContext.getOrCreateComponentType(dstResName), langSpec.toVariableName(dstResName)); + VariableDeclaration refVarForPush = langSpec.newVariableDeclaration(generationContext.getOrCreateComponentType(dstResName), langSpec.toVariableName(dstResName)); if (!platformSpec.isMonolithic() && (outsideOutputResource || (resourceNode.getOutSideResource(ch).getCommonPrefix(dstResPath) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { // Inter-service (for REST API) @@ -654,7 +657,7 @@ if (dstRes.getParent() != null) { // Reference to its root resource. String dstRootResName = getComponentName(dstRes.getRoot(), langSpec); - Type dstRootResType = new Type(dstRootResName, dstRootResName); + Type dstRootResType = generationContext.getOrCreateComponentType(dstRootResName); dstRootResName = langSpec.toVariableName(dstRootResName); FieldDeclaration refRootFieldForPush = langSpec.newFieldDeclaration(dstRootResType, dstRootResName); VariableDeclaration refRootVarForPush = langSpec.newVariableDeclaration(dstRootResType, dstRootResName); @@ -756,8 +759,8 @@ srcRes = srcRes.getParent(); } String srcResName = getComponentName(srcRes.getResourceHierarchy(), langSpec); - FieldDeclaration refFieldForPull = langSpec.newFieldDeclaration(new Type(srcResName, srcResName), langSpec.toVariableName(srcResName)); - VariableDeclaration refVarForPull = langSpec.newVariableDeclaration(new Type(srcResName, srcResName), langSpec.toVariableName(srcResName)); + FieldDeclaration refFieldForPull = langSpec.newFieldDeclaration(generationContext.getOrCreateComponentType(srcResName), langSpec.toVariableName(srcResName)); + VariableDeclaration refVarForPull = langSpec.newVariableDeclaration(generationContext.getOrCreateComponentType(srcResName), langSpec.toVariableName(srcResName)); if (!platformSpec.isMonolithic() && (outsideInputResource || (resourceNode.getInSideResource(ch).getCommonPrefix(srcRes) == null && platformSpec.isDifferentTreesAsDifferentServices()))) { // Inter-service (for REST API) @@ -805,7 +808,7 @@ if (srcRes.getParent() != null) { // Reference to its root resource. String srcRootResName = getComponentName(srcRes.getRoot().getResourceHierarchy(), langSpec); - Type srcRootResType = new Type(srcRootResName, srcRootResName); + Type srcRootResType = generationContext.getOrCreateComponentType(srcRootResName); srcRootResName = langSpec.toVariableName(srcRootResName); FieldDeclaration refRootFieldForPull = langSpec.newFieldDeclaration(srcRootResType, srcRootResName); VariableDeclaration refRootVarForPull = langSpec.newVariableDeclaration(srcRootResType, srcRootResName); @@ -920,7 +923,7 @@ childNode = ancestorNode; ancestorNode = ancestorNode.getParent(); } while (!generatesComponent(ancestorNode.getResourceHierarchy())); - TypeDeclaration ancestorComponent = resourceHierarchyToComponent.get(ancestorNode.getResourceHierarchy()); + TypeDeclaration ancestorComponent = generationContext.getComponent(ancestorNode.getResourceHierarchy()); List getterParams = new ArrayList<>(); int v = 1; while (ancestors.size() > 0) { @@ -1023,9 +1026,9 @@ String[] sideEffects = new String[] {""}; pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } - generatePullDataTransfer(stateGetter, srcResourceName, - srcResPath.getResourceHierarchy().toResourcePath(pathParams), srcResourceType, - true, platformSpec, langSpec); + generatePullDataTransfer(stateGetter, null, + srcResourceName, srcResPath.getResourceHierarchy().toResourcePath(pathParams), + srcResourceType, true, platformSpec, langSpec); bDeclareClientField = true; } } @@ -1058,9 +1061,9 @@ String[] sideEffects = new String[] {""}; pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } - generatePullDataTransfer(stateGetter, refResourceName, - refResPath.getResourceHierarchy().toResourcePath(pathParams), refResourceType, - true, platformSpec, langSpec); + generatePullDataTransfer(stateGetter, null, + refResourceName, refResPath.getResourceHierarchy().toResourcePath(pathParams), + refResourceType, true, platformSpec, langSpec); bDeclareClientField = true; } } @@ -1096,7 +1099,7 @@ Type srcResourceType = srcResPath.getResourceStateType(); String srcResName2 = langSpec.toVariableName(getComponentName(srcResPath.getResourceHierarchy(), langSpec)); String srcPath2 = srcResPath.toResourcePath().replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); - generatePullDataTransfer(stateGetter, srcResName2, srcPath2, srcResourceType, false, platformSpec, langSpec); + generatePullDataTransfer(stateGetter, null, srcResName2, srcPath2, srcResourceType, false, platformSpec, langSpec); bDeclareClientField = true; } } @@ -1123,11 +1126,11 @@ String srcResName2 = langSpec.toVariableName(getComponentName(src2.getResourceHierarchy(), langSpec)); if (platformSpec.isMonolithic()) { String srcGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(src2, resourceNode.getInSideResource(curChannel)).toImplementation(new String[] {""}); - stateGetter.addStatement(langSpec.getVariableDeclaration(srcResType2.getInterfaceTypeName(), srcResName2) + stateGetter.addStatement(langSpec.newVariableDeclaration(srcResType2, srcResName2) + langSpec.getAssignment() + srcGetter + langSpec.getStatementDelimiter()); } else { String srcPath2 = src2.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); - generatePullDataTransfer(stateGetter, srcResName2, srcPath2, srcResType2, false, platformSpec, langSpec); + generatePullDataTransfer(stateGetter, null, srcResName2, srcPath2, srcResType2, false, platformSpec, langSpec); bDeclareClientField = true; } } else { @@ -1140,11 +1143,11 @@ String srcResName2 = langSpec.toVariableName(getComponentName(src2.getResourceHierarchy(), langSpec)); if (platformSpec.isMonolithic()) { String dependingGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(src2, resourceNode.getInSideResource(curChannel)).toImplementation(new String[] {""}); - stateGetter.addStatement(langSpec.getVariableDeclaration(srcResType2.getInterfaceTypeName(), srcResName2) + stateGetter.addStatement(langSpec.newVariableDeclaration(srcResType2, srcResName2) + langSpec.getAssignment() + dependingGetter + langSpec.getStatementDelimiter()); } else { String srcPath2 = src2.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); - generatePullDataTransfer(stateGetter, srcResName2, srcPath2, srcResType2, false, platformSpec, langSpec); + generatePullDataTransfer(stateGetter, null, srcResName2, srcPath2, srcResType2, false, platformSpec, langSpec); bDeclareClientField = true; } } @@ -1193,10 +1196,10 @@ // enclosed by a for loop (for data collecting pull transfer) Expression selExp = curChannel.getSelectors().get(0).getExpression(); Type selType = null; - String forVarName = null; + Block forLoopBlock = stateGetter.getBody(); if (selExp instanceof Variable) { selType = ((Variable) selExp).getType(); - forVarName = ((Variable) selExp).getName(); + String forVarName = ((Variable) selExp).getName(); ChannelMember insideChMem = null; for (ChannelMember cm2 :curChannel.getInputChannelMembers()) { if (!cm2.isOutside()) { @@ -1236,10 +1239,16 @@ } if (selType.equals(DataConstraintModel.typeInt)) { // make a for loop (for a list) for data collecting. - stateGetter.addFirstStatement(langSpec.getForStatementForList(forVarName, parent)); + ForStatement forLoopToCollectData = langSpec.getForStatementForList(forVarName, parent); + forLoopBlock = new Block(); + forLoopToCollectData.setBody(forLoopBlock); + stateGetter.addStatement(forLoopToCollectData); } else if (selType.equals(DataConstraintModel.typeString)) { // make a for loop (for a map) for data collecting. - stateGetter.addFirstStatement(langSpec.getForStatementForMap(forVarName, DataConstraintModel.typeString.getInterfaceTypeName(), parent)); + EnhancedForStatement forLoopToCollectData = langSpec.getForStatementForMap(forVarName, parent); + forLoopBlock = new Block(); + forLoopToCollectData.setBody(forLoopBlock); + stateGetter.addStatement(forLoopToCollectData); } if (!platformSpec.isMonolithic() && insideResPath.getCommonPrefix(dstResPath) == null @@ -1248,18 +1257,16 @@ Type parentResType = insideResPath.getResourceStateType(); String parentResName = langSpec.toVariableName(getComponentName(insideResPath.getResourceHierarchy(), langSpec)); String parentResPath = insideResPath.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); - generatePullDataTransfer(stateGetter, parentResName, parentResPath, parentResType, true, platformSpec, langSpec); + generatePullDataTransfer(stateGetter, forLoopBlock, parentResName, parentResPath, parentResType, true, platformSpec, langSpec); bDeclareClientField = true; } } } // initialize the variables to hold side effects within the loop for (Variable var: varsForSideEffects) { - stateGetter.addFirstStatement(langSpec.getVariableDeclaration(var.getType().getInterfaceTypeName(), var.getName()) + stateGetter.addFirstStatement(langSpec.newVariableDeclaration(var.getType(), var.getName()) + langSpec.getAssignment() + langSpec.getConstructorInvocation(var.getType().getImplementationTypeName(), null) + langSpec.getStatementDelimiter()); } - // end of the loop - stateGetter.addStatement("}"); if (curChannel.getChildren() != null && curChannel.getChildren().size() > 0) { channelItrStack.push(chItr); chItr = curChannel.getChildren().iterator(); @@ -1309,7 +1316,7 @@ if (!descendants.contains(descendant.getResourceHierarchy())) { descendants.add(descendant.getResourceHierarchy()); String descendantCompName = getComponentName(descendant.getResourceHierarchy(), langSpec); - Type descendantType = new Type(descendantCompName, descendantCompName); + Type descendantType = generationContext.getOrCreateComponentType(descendantCompName); MethodDeclaration descendantGetter = null; if (params.size() == 0) { descendantGetter = langSpec.newMethodDeclaration(getterPrefix + descendantCompName, descendantType); @@ -1603,7 +1610,9 @@ } i++; } - update.addFirstStatement(langSpec.getIfStatement(conditions, updateStatement)); + Block ifBlock = new Block(); + ifBlock.addStatement(updateStatement); + update.addFirstStatement(langSpec.getIfStatement(conditions, ifBlock)); } } } @@ -1626,61 +1635,62 @@ Type paramType = jsonParam.getType(); String paramName = jsonParam.getName(); String paramTypeName = paramType.getInterfaceTypeName(); - String strTypeName = DataConstraintModel.typeString.getInterfaceTypeName(); String paramConverter = ""; if (DataConstraintModel.typeList.isAncestorOf(paramType) && paramType != DataConstraintModel.typeList) { - Type compType = TypeInference.getListComponentType(paramType); - if (DataConstraintModel.typeTuple.isAncestorOf(compType)) { - jsonParam.setType(DataConstraintModel.typeListStr); - jsonParam.setName(paramName + "_json"); - paramConverter += langSpec.getVariableDeclaration(paramTypeName, paramName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(paramType.getImplementationTypeName(), null) + langSpec.getStatementDelimiter() + "\n"; - paramConverter += langSpec.getForStatementForCollection("str", strTypeName, jsonParam.getName()) + "\n"; - String mapTypeName = convertFromEntryToMapType(compType, langSpec); - paramConverter += "\t" + ((RestApiSpecific) platformSpec).getConversionFromJsonString("str", "i", mapTypeName) + langSpec.getStatementDelimiter() + "\n"; - paramConverter += "\t" + langSpec.getMethodInvocation(paramName, DataConstraintModel.append.getImplName(), List.of(getCodeForConversionFromMapToTuple(compType, "i", langSpec))) + langSpec.getStatementDelimiter() + "\n"; - paramConverter += langSpec.getEndForStatement("str"); - ((RestApiSpecific) platformSpec).addJsonException(update); - } else if (DataConstraintModel.typePair.isAncestorOf(compType)) { - jsonParam.setType(DataConstraintModel.typeListStr); - jsonParam.setName(paramName + "_json"); - paramConverter += langSpec.getVariableDeclaration(paramTypeName, paramName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(paramType.getImplementationTypeName(), null) + langSpec.getStatementDelimiter() + "\n"; - paramConverter += langSpec.getForStatementForCollection("str", strTypeName, jsonParam.getName()) + "\n"; - String mapTypeName = convertFromEntryToMapType(compType, langSpec); - paramConverter += "\t" + ((RestApiSpecific) platformSpec).getConversionFromJsonString("str", "i", mapTypeName) + langSpec.getStatementDelimiter() + "\n"; - paramConverter += "\t" + langSpec.getMethodInvocation(paramName, DataConstraintModel.append.getImplName(), List.of(getCodeForConversionFromMapToPair(compType, "i", langSpec))) + langSpec.getStatementDelimiter() + "\n"; - paramConverter += langSpec.getEndForStatement("str"); - ((RestApiSpecific) platformSpec).addJsonException(update); - } else if (DataConstraintModel.typeMap.isAncestorOf(compType)) { - jsonParam.setType(DataConstraintModel.typeListStr); - // To do. + if (paramType instanceof ListType) { + Type compType = ((ListType) paramType).getElementType(); + if (compType != null && DataConstraintModel.typeTuple.isAncestorOf(compType)) { + jsonParam.setType(DataConstraintModel.typeListStr); + jsonParam.setName(paramName + "_json"); + paramConverter += langSpec.newVariableDeclaration(paramType, paramName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(paramType.getImplementationTypeName(), null) + langSpec.getStatementDelimiter() + "\n"; + paramConverter += langSpec.getForStatementForCollection(langSpec.newVariableDeclaration(DataConstraintModel.typeString, "str"), jsonParam.getName()) + "\n"; + Type mapType = convertFromEntryToMapType(compType, langSpec); + paramConverter += "\t" + ((RestApiSpecific) platformSpec).getConversionFromJsonString("str", "i", mapType.getInterfaceTypeName()) + langSpec.getStatementDelimiter() + "\n"; + paramConverter += "\t" + langSpec.getMethodInvocation(paramName, DataConstraintModel.append.getImplName(), List.of(getCodeForConversionFromMapToTuple(compType, "i", langSpec))) + langSpec.getStatementDelimiter() + "\n"; + paramConverter += langSpec.getEndForStatement("str"); + ((RestApiSpecific) platformSpec).addJsonException(update); + } else if (compType != null && DataConstraintModel.typePair.isAncestorOf(compType)) { + jsonParam.setType(DataConstraintModel.typeListStr); + jsonParam.setName(paramName + "_json"); + paramConverter += langSpec.newVariableDeclaration(paramType, paramName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(paramType.getImplementationTypeName(), null) + langSpec.getStatementDelimiter() + "\n"; + paramConverter += langSpec.getForStatementForCollection(langSpec.newVariableDeclaration(DataConstraintModel.typeString, "str"), jsonParam.getName()) + "\n"; + Type mapType = convertFromEntryToMapType(compType, langSpec); + paramConverter += "\t" + ((RestApiSpecific) platformSpec).getConversionFromJsonString("str", "i", mapType.getInterfaceTypeName()) + langSpec.getStatementDelimiter() + "\n"; + paramConverter += "\t" + langSpec.getMethodInvocation(paramName, DataConstraintModel.append.getImplName(), List.of(getCodeForConversionFromMapToPair(compType, "i", langSpec))) + langSpec.getStatementDelimiter() + "\n"; + paramConverter += langSpec.getEndForStatement("str"); + ((RestApiSpecific) platformSpec).addJsonException(update); + } else if (compType != null && DataConstraintModel.typeMap.isAncestorOf(compType)) { + jsonParam.setType(DataConstraintModel.typeListStr); + // To do. + } } } else if (DataConstraintModel.typeTuple.isAncestorOf(paramType)) { jsonParam.setType(DataConstraintModel.typeString); jsonParam.setName(paramName + "_json"); - paramConverter += langSpec.getVariableDeclaration(paramTypeName, paramName) + langSpec.getStatementDelimiter() + "\n"; + paramConverter += langSpec.newVariableDeclaration(paramType, paramName) + langSpec.getStatementDelimiter() + "\n"; paramConverter += langSpec.getOpeningScoreDelimiter() + "\n"; - String mapTypeName = convertFromEntryToMapType(paramType, langSpec); - paramConverter += "\t" + ((RestApiSpecific) platformSpec).getConversionFromJsonString(paramName + "_json", "i", mapTypeName) + langSpec.getStatementDelimiter() + "\n"; + Type mapType = convertFromEntryToMapType(paramType, langSpec); + paramConverter += "\t" + ((RestApiSpecific) platformSpec).getConversionFromJsonString(paramName + "_json", "i", mapType.getInterfaceTypeName()) + langSpec.getStatementDelimiter() + "\n"; paramConverter += "\t" + paramName + langSpec.getAssignment() + getCodeForConversionFromMapToTuple(paramType, "i", langSpec) + langSpec.getStatementDelimiter() + "\n"; paramConverter += langSpec.getClosingScoreDelimiter(); ((RestApiSpecific) platformSpec).addJsonException(update); } else if (DataConstraintModel.typePair.isAncestorOf(paramType)) { jsonParam.setType(DataConstraintModel.typeString); jsonParam.setName(paramName + "_json"); - paramConverter += langSpec.getVariableDeclaration(paramTypeName, paramName) + langSpec.getStatementDelimiter() + "\n"; + paramConverter += langSpec.newVariableDeclaration(paramType, paramName) + langSpec.getStatementDelimiter() + "\n"; paramConverter += langSpec.getOpeningScoreDelimiter() + "\n"; - String mapTypeName = convertFromEntryToMapType(paramType, langSpec); - paramConverter += "\t" + ((RestApiSpecific) platformSpec).getConversionFromJsonString(paramName + "_json", "i", mapTypeName) + langSpec.getStatementDelimiter() + "\n"; + Type mapType = convertFromEntryToMapType(paramType, langSpec); + paramConverter += "\t" + ((RestApiSpecific) platformSpec).getConversionFromJsonString(paramName + "_json", "i", mapType.getInterfaceTypeName()) + langSpec.getStatementDelimiter() + "\n"; paramConverter += "\t" + paramName + langSpec.getAssignment() + getCodeForConversionFromMapToPair(paramType, "i", langSpec) + langSpec.getStatementDelimiter() + "\n"; paramConverter += langSpec.getClosingScoreDelimiter(); ((RestApiSpecific) platformSpec).addJsonException(update); } else if (DataConstraintModel.typeMap.isAncestorOf(paramType)) { jsonParam.setType(DataConstraintModel.typeString); jsonParam.setName(paramName + "_json"); - paramConverter += langSpec.getVariableDeclaration(paramTypeName, paramName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(paramType.getImplementationTypeName(), null) + langSpec.getStatementDelimiter() + "\n"; + paramConverter += langSpec.newVariableDeclaration(paramType, paramName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(paramType.getImplementationTypeName(), null) + langSpec.getStatementDelimiter() + "\n"; paramConverter += langSpec.getOpeningScoreDelimiter() + "\n"; - String mapTypeName = convertFromEntryToMapType(paramType, langSpec); - paramConverter += "\t" + ((RestApiSpecific) platformSpec).getConversionFromJsonString(paramName + "_json", "i", mapTypeName) + langSpec.getStatementDelimiter() + "\n"; + Type mapType = convertFromEntryToMapType(paramType, langSpec); + paramConverter += "\t" + ((RestApiSpecific) platformSpec).getConversionFromJsonString(paramName + "_json", "i", mapType.getInterfaceTypeName()) + langSpec.getStatementDelimiter() + "\n"; paramConverter += "\t" + getCodeForConversionFromMapToMap(paramType, "i", paramName, langSpec) + "\n"; paramConverter += langSpec.getClosingScoreDelimiter(); ((RestApiSpecific) platformSpec).addJsonException(update); @@ -1831,8 +1841,7 @@ } if ((((PushPullAttribute) dOut.getAttribute()).getSelectedOption() == PushPullValue.PUSH && !outsideInputResource2) || outsideOutputResource2) { // PUSH transfer - boolean addForStatement = false; - String forVarName = null; + Block forLoopBlock = update.getBody(); if (descendantDstChannels.contains(chNode2)) { // For hierarchical channels (broadcasting push transfer). if (ch2.getSelectors() != null && ch2.getSelectors().size() > 0) { @@ -1840,7 +1849,7 @@ Type selType = null; if (selExp instanceof Variable) { selType = ((Variable) selExp).getType(); - forVarName = ((Variable) selExp).getName(); + String forVarName = ((Variable) selExp).getName(); ChannelMember insideChMem = null; for (ChannelMember cm :ch2.getInputChannelMembers()) { if (!cm.isOutside()) { @@ -1888,12 +1897,16 @@ } if (selType.equals(DataConstraintModel.typeInt)) { // make a for loop (for a list) for broadcasting. - update.addStatement(langSpec.getForStatementForList(forVarName, parent)); - addForStatement = true; + ForStatement forLoopToCollectData = langSpec.getForStatementForList(forVarName, parent); + forLoopBlock = new Block(); + forLoopToCollectData.setBody(forLoopBlock); + update.addStatement(forLoopToCollectData); } else if (selType.equals(DataConstraintModel.typeString)) { // make a for loop (for a map) for broadcasting. - update.addStatement(langSpec.getForStatementForMap(forVarName, DataConstraintModel.typeString.getInterfaceTypeName(), parent)); - addForStatement = true; + EnhancedForStatement forLoopToCollectData = langSpec.getForStatementForMap(forVarName, parent); + forLoopBlock = new Block(); + forLoopToCollectData.setBody(forLoopBlock); + update.addStatement(forLoopToCollectData); } if (!platformSpec.isMonolithic() && insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) == null @@ -1902,7 +1915,7 @@ Type parentResType = insideResPath.getResourceStateType(); String parentResName = langSpec.toVariableName(getComponentName(insideResPath.getResourceHierarchy(), langSpec)); String parentResPath = insideResPath.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); - generatePullDataTransfer(update, parentResName, parentResPath, parentResType, true, platformSpec, langSpec); + generatePullDataTransfer(update, forLoopBlock, parentResName, parentResPath, parentResType, true, platformSpec, langSpec); if (component != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(component)) { // Declare a client field to connect to the destination resource of push transfer. ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(component); @@ -1943,7 +1956,7 @@ for (Expression pathExp: ref.getPathParams()) { pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } - generatePullDataTransfer(update, refVarName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType, false, platformSpec, langSpec); + generatePullDataTransfer(update, forLoopBlock, refVarName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType, false, platformSpec, langSpec); if (component != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(component)) { // Declare a client field to connect to the destination resource of push transfer. ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(component); @@ -1955,7 +1968,7 @@ Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, srcRes); String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); - update.addStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + forLoopBlock.addStatement(sideEffects[0] + langSpec.newVariableDeclaration(ref.getResourceStateType(), refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); } } @@ -1965,9 +1978,8 @@ } } // Add an update method invocation. - hasUpdateMethodinvoked = addUpdateMethodInvocation(resourceNode, dstNode, update, refParams, - ch2, in, out1, inDegree, outsideOutputResource2, - forVarName, addForStatement, hasUpdateMethodinvoked); + hasUpdateMethodinvoked = addUpdateMethodInvocation(resourceNode, dstNode, update, forLoopBlock, refParams, + ch2, in, out1, inDegree, outsideOutputResource2, hasUpdateMethodinvoked); } } @@ -2338,7 +2350,7 @@ String[] sideEffects = new String[] {""}; String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); - mainInputAccessor.addFirstStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + mainInputAccessor.addFirstStatement(sideEffects[0] + langSpec.newVariableDeclaration(ref.getResourceStateType(), refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); } } @@ -2478,7 +2490,7 @@ for (Expression pathExp: ref.getPathParams()) { pathParams.add("\" + " + pathExp.toImplementation(sideEffects) + " + \""); } - generatePullDataTransfer(input, refResourceName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType, true, platformSpec, langSpec); + generatePullDataTransfer(input, null, refResourceName, ref.getResourceHierarchy().toResourcePath(pathParams), refResourceType, true, platformSpec, langSpec); if (component != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(component)) { // Declare a client field to connect to the destination resource of push transfer. ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(component); @@ -2490,7 +2502,7 @@ Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, dstRes); String refExp = refGetter.toImplementation(sideEffects); String refTypeName = refResourceType.getInterfaceTypeName(); - input.addFirstStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refResourceName) + input.addFirstStatement(sideEffects[0] + langSpec.newVariableDeclaration(refResourceType, refResourceName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); } } @@ -2616,8 +2628,7 @@ } if ((((PushPullAttribute) dOut.getAttribute()).getSelectedOption() == PushPullValue.PUSH && !outsideInputResource2) || outsideOutputResource2) { // PUSH transfer - boolean addForStatement = false; - String forVarName = null; + Block forLoopBlock = input.getBody(); if (descendantDstChannels.contains(chNode2)) { // For hierarchical channels (broadcasting push transfer). if (ch2.getSelectors() != null && ch2.getSelectors().size() > 0) { @@ -2625,7 +2636,7 @@ Type selType = null; if (selExp instanceof Variable) { selType = ((Variable) selExp).getType(); - forVarName = ((Variable) selExp).getName(); + String forVarName = ((Variable) selExp).getName(); ChannelMember insideChMem = null; for (ChannelMember cm :ch2.getInputChannelMembers()) { if (!cm.isOutside()) { @@ -2673,12 +2684,16 @@ } if (selType.equals(DataConstraintModel.typeInt)) { // make a for loop (for a list) for broadcasting. - input.addStatement(langSpec.getForStatementForList(forVarName, parent)); - addForStatement = true; + ForStatement forLoopToCollectData = langSpec.getForStatementForList(forVarName, parent); + forLoopBlock = new Block(); + forLoopToCollectData.setBody(forLoopBlock); + input.addStatement(forLoopToCollectData); } else if (selType.equals(DataConstraintModel.typeString)) { // make a for loop (for a map) for broadcasting. - input.addStatement(langSpec.getForStatementForMap(forVarName, DataConstraintModel.typeString.getInterfaceTypeName(), parent)); - addForStatement = true; + EnhancedForStatement forLoopToCollectData = langSpec.getForStatementForMap(forVarName, parent); + forLoopBlock = new Block(); + forLoopToCollectData.setBody(forLoopBlock); + input.addStatement(forLoopToCollectData); } if (!platformSpec.isMonolithic() && insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) == null @@ -2687,7 +2702,7 @@ Type parentResType = insideResPath.getResourceStateType(); String parentResName = langSpec.toVariableName(getComponentName(insideResPath.getResourceHierarchy(), langSpec)); String parentResPath = insideResPath.toResourcePath().replaceAll(":.*\\}","\\}").replaceAll("\\{", "\"+").replaceAll("\\}", "+\""); - generatePullDataTransfer(input, parentResName, parentResPath, parentResType, true, platformSpec, langSpec); + generatePullDataTransfer(input, forLoopBlock, parentResName, parentResPath, parentResType, true, platformSpec, langSpec); if (component != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(component)) { // Declare a client field to connect to the destination resource of push transfer. ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(component); @@ -2724,7 +2739,7 @@ String[] sideEffects = new String[] {""}; String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); - input.addStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); + forLoopBlock.addStatement(sideEffects[0] + langSpec.newVariableDeclaration(ref.getResourceStateType(), refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); } refParams.add(new AbstractMap.SimpleEntry<>(ref.getResourceStateType(), new AbstractMap.SimpleEntry<>(refVarName, @@ -2732,9 +2747,8 @@ } } // Add an update method invocation. - hasUpdateMethodinvoked = addUpdateMethodInvocation(resourceNode, dstNode, input, refParams, - ch2, in, out2, inDegree, outsideOutputResource2, - forVarName, addForStatement, hasUpdateMethodinvoked); + hasUpdateMethodinvoked = addUpdateMethodInvocation(resourceNode, dstNode, input, forLoopBlock, refParams, + ch2, in, out2, inDegree, outsideOutputResource2, hasUpdateMethodinvoked); } } @@ -2812,10 +2826,12 @@ } private boolean addUpdateMethodInvocation(ResourceNode srcNode, ResourceNode dstNode, - MethodDeclaration callerMethod, List>> refParams, - DataTransferChannel ch, ChannelMember in, ChannelMember out, int inDegree, boolean outsideOutputResource, - String forVarName, boolean addForStatement, boolean hasUpdateMethodinvoked) { - List>> pathParams = new ArrayList<>(); + MethodDeclaration callerMethod, Block callerBlock, List>> refParams, + DataTransferChannel ch, ChannelMember in, ChannelMember out, int inDegree, boolean outsideOutputResource, boolean hasUpdateMethodinvoked) { + if (callerBlock == null) { + callerBlock = callerMethod.getBody(); + } + List>> pathParams = new ArrayList<>(); if (platformSpec.isMonolithic()) { // Update fields to refer to outside resources. ResourcePath filledOutsideResourcePath = null; @@ -2847,7 +2863,7 @@ } String[] sideEffects = new String[] {""}; String outsideAccessor = outsideExp.toImplementation(sideEffects); - callerMethod.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. + callerBlock.addStatement(langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter()); // change the reference field. } } } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork @@ -2971,21 +2987,23 @@ TypeDeclaration srcComponent = null; TypeDeclaration srcParentComponent = null; if (generatesComponent(srcRes)) { - srcComponent = resourceHierarchyToComponent.get(srcRes); + srcComponent = generationContext.getComponent(srcRes); } else if (srcRes.getParent() != null) { - srcParentComponent = resourceHierarchyToComponent.get(srcRes.getParent()); + srcParentComponent = generationContext.getComponent(srcRes.getParent()); } if (!hasUpdateMethodinvoked) { // The first call to an update method in this method - callerMethod.addStatement(restApiSpec.getHttpMethodParamsConstructionStatement(srcRes.getResourceName(), params, true)); - String httpMethodCall = langSpec.getVariableDeclaration(DataConstraintModel.typeString.getInterfaceTypeName(), "result") + callerBlock.addStatement(restApiSpec.getHttpMethodParamsConstructionStatement(srcRes.getResourceName(), params, true)); + String httpMethodCall = langSpec.newVariableDeclaration(DataConstraintModel.typeString, "result") + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, srcResName, httpMethod); if (guardCondition == null) { // Non-conditional http method call. - callerMethod.addStatement(httpMethodCall); + callerBlock.addStatement(httpMethodCall); } else { // Conditional http method call by a guarded state transition. - callerMethod.addStatement(langSpec.getIfStatement(guardCondition, httpMethodCall)); + Block ifBlock = new Block(); + ifBlock.addStatement(httpMethodCall); + callerBlock.addStatement(langSpec.getIfStatement(guardCondition, ifBlock)); } if (srcComponent != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(srcComponent)) { // Declare a client field to connect to the destination resource of push transfer. @@ -3000,14 +3018,16 @@ hasUpdateMethodinvoked = true; } else { // After the second time of call to update methods in this method - callerMethod.addStatement(restApiSpec.getHttpMethodParamsConstructionStatement(srcRes.getResourceName(), params, false)); + callerBlock.addStatement(restApiSpec.getHttpMethodParamsConstructionStatement(srcRes.getResourceName(), params, false)); String httpMethodCall = "result" + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, srcResName, httpMethod); if (guardCondition == null) { // Non-conditional http method call. - callerMethod.addStatement(httpMethodCall); + callerBlock.addStatement(httpMethodCall); } else { // Conditional http method call by a guarded state transition. - callerMethod.addStatement(langSpec.getIfStatement(guardCondition, httpMethodCall)); + Block ifBlock = new Block(); + ifBlock.addStatement(httpMethodCall); + callerBlock.addStatement(langSpec.getIfStatement(guardCondition, ifBlock)); } if (srcComponent != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(srcComponent)) { // Declare a client field to connect to the destination resource of push transfer. @@ -3034,10 +3054,12 @@ + langSpec.getStatementDelimiter(); // this.dst.updateDstFromSrc(value, refParams); if (guardCondition == null) { // Non-conditional invocation. - callerMethod.addStatement(methodInvocation); + callerBlock.addStatement(methodInvocation); } else { // Conditional invocation by a guarded state transition. - callerMethod.addStatement(langSpec.getIfStatement(guardCondition, methodInvocation)); + Block ifBlock = new Block(); + ifBlock.addStatement(methodInvocation); + callerBlock.addStatement(langSpec.getIfStatement(guardCondition, ifBlock)); } } } else { @@ -3060,16 +3082,14 @@ } if (guardCondition == null) { // Non-conditional invocation. - callerMethod.addStatement(methodInvocation); + callerBlock.addStatement(methodInvocation); } else { // Conditional invocation by a guarded state transition. - callerMethod.addStatement(langSpec.getIfStatement(guardCondition, methodInvocation)); + Block ifBlock = new Block(); + ifBlock.addStatement(methodInvocation); + callerBlock.addStatement(langSpec.getIfStatement(guardCondition, ifBlock)); } } - if (addForStatement) { - // Close the for loop - callerMethod.addStatement(langSpec.getEndForStatement(forVarName)); - } return hasUpdateMethodinvoked; } @@ -3131,7 +3151,7 @@ String updateMethodName = getUpdateMethodName(srcRes, dstRes, ch); if (generatesComponent(dstRes)) { // A component is created for this resource. - TypeDeclaration dstComponent = resourceHierarchyToComponent.get(dstRes); + TypeDeclaration dstComponent = generationContext.getComponent(dstRes); for (MethodDeclaration method: dstComponent.getMethods()) { if (method.getName().equals(updateMethodName)) { update = method; @@ -3144,7 +3164,7 @@ } } else if (dstRes.getParent() != null) { // No component is created for this resource. - TypeDeclaration dstParentComponent = resourceHierarchyToComponent.get(dstRes.getParent()); + TypeDeclaration dstParentComponent = generationContext.getComponent(dstRes.getParent()); for (MethodDeclaration method: dstParentComponent.getMethods()) { if (method.getName().equals(updateMethodName)) { update = method; diff --git a/AlgebraicDataflowArchitectureModel/src/generators/ILanguageSpecific.java b/AlgebraicDataflowArchitectureModel/src/generators/ILanguageSpecific.java index eebaa15..0952bb4 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/ILanguageSpecific.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/ILanguageSpecific.java @@ -1,15 +1,14 @@ package generators; -import java.util.ArrayList; import java.util.List; import code.ast.*; -import models.algebra.Expression; import models.algebra.Term; import models.algebra.Type; -import models.algebra.Variable; import models.dataConstraintModel.JsonType; -import models.dataFlowModel.DataTransferChannel.IResourceStateAccessor; +import models.dataConstraintModel.ListType; +import models.dataConstraintModel.MapType; +import models.dataConstraintModel.TupleType; public interface ILanguageSpecific { CompilationUnit newCompilationUnit(TypeDeclaration component); @@ -19,15 +18,16 @@ MethodDeclaration newMethodDeclaration(String methodName, boolean isConstructor, Type returnType, List parameters); FieldDeclaration newFieldDeclaration(Type fieldType, String fieldName); FieldDeclaration newFieldDeclaration(Type fieldType, String fieldName, String fieldInitializer); - Type newListType(String compTypeName); - Type newListType(String compTypeName, Type parentListType); - Type newMapType(Type keyType, String compTypeName); - Type newMapType(Type keyType, String compTypeName, Type parentMapType); - Type newTupleType(List compTypes); - Type newTupleType(List componentTypes, Type parentTupleType); + ListType newListType(Type compType); + ListType newListType(Type compType, Type parentListType); + MapType newMapType(Type keyType, String compTypeName); + MapType newMapType(Type keyType, String compTypeName, Type parentMapType); + MapType newMapType(Type keyType, Type valueType); + MapType newMapType(Type keyType, Type valueType, Type parentMapType); + TupleType newTupleType(List compTypes); + TupleType newTupleType(List componentTypes, Type parentTupleType); JsonType newJsonType(); JsonType newJsonType(Type parentJsonType); - VariableDeclaration getVariableDeclaration(Type typeName, String varName); boolean declareField(); String getSelfExp(); String getFieldAccessor(String fieldName); @@ -38,9 +38,9 @@ String getConstructorInvocation(String componentName, List parameters); ReturnStatement getReturnStatement(String returnValue); IfStatement getIfStatement(Term condition, Statement block); - ForStatement getForStatementForList(Variable varName, Expression list); + ForStatement getForStatementForList(String varName, String list); EnhancedForStatement getForStatementForCollection(VariableDeclaration varDeclaration, String collection); - EnhancedForStatement getForStatementForMap(VariableDeclaration varDeclaration, String map); + EnhancedForStatement getForStatementForMap(String varName, String map); String getEndForStatement(); String getEndForStatement(String varName); String toComponentName(String name); @@ -59,4 +59,5 @@ String getDecomposedTuple(String tupleExp, VariableDeclaration tupleVar, List vars); boolean isValueType(Type type); boolean isVoidType(Type type); + Type getWrapperType(Type type); } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaSpecific.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaSpecific.java index 900d9b8..8effbd1 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaSpecific.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaSpecific.java @@ -5,17 +5,23 @@ import java.util.List; import code.ast.*; +import code.ast.Expression; import code.ast.Variable; import models.algebra.*; -import models.algebra.Expression; import models.algebra.Type; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.JsonType; +import models.dataConstraintModel.ListType; +import models.dataConstraintModel.MapType; +import models.dataConstraintModel.TupleType; public class JavaSpecific implements ILanguageSpecific { public static final Type typeVoid = new Type("Void", new code.ast.SimpleType("void")); public static final code.ast.SimpleType typeObject = new code.ast.SimpleType("Object"); + public static final code.ast.SimpleType typeBoolean = new code.ast.SimpleType("Boolean"); public static final code.ast.SimpleType typeInteger = new code.ast.SimpleType("Integer"); + public static final code.ast.SimpleType typeLong = new code.ast.SimpleType("Long"); + public static final code.ast.SimpleType typeFloat = new code.ast.SimpleType("Float"); public static final code.ast.SimpleType typeDouble = new code.ast.SimpleType("Double"); public static final code.ast.SimpleType typeString = new code.ast.SimpleType("String"); public static final code.ast.SimpleType typeList = new code.ast.SimpleType("List"); @@ -70,37 +76,51 @@ } @Override - public Type newListType(String compTypeName) { - return newListType(compTypeName, DataConstraintModel.typeList); + public ListType newListType(Type compType) { + return newListType(compType, DataConstraintModel.typeList); } @Override - public Type newListType(String compTypeName, Type parentListType) { + public ListType newListType(Type compType, Type parentListType) { List typeArgs = new ArrayList<>(); - typeArgs.add(new code.ast.SimpleType(compTypeName)); - return new Type("List", new code.ast.ParameterizedType(typeArrayList), new code.ast.ParameterizedType(JavaSpecific.typeList, typeArgs), parentListType); + typeArgs.add((code.ast.Type) compType.getInterfaceType()); + return new ListType("List", new code.ast.ParameterizedType(typeArrayList), new code.ast.ParameterizedType(JavaSpecific.typeList, typeArgs), compType, parentListType); } @Override - public Type newMapType(Type keyType, String valueTypeName) { + public MapType newMapType(Type keyType, String valueTypeName) { return newMapType(keyType, valueTypeName, DataConstraintModel.typeMap); } @Override - public Type newMapType(Type keyType, String valueTypeName, Type parentMapType) { + public MapType newMapType(Type keyType, String valueTypeName, Type parentMapType) { + Type valueType = new Type(valueTypeName, new code.ast.SimpleType(valueTypeName)); List typeArgs = new ArrayList<>(); typeArgs.add((code.ast.Type) keyType.getInterfaceType()); - typeArgs.add(new code.ast.SimpleType(valueTypeName)); - return new Type("Map", new code.ast.ParameterizedType(typeHashMap), new code.ast.ParameterizedType(JavaSpecific.typeMap, typeArgs), parentMapType); + typeArgs.add((code.ast.Type) valueType.getInterfaceType()); + return new MapType("Map", new code.ast.ParameterizedType(typeHashMap), new code.ast.ParameterizedType(JavaSpecific.typeMap, typeArgs), keyType, valueType, parentMapType); + } + + @Override + public MapType newMapType(Type keyType, Type valueType) { + return newMapType(keyType, valueType, DataConstraintModel.typeMap); + } + + @Override + public MapType newMapType(Type keyType, Type valueType, Type parentMapType) { + List typeArgs = new ArrayList<>(); + typeArgs.add((code.ast.Type) keyType.getInterfaceType()); + typeArgs.add((code.ast.Type) valueType.getInterfaceType()); + return new MapType("Map", new code.ast.ParameterizedType(typeHashMap), new code.ast.ParameterizedType(JavaSpecific.typeMap, typeArgs), keyType, valueType, parentMapType); } @Override - public Type newTupleType(List componentTypes) { + public TupleType newTupleType(List componentTypes) { return newTupleType(componentTypes, DataConstraintModel.typeTuple); } @Override - public Type newTupleType(List componentTypes, Type parentTupleType) { + public TupleType newTupleType(List componentTypes, Type parentTupleType) { code.ast.Type implType = new code.ast.SimpleType("AbstractMap.SimpleEntry"); code.ast.Type interfaceType = typeMapEntry; if (componentTypes.size() >= 2) { @@ -112,8 +132,7 @@ interfaceType = new code.ast.ParameterizedType(typeMapEntry, typeArgs); } } - Type newTupleType = new Type("Tuple", implType, interfaceType, parentTupleType); - return newTupleType; + return new TupleType("Tuple", implType, interfaceType, componentTypes, parentTupleType); } @Override @@ -129,11 +148,6 @@ } @Override - public VariableDeclaration getVariableDeclaration(Type typeName, String varName) { - return new VariableDeclaration(typeName, varName); - } - - @Override public boolean declareField() { return true; } @@ -226,17 +240,20 @@ } @Override - public ForStatement getForStatementForList(models.algebra.Variable varName, Expression list) { + public ForStatement getForStatementForList(String varName, String list) { + VariableDeclaration varDec = new VariableDeclaration(DataConstraintModel.typeInt, varName, new code.ast.Constant("0")); + VariableDeclarationStatement varDecStmt = new VariableDeclarationStatement(); + varDecStmt.addFragment(varDec); ForStatement forStatement = new ForStatement(); - forStatement.getInitializers().add(new PlainStatement("int " + varName.getName() + " = 0")); + forStatement.getInitializers().add(varDecStmt); InfixExpression condition = new InfixExpression( new Symbol("<", 2, Symbol.Type.INFIX), - new code.ast.Variable(varName.getName()), - new code.ast.Variable(list.toString() + ".size()") + new code.ast.Variable(varName), + new code.ast.Variable(list + ".size()") ); forStatement.setExpression(condition); PostfixExpression increment = new PostfixExpression( - new code.ast.Variable(varName.getName()), + new code.ast.Variable(varName), PostfixExpression.Operator.INCREMENT ); forStatement.setUpdaters(Arrays.asList(new ExpressionStatement(increment))); @@ -254,7 +271,8 @@ } @Override - public EnhancedForStatement getForStatementForMap(VariableDeclaration varDeclaration, String map) { + public EnhancedForStatement getForStatementForMap(String varName, String map) { + VariableDeclaration varDeclaration = new VariableDeclaration(DataConstraintModel.typeString, varName); EnhancedForStatement enhancedForStatement = new EnhancedForStatement(); enhancedForStatement.setParameter(varDeclaration); @@ -374,11 +392,11 @@ @Override public String getDecomposedTuple(String tupleExp, VariableDeclaration tupleVar, List vars) { String statements = ""; - statements += getVariableDeclaration(tupleVar.getType(), tupleVar.getName()) + statements += newVariableDeclaration(tupleVar.getType(), tupleVar.getName()) + getAssignment() + tupleExp + getStatementDelimiter(); for (int i = 0; i < vars.size(); i++) { VariableDeclaration var = vars.get(i); - statements += "\n" + getVariableDeclaration(var.getType(), var.getName()) + statements += "\n" + newVariableDeclaration(var.getType(), var.getName()) + getAssignment() + getTupleGet(tupleVar.getName(), i, vars.size()) + getStatementDelimiter(); @@ -406,6 +424,22 @@ } return false; } + + @Override + public Type getWrapperType(Type type) { + if (type == DataConstraintModel.typeInt) { + return new Type("Integer", typeInteger); + } else if (type == DataConstraintModel.typeLong) { + return new Type("Long", typeLong); + } else if (type == DataConstraintModel.typeFloat) { + return new Type("Float", typeFloat); + } else if (type == DataConstraintModel.typeDouble) { + return new Type("Double", typeDouble); + } else if (type == DataConstraintModel.typeBoolean) { + return new Type("Boolean", typeBoolean); + } + return type; + } private String getImplementationTypeName(Type type) { if (type == null) diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseySpecific.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseySpecific.java index 33a9686..04cfad8 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseySpecific.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseySpecific.java @@ -12,6 +12,7 @@ import code.ast.VariableDeclaration; import models.algebra.Type; import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.ListType; public class JerseySpecific extends RestApiSpecific { public static final Type typeClient = new Type("Client", new code.ast.SimpleType("Client")); @@ -108,20 +109,22 @@ String paramName = param.getValue().getKey(); String value = param.getValue().getValue(); if (DataConstraintModel.typeList.isAncestorOf(paramType)) { - Type compType = TypeInference.getListComponentType(paramType); - String wrapperType = DataConstraintModel.getWrapperType(compType); - if (wrapperType == null) { - statements += langSpec.getForStatementForCollection("i", compType.getInterfaceTypeName(), value) + "\n"; - } else { - statements += langSpec.getForStatementForCollection("i", wrapperType, value) + "\n"; + if (paramType instanceof ListType) { + Type compType = ((ListType) paramType).getElementType(); + Type wrapperType = langSpec.getWrapperType(compType); + if (!langSpec.isValueType(compType)) { + statements += langSpec.getForStatementForCollection(langSpec.newVariableDeclaration(compType, "i"), value) + "\n"; + } else { + statements += langSpec.getForStatementForCollection(langSpec.newVariableDeclaration(wrapperType, "i"), value) + "\n"; + } + if (DataConstraintModel.typeTuple.isAncestorOf(compType) || DataConstraintModel.typePair.isAncestorOf(paramType) || DataConstraintModel.typeList.isAncestorOf(compType) || DataConstraintModel.typeMap.isAncestorOf(paramType)) { + statements += "\tform.param(\"" + paramName + "\", " + langSpec.getConstructorInvocation("ObjectMapper", null) + ".writeValueAsString(i))" + langSpec.getStatementDelimiter() + "\n"; // typeTuple: {"1.0":2.0}, typePair: {"left": 1.0, "right":2.0} + } else { + statements += "\tform.param(\"" + paramName + "\", i.toString())" + langSpec.getStatementDelimiter() + "\n"; + } + statements += langSpec.getEndForStatement("i") + "\n"; +// return "Entity entity = Entity.entity(" + paramName + ".toString(), MediaType.APPLICATION_JSON);"; } - if (DataConstraintModel.typeTuple.isAncestorOf(compType) || DataConstraintModel.typePair.isAncestorOf(paramType) || DataConstraintModel.typeList.isAncestorOf(compType) || DataConstraintModel.typeMap.isAncestorOf(paramType)) { - statements += "\tform.param(\"" + paramName + "\", " + langSpec.getConstructorInvocation("ObjectMapper", null) + ".writeValueAsString(i))" + langSpec.getStatementDelimiter() + "\n"; // typeTuple: {"1.0":2.0}, typePair: {"left": 1.0, "right":2.0} - } else { - statements += "\tform.param(\"" + paramName + "\", i.toString())" + langSpec.getStatementDelimiter() + "\n"; - } - statements += langSpec.getEndForStatement("i") + "\n"; -// return "Entity entity = Entity.entity(" + paramName + ".toString(), MediaType.APPLICATION_JSON);"; } else if (DataConstraintModel.typeTuple.isAncestorOf(paramType) || DataConstraintModel.typePair.isAncestorOf(paramType) || DataConstraintModel.typeMap.isAncestorOf(paramType)) { // typeTuple: {"1.0":2.0}, typePair: {"left": 1.0, "right":2.0} statements += "form.param(\"" + paramName + "\", " + langSpec.getConstructorInvocation("ObjectMapper", null) + ".writeValueAsString(" + value + "))" + langSpec.getStatementDelimiter() + "\n"; diff --git a/AlgebraicDataflowArchitectureModel/src/generators/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/generators/TypeInference.java index bd8418c..1d9f4f9 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/TypeInference.java @@ -22,10 +22,13 @@ import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.JsonType; +import models.dataConstraintModel.ListType; +import models.dataConstraintModel.MapType; import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; import models.dataConstraintModel.Selector; import models.dataConstraintModel.StateTransition; +import models.dataConstraintModel.TupleType; import models.dataFlowModel.DataTransferModel; import models.dataFlowModel.ResourceNode; @@ -2144,11 +2147,9 @@ } } - private Type createNewListType(Type compType, Type parentType) { - String compTypeName = getInterfaceTypeName(compType); + private ListType createNewListType(Type compType, Type parentType) { List childrenTypes = getChildrenTypes(parentType, listComponentTypes.keySet()); - Type newListType = langSpec.newListType(compTypeName, parentType); - newListType.addParentType(parentType); + ListType newListType = langSpec.newListType(compType, parentType); listTypes.put(compType, newListType); listComponentTypes.put(newListType, compType); for (Type childType : childrenTypes) { @@ -2165,9 +2166,9 @@ return newListType; } - private Type createNewMapType(List componentTypes, Type parentMapType) { + private MapType createNewMapType(List componentTypes, Type parentMapType) { List childrenTypes = getChildrenTypes(parentMapType, mapComponentTypes.keySet()); - Type newMapType = langSpec.newMapType(componentTypes.get(0), componentTypes.get(1).toString(), parentMapType); + MapType newMapType = langSpec.newMapType(componentTypes.get(0), componentTypes.get(1), parentMapType); mapTypes.put(componentTypes, newMapType); mapComponentTypes.put(newMapType, componentTypes); for (Type childType : childrenTypes) { @@ -2184,9 +2185,9 @@ return newMapType; } - private Type createNewTupleType(List componentTypes, Type parentTupleType) { + private TupleType createNewTupleType(List componentTypes, Type parentTupleType) { List childrenTypes = getChildrenTypes(parentTupleType, tupleComponentTypes.keySet()); - Type newTupleType = langSpec.newTupleType(componentTypes, parentTupleType); + TupleType newTupleType = langSpec.newTupleType(componentTypes, parentTupleType); tupleTypes.put(componentTypes, newTupleType); tupleComponentTypes.put(newTupleType, componentTypes); for (Type childType : childrenTypes) { diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonType.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonType.java index 922351c..0e098bc 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonType.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonType.java @@ -7,9 +7,7 @@ import models.algebra.Type; public class JsonType extends Type { - protected boolean isListOrMap = false; protected Map memberTypes = null; - protected Type listOrMapElementType = null; public JsonType(String typeName, ITypeImpl implementationType) { super(typeName, implementationType); @@ -46,20 +44,4 @@ public void addMemberType(String key, Type valueType) { memberTypes.put(key, valueType); } - -// public boolean isListOrMap() { -// return isListOrMap; -// } -// -// public void setListOrMap(boolean isListOrMap) { -// this.isListOrMap = isListOrMap; -// } - - public Type getElementType() { - return listOrMapElementType; - } - - public void setElementType(Type listElementType) { - this.listOrMapElementType = listElementType; - } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListType.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListType.java new file mode 100644 index 0000000..35e6589 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListType.java @@ -0,0 +1,32 @@ +package models.dataConstraintModel; + +import models.algebra.Type; + +public class ListType extends Type { + protected Type elementType = null; + + public ListType(String typeName, ITypeImpl implementationType) { + super(typeName, implementationType); + } + + public ListType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType) { + super(typeName, implementationType, interfaceType); + } + + public ListType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType, Type parentListType) { + super(typeName, implementationType, interfaceType, parentListType); + } + + public ListType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType, Type parentListType, Type elementType) { + super(typeName, implementationType, interfaceType, parentListType); + this.elementType = elementType; + } + + public Type getElementType() { + return elementType; + } + + public void setElementType(Type listElementType) { + this.elementType = listElementType; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/MapType.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/MapType.java new file mode 100644 index 0000000..b9f3233 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/MapType.java @@ -0,0 +1,49 @@ +package models.dataConstraintModel; + +import models.algebra.Type; + +public class MapType extends Type { + protected Type keyType = null; + protected Type valueType = null; + + public MapType(String typeName, ITypeImpl implementationType) { + super(typeName, implementationType); + } + + public MapType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType) { + super(typeName, implementationType, interfaceType); + } + + public MapType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType, Type parentMapType) { + super(typeName, implementationType, interfaceType, parentMapType); + } + + public MapType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType, Type keyType, Type valueType) { + super(typeName, implementationType, interfaceType); + this.keyType = keyType; + this.valueType = valueType; + } + + public MapType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType, Type parentMapType, Type keyType, Type valueType) { + super(typeName, implementationType, interfaceType, parentMapType); + this.keyType = keyType; + this.valueType = valueType; + } + + public Type getKeyType() { + return keyType; + } + + public void setKeyType(Type keyType) { + this.keyType = keyType; + } + + public Type getValueType() { + return valueType; + } + + public void setValueType(Type valueType) { + this.valueType = valueType; + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/PairType.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/PairType.java new file mode 100644 index 0000000..5e79573 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/PairType.java @@ -0,0 +1,19 @@ +package models.dataConstraintModel; + +import models.algebra.Type; + +public class PairType extends Type { + protected Type componentType = null; + + public PairType(String typeName, ITypeImpl implementationType) { + super(typeName, implementationType); + } + + public Type getComponentType() { + return componentType; + } + + public void setComponentType(Type pairComponentType) { + this.componentType = pairComponentType; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/TupleType.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/TupleType.java new file mode 100644 index 0000000..ef95568 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/TupleType.java @@ -0,0 +1,44 @@ +package models.dataConstraintModel; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import models.algebra.Type; + +public class TupleType extends Type { + protected List componentTypes; + + public TupleType(String typeName, ITypeImpl implementationType) { + super(typeName, implementationType); + this.componentTypes = new ArrayList<>(); + } + + public TupleType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType) { + super(typeName, implementationType, interfaceType); + this.componentTypes = new ArrayList<>(); + } + + public TupleType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType, Type parentTupleType) { + super(typeName, implementationType, interfaceType, parentTupleType); + this.componentTypes = new ArrayList<>(); + } + + public TupleType(String typeName, code.ast.Type implementationType, code.ast.Type interfaceType, List componentTypes, Type parentTupleType) { + super(typeName, implementationType, interfaceType, parentTupleType); + this.componentTypes = componentTypes; + } + + public List getComponentTypes() { + return componentTypes; + } + + public Type getComponentType(int idx) { + return componentTypes.get(idx); + } + + public void addComponentType(Type componentType) { + componentTypes.add(componentType); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/tests/ASTTest.java b/AlgebraicDataflowArchitectureModel/src/tests/ASTTest.java index 14ced0d..74be013 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/ASTTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/ASTTest.java @@ -26,9 +26,7 @@ )); methodBody.addStatement(variableDeclarationStatement); - models.algebra.Variable j = new models.algebra.Variable("j"); - models.algebra.Constant limit = new models.algebra.Constant("5"); - ForStatement forStatement = javaGen.getForStatementForList(j, limit); + ForStatement forStatement = javaGen.getForStatementForList("j", "list"); Block forBody = new Block(); forBody.addStatement(new ExpressionStatement( new InfixExpression(new Symbol("+=", 2, Symbol.Type.INFIX), new Variable("sum"), new Variable("j"))