package algorithms; import java.util.ArrayList; import code.ast.*; import models.*; import models.algebra.*; import models.dataConstraintModel.*; import models.dataFlowModel.*; import models.dataFlowModel.DataflowChannelGenerator.IResourceStateAccessor; public class CodeGenerator { static public ArrayList<TypeDeclaration> doGenerate(ResourceDependencyGraph graph, DataFlowModel model) { ArrayList<TypeDeclaration> codes = new ArrayList<>(); ArrayList<ResourceNode> resources = StoreResourceCheck(graph); codes.add(new TypeDeclaration("Main")); for (ResourceNode rn : resources) { String name = rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase() + rn.getIdentifierTemplate().getResourceName().substring(1); FieldDeclaration field = new FieldDeclaration(new Type(name, name), rn.getIdentifierTemplate().getResourceName()); TypeDeclaration type = new TypeDeclaration(name); codes.get(0).addField(field); 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); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { type.addField(new FieldDeclaration(new Type(rename, rename), ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName())); type.addConstructors(new VariableDeclaration(new Type(rename, rename), ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName())); } } ArrayList<VariableDeclaration> vars = new ArrayList<>(); boolean flag = false; 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); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { type.addField(new FieldDeclaration(new Type(rename, rename), ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); type.addConstructors(new VariableDeclaration(new Type(rename, rename), ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); } else { vars.add(new VariableDeclaration( ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceStateType(), ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName())); flag = true; } } if (flag) type.addMethod(new MethodDeclaration("update", false, new Type("Void", "void"), vars)); if (((StoreAttribute) rn.getAttribute()).isStored()) { type.addField(new FieldDeclaration(rn.getIdentifierTemplate().getResourceStateType(), rn.getIdentifierTemplate().getResourceName())); } type.addMethod(new MethodDeclaration("get" + type.getTypeName(), rn.getIdentifierTemplate().getResourceStateType())); codes.add(type); } return codes; } static public ArrayList<String> getCodes(ArrayList<TypeDeclaration> codeTree) { ArrayList<String> codes = new ArrayList<>(); for (TypeDeclaration type : codeTree) { codes.add("public class " + type.getTypeName() + "{"); for (FieldDeclaration field : type.getFields()) { if (type.getTypeName() != "Main") { String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " + field.getName(); if(field.getType().equals(DataConstraintModel.typeList)) cons += " = new ArrayList<>()"; cons += ";"; codes.add(cons); } else { String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " " + field.getName() + " = new " + field.getType().getTypeName() + "("; for (TypeDeclaration tree : codeTree) { if (field.getType().getTypeName() == tree.getTypeName()) { for (VariableDeclaration var : tree.getConstructors()) { cons += var.getName() + ","; } if (!tree.getConstructors().isEmpty()) cons = cons.substring(0, cons.length() - 1); break; } } cons += ");"; codes.add(cons); } } codes.add(""); if (type.getTypeName() != "Main") { if (!type.getConstructors().isEmpty()) { String cons = "\t" + "public " + type.getTypeName() + "("; for (VariableDeclaration constructor : type.getConstructors()) { cons += constructor.getType().getTypeName() + " " + constructor.getName() + ","; } if (!type.getConstructors().isEmpty()) cons = cons.substring(0, cons.length() - 1); cons += "){"; codes.add(cons); for (FieldDeclaration field : type.getFields()) { for (VariableDeclaration vari : type.getConstructors()) { if (field.getType().getTypeName().equals(vari.getType().getTypeName())) { codes.add("\t\t" + "this." + field.getName() + " = " + field.getName() + ";"); } } } codes.add("\t" + "}"); codes.add(""); } } for (MethodDeclaration method : type.getMethods()) { String varstr = "\t" + "public " + method.getReturnType().getImplementationTypeName() + " " + method.getName() + "("; if (method.getParameters() != null) { for (VariableDeclaration var : method.getParameters()) { varstr += var.getType().getImplementationTypeName() + " " + var.getName() + ","; } if (!method.getParameters().isEmpty()) varstr = varstr.substring(0, varstr.length() - 1); } codes.add(varstr + ")" + "{"); codes.add("\t" + "}"); codes.add(""); } codes.add("}"); codes.add(""); } return codes; } static private ArrayList<ResourceNode> StoreResourceCheck(ResourceDependencyGraph graph) { ArrayList<ResourceNode> resources = new ArrayList<>(); for (Node n : graph.getNodes()) { ResourceNode rn = (ResourceNode) n; boolean flag = true; for (Edge e : rn.getOutEdges()) { ResourceDependency re = (ResourceDependency) e; if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { flag = false; } } for (Edge e : rn.getInEdges()) { ResourceDependency re = (ResourceDependency) e; if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { flag = false; } } if (flag) resources.add(rn); } trackNode(resources.get(0), resources); return resources; } static private void trackNode(ResourceNode current, ArrayList<ResourceNode> resources) { if (!resources.contains(current)) resources.add(current); for (Edge e : current.getOutEdges()) { ResourceDependency re = (ResourceDependency) e; if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { trackNode((ResourceNode) re.getDestination(), resources); } } for (Edge e : current.getInEdges()) { ResourceDependency re = (ResourceDependency) e; if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { trackNode((ResourceNode) re.getSource(), resources); } } } static public IResourceStateAccessor pushAccessor = new IResourceStateAccessor() { @Override public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { if (target.equals(from)) { return new Field(target.getResourceName(), target.getResourceStateType() != null ? target.getResourceStateType() : DataConstraintModel.typeInt); } return null; } @Override public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { return new Parameter(target.getResourceName(), target.getResourceStateType() != null ? target.getResourceStateType() : DataConstraintModel.typeInt); } }; static public IResourceStateAccessor pullAccessor = new IResourceStateAccessor() { @Override public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { if (target.equals(from)) { return new Field(target.getResourceName(), target.getResourceStateType() != null ? target.getResourceStateType() : DataConstraintModel.typeInt); } return null; } @Override public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { Term getter = new Term(new Symbol("get" + target.getResourceName(), 1, Symbol.Type.METHOD)); getter.addChild(new Field(target.getResourceName(), target.getResourceStateType())); return getter; } }; }