diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java index 6f0b0f5..d75e568 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java @@ -80,25 +80,26 @@ + rn.getIdentifierTemplate().getResourceName().substring(1); TypeDeclaration type = new TypeDeclaration(resourceName); - // Declare the field to refer each resource in the main type. + // Declare the field to refer to each resource in the main type. String fieldInitializer = "new " + resourceName + "("; + Set depends = new HashSet<>(); for (Edge e : rn.getOutEdges()) { ResourceDependency re = (ResourceDependency) e; - String rename = ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName() - .substring(0, 1).toUpperCase() - + ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName().substring(1); + IdentifierTemplate dstRes = ((ResourceNode) re.getDestination()).getIdentifierTemplate(); + String resName = dstRes.getResourceName().substring(0, 1).toUpperCase() + dstRes.getResourceName().substring(1); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { - fieldInitializer += rename.toLowerCase() + ","; + depends.add(dstRes); + fieldInitializer += resName.toLowerCase() + ","; f = true; } } for (Edge e : rn.getInEdges()) { ResourceDependency re = (ResourceDependency) e; - String rename = ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName() - .substring(0, 1).toUpperCase() - + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName().substring(1); + IdentifierTemplate srcRes = ((ResourceNode) re.getSource()).getIdentifierTemplate(); + String resName = srcRes.getResourceName().substring(0, 1).toUpperCase() + srcRes.getResourceName().substring(1); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { - fieldInitializer += rename.toLowerCase() + ","; + depends.add(srcRes); + fieldInitializer += resName.toLowerCase() + ","; f = true; } else { if (rn.getIndegree() > 1) { @@ -112,9 +113,9 @@ Set refs = new HashSet<>(); for (ChannelGenerator cg : model.getChannelGenerators()) { DataflowChannelGenerator c = (DataflowChannelGenerator) cg; - if (c.getOutputIdentifierTemplates().contains(rn.getIdentifierTemplate())) { + if (c.getInputIdentifierTemplates().contains(rn.getIdentifierTemplate())) { for (IdentifierTemplate id: c.getReferenceIdentifierTemplates()) { - if (!refs.contains(id)) { + if (!refs.contains(id) && !depends.contains(id)) { refs.add(id); String refResName = id.getResourceName(); fieldInitializer += refResName.toLowerCase() + ","; @@ -123,11 +124,9 @@ } } } - if (f) - fieldInitializer = fieldInitializer.substring(0, fieldInitializer.length() - 1); + if (f) fieldInitializer = fieldInitializer.substring(0, fieldInitializer.length() - 1); fieldInitializer += ")"; - FieldDeclaration field = new FieldDeclaration(new Type(resourceName, resourceName), - rn.getIdentifierTemplate().getResourceName()); + FieldDeclaration field = new FieldDeclaration(new Type(resourceName, resourceName), rn.getIdentifierTemplate().getResourceName()); mainType.addField(field); Block manConstructorBody = mainConstructor.getBody(); if (manConstructorBody == null) { @@ -139,38 +138,39 @@ // Declare a constructor, fields and update methods in the type of each resource. MethodDeclaration constructor = new MethodDeclaration(resourceName, true); Block block = new Block(); + depends = new HashSet<>(); for (Edge e : rn.getOutEdges()) { ResourceDependency re = (ResourceDependency) e; - String dstResName = ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName() - .substring(0, 1).toUpperCase() - + ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName().substring(1); + IdentifierTemplate dstRes = ((ResourceNode) re.getDestination()).getIdentifierTemplate(); + String dstResName = dstRes.getResourceName().substring(0, 1).toUpperCase() + dstRes.getResourceName().substring(1); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { // Declare a field to refer to the destination resource of push transfer. - type.addField(new FieldDeclaration(new Type(dstResName, dstResName), - ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName())); - constructor.addParameter(new VariableDeclaration(new Type(dstResName, dstResName), - ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName())); + depends.add(dstRes); + type.addField(new FieldDeclaration(new Type(dstResName, dstResName), dstRes.getResourceName())); + constructor.addParameter(new VariableDeclaration(new Type(dstResName, dstResName), dstRes.getResourceName())); block.addStatement("this." + dstResName.toLowerCase() + " = " + dstResName.toLowerCase() + ";"); } } for (Edge e : rn.getInEdges()) { ResourceDependency re = (ResourceDependency) e; - String srcResName = ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName() - .substring(0, 1).toUpperCase() - + ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName().substring(1); + IdentifierTemplate srcRes = ((ResourceNode) re.getSource()).getIdentifierTemplate(); + String srcResName = srcRes.getResourceName().substring(0, 1).toUpperCase() + srcRes.getResourceName().substring(1); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { // Declare a field to refer to the source resource of pull transfer. - type.addField(new FieldDeclaration(new Type(srcResName, srcResName), - ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); - constructor.addParameter(new VariableDeclaration(new Type(srcResName, srcResName), - ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); + depends.add(srcRes); + type.addField(new FieldDeclaration(new Type(srcResName, srcResName), srcRes.getResourceName())); + constructor.addParameter(new VariableDeclaration(new Type(srcResName, srcResName), srcRes.getResourceName())); block.addStatement("this." + srcResName.toLowerCase() + " = " + srcResName.toLowerCase() + ";"); } else { // Declare an update method in the type of the destination resource. ArrayList vars = new ArrayList<>(); - vars.add(new VariableDeclaration( - ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceStateType(), - ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); + vars.add(new VariableDeclaration(srcRes.getResourceStateType(), srcRes.getResourceName())); + DataflowChannelGenerator c = (DataflowChannelGenerator) re.getChannelGenerator(); + for (IdentifierTemplate ref: c.getReferenceIdentifierTemplates()) { + if (ref != rn.getIdentifierTemplate()) { + vars.add(new VariableDeclaration(ref.getResourceStateType(), ref.getResourceName())); + } + } type.addMethod(new MethodDeclaration("update" + srcResName, false, typeVoid, vars)); } } @@ -178,15 +178,15 @@ refs = new HashSet<>(); for (ChannelGenerator cg : model.getChannelGenerators()) { DataflowChannelGenerator c = (DataflowChannelGenerator) cg; - if (c.getOutputIdentifierTemplates().contains(rn.getIdentifierTemplate())) { + if (c.getInputIdentifierTemplates().contains(rn.getIdentifierTemplate())) { for (IdentifierTemplate id: c.getReferenceIdentifierTemplates()) { - if (!refs.contains(id)) { + if (!refs.contains(id) && !depends.contains(id)) { refs.add(id); String refResName = id.getResourceName(); refResName = refResName.substring(0, 1).toUpperCase() + refResName.substring(1); type.addField(new FieldDeclaration(new Type(refResName, refResName), id.getResourceName())); constructor.addParameter(new VariableDeclaration(new Type(refResName, refResName), id.getResourceName())); - block.addStatement("this." + refResName.toLowerCase() + " = " + refResName.toLowerCase() + ";"); + block.addStatement("this." + id.getResourceName() + " = " + id.getResourceName() + ";"); } } } @@ -411,7 +411,7 @@ } for (Node n: graph.getNodes()) { // for reference resources. ResourceNode rn = (ResourceNode) n; - for (Edge e : rn.getInEdges()) { + for (Edge e : rn.getOutEdges()) { ResourceDependency re = (ResourceDependency) e; for (ChannelMember m: re.getChannelGenerator().getReferenceChannelMembers()) { if (m.getIdentifierTemplate() == curNode.getIdentifierTemplate()) { @@ -438,7 +438,10 @@ target.getResourceStateType() != null ? target.getResourceStateType() : DataConstraintModel.typeInt); } - return null; + // for reference channel member + return new Parameter(target.getResourceName(), + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); } @Override diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java index 4e75870..b553446 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java @@ -46,6 +46,7 @@ // Generate the body of each update or getter method. try { + Map> referredResources = new HashMap<>(); for (Edge e: graph.getEdges()) { ResourceDependency d = (ResourceDependency) e; PushPullAttribute pushPull = (PushPullAttribute) d.getAttribute(); @@ -62,21 +63,7 @@ MethodDeclaration update = getUpdateMethod(dstType, srcType); if (((StoreAttribute) dst.getAttribute()).isStored()) { // update stored state of dst side resource (when every incoming edge is in push style) - Expression updateExp = null; - if (d.getChannelGenerator().getReferenceChannelMembers().size() == 0) { - updateExp = d.getChannelGenerator().deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); - } else { - // if there exists one or more reference channel member. - HashMap inputIdentifierToStateAccessor = new HashMap<>(); - for (Edge eIn: dst.getInEdges()) { - ResourceDependency dIn = (ResourceDependency) eIn; - inputIdentifierToStateAccessor.put(((ResourceNode) dIn.getSource()).getIdentifierTemplate(), JavaCodeGenerator.pushAccessor); - } - for (ChannelMember c: d.getChannelGenerator().getReferenceChannelMembers()) { - inputIdentifierToStateAccessor.put(c.getIdentifierTemplate(), JavaCodeGenerator.pullAccessor); // by pull transfer - } - updateExp = d.getChannelGenerator().deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor, inputIdentifierToStateAccessor); - } + Expression updateExp = d.getChannelGenerator().deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); String[] sideEffects = new String[] {""}; String curState = updateExp.toImplementation(sideEffects); String updateStatement; @@ -105,10 +92,54 @@ } // src side (for a chain of update method invocations) for (MethodDeclaration srcUpdate: getUpdateMethods(srcType)) { - srcUpdate.addStatement(dstResourceName + ".update" + srcType.getTypeName() + "(value);"); + String refParams = ""; + Set referredSet = referredResources.get(srcUpdate); + for (ChannelMember rc: d.getChannelGenerator().getReferenceChannelMembers()) { + // to get the value of reference member. + IdentifierTemplate ref = rc.getIdentifierTemplate(); + if (referredSet == null) { + referredSet = new HashSet<>(); + referredResources.put(srcUpdate, referredSet); + } + if (ref != dst.getIdentifierTemplate()) { + String refVarName = ref.getResourceName(); + if (!referredSet.contains(ref)) { + referredSet.add(ref); + Expression refGetter = JavaCodeGenerator.pullAccessor.getCurrentStateAccessorFor(ref, src.getIdentifierTemplate()); + String[] sideEffects = new String[] {""}; + String refExp = refGetter.toImplementation(sideEffects); + String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); + srcUpdate.addStatement(sideEffects[0] + refTypeName + " " + refVarName + " = " + refExp + ";"); + } + refParams += ", " + refVarName; + } + } + srcUpdate.addStatement("this." + dstResourceName + ".update" + srcType.getTypeName() + "(value" + refParams + ");"); } for (MethodDeclaration srcInput: getInputMethods(srcType, src, model)) { - srcInput.addStatement(dstResourceName + ".update" + srcType.getTypeName() + "(value);"); + String refParams = ""; + Set referredSet = referredResources.get(srcInput); + for (ChannelMember rc: d.getChannelGenerator().getReferenceChannelMembers()) { + // to get the value of reference member. + IdentifierTemplate ref = rc.getIdentifierTemplate(); + if (referredSet == null) { + referredSet = new HashSet<>(); + referredResources.put(srcInput, referredSet); + } + if (ref != dst.getIdentifierTemplate()) { + String refVarName = ref.getResourceName(); + if (!referredSet.contains(ref)) { + referredSet.add(ref); + Expression refGetter = JavaCodeGenerator.pullAccessor.getCurrentStateAccessorFor(ref, src.getIdentifierTemplate()); + String[] sideEffects = new String[] {""}; + String refExp = refGetter.toImplementation(sideEffects); + String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); + srcInput.addStatement(sideEffects[0] + refTypeName + " " + refVarName + " = " + refExp + ";"); + } + refParams += ", " + refVarName; + } + } + srcInput.addStatement("this." + dstResourceName + ".update" + srcType.getTypeName() + "(value" + refParams + ");"); } } else { // for pull (or push/pull) data transfer diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index b07fa4b..706841f 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -1223,7 +1223,7 @@ } else { // for insert if (compareTypes(compType, newTupleType)) { - ((Variable) compExp).setType(newTupleType); + ((Term) compExp).setType(newTupleType); updateExps.put(System.identityHashCode(compExp), compExp); } }