・DataFlowGraph を用いたコード生成で,コンストラクタの戻り値が void になっていたのを修正.
・DataFlowGraph を用いたコード生成で,子孫リソースのJsonの型をただしくクラスに置き換えられてなかったのを修正.
1 parent 64613ec commit 1003312714963b39a57ea2f205f568b4be5e4e88
Naoya Nitta authored on 26 Dec
Showing 2 changed files
View
88
AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java
Map<ResourceHierarchy, TypeDeclaration> resourceComponents = new HashMap<>();
Map<ResourceHierarchy, MethodDeclaration> resourceConstructors = new HashMap<>();
List<Map.Entry<ResourceHierarchy, VariableDeclaration>> constructorParams = new ArrayList<>();
List<Map.Entry<ResourceHierarchy, String>> constructorStatements = new ArrayList<>();
Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>> updateStatements = new HashMap<>();
Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>> updateStatements = new HashMap<>();
Map<ResourceHierarchy, Set<ResourceHierarchy>> descendantGetters = new HashMap<>();
// For each components (1st pass).
for (Node componentNode: components) {
parentComponent = resourceComponents.get(resourceNode.getResourceHierarchy().getParent());
}
// Declare cache fields and update methods in this resource.
Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>>> initStatementsAndUpdateUpdates = declareCacheFieldsAndUpdateMethods(resourceNode, component, parentComponent, langSpec);
Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>>> initStatementsAndUpdateUpdates = declareCacheFieldsAndUpdateMethods(resourceNode, component, parentComponent, langSpec);
if (component == null) {
// Constructor statements were not added to any component because no component had been generated.
for (String statement: initStatementsAndUpdateUpdates.getKey()) {
constructorStatements.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), statement));
}
}
for (Map.Entry<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>> entry: initStatementsAndUpdateUpdates.getValue().entrySet()) {
for (Map.Entry<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>> entry: initStatementsAndUpdateUpdates.getValue().entrySet()) {
updateStatements.put(entry.getKey(), entry.getValue());
}
// Declare the fields to refer to other resources in the parent/this component, and the state field in the parent component.
}
}
// Declare input methods in this component and the main component.
Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>>> initStatementsAndInputUpdates = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, model, langSpec);
Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>>> initStatementsAndInputUpdates = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, model, langSpec);
if (component == null) {
// Constructor statements were not added to any component because no component had been generated.
for (String statement: initStatementsAndInputUpdates.getKey()) {
constructorStatements.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy().getParent(), statement));
}
}
for (Map.Entry<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>> entry: initStatementsAndInputUpdates.getValue().entrySet()) {
for (Map.Entry<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>> entry: initStatementsAndInputUpdates.getValue().entrySet()) {
updateStatements.put(entry.getKey(), entry.getValue());
}
}
// Add update statements.
for (MethodDeclaration method: updateStatements.keySet()) {
Expression updateExp = updateStatements.get(method).getKey();
ResourceHierarchy descendantRes = updateStatements.get(method).getValue();
Set<ResourceHierarchy> children;
do {
if (JavaCodeGenerator.generatesComponent(descendantRes)) break;
children = descendantRes.getChildren();
} while (children != null && children.size() == 1 && (descendantRes = children.iterator().next()) != null);
TypeDeclaration descendanttComponent = resourceComponents.get(descendantRes);
addUpdateStatementWithConstructorInvocationToMethod(method, updateExp, descendantRes, descendanttComponent, langSpec);
ResourceHierarchy resource = updateStatements.get(method).getValue().getKey();
ResourceHierarchy descendantRes = updateStatements.get(method).getValue().getValue();
TypeDeclaration descendantComponent = resourceComponents.get(descendantRes);
addUpdateStatementWithConstructorInvocationToMethod(method, updateExp, resource, descendantRes, descendantComponent, langSpec);
}
}
 
private static List<VariableDeclaration> addConstructorParameters(ResourceHierarchy resource, Map<ResourceHierarchy, TypeDeclaration> resourceComponents,
if (resource.getNumParameters() > 0) params.clear();
return params;
}
private void addUpdateStatementWithConstructorInvocationToMethod(MethodDeclaration method, Expression exp, ResourceHierarchy descendantRes, TypeDeclaration descendantComponent, ILanguageSpecific langSpec) {
private void addUpdateStatementWithConstructorInvocationToMethod(MethodDeclaration method, Expression exp, ResourceHierarchy resource, ResourceHierarchy descendantRes, TypeDeclaration descendantComponent, ILanguageSpecific langSpec) {
Type replacedJsonType = descendantRes.getResourceStateType();
String replacingClassName = getComponentName(descendantRes, langSpec);
Type descendantType = new Type(replacingClassName, replacingClassName);
Map<Position, Term> subTerms = ((Term) exp).getSubTerms(Term.class);
}
}
}
// Replace the type of the state field.
Type fieldType = getImplStateType(descendantRes.getParent(), langSpec);
Type fieldType = getImplStateType(resource, langSpec);
if (exp instanceof Term) {
((Term) exp).setType(fieldType);
for (Map.Entry<Position, Variable> varEnt: ((Term) exp).getVariables().entrySet()) {
if (varEnt.getValue().getName().equals(fieldOfResourceState)) {
} while (childNodes != null && childNodes.size() == 1 && (descendant = childNodes.iterator().next()) != null);
}
}
private Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>>> declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, ILanguageSpecific langSpec) {
private Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>>> declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, ILanguageSpecific langSpec) {
// Declare cash fields and update methods in the component.
String resComponentName = getComponentName(resourceNode.getResourceHierarchy(), langSpec);
List<String> constructorStatements = new ArrayList<>();
Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>> updateStatements = new HashMap<>();
Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>> updateStatements = new HashMap<>();
for (Edge chToRes: resourceNode.getInEdges()) {
for (Edge resToCh: chToRes.getSource().getInEdges()) {
DataTransferChannel ch = ((ChannelNode) resToCh.getDestination()).getChannel();
DataFlowEdge re = (DataFlowEdge) resToCh;
}
// Replace Json constructor with a constructor of the child resource.
ResourceHierarchy outRes = out.getResource().getResourceHierarchy();
if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) {
ResourceHierarchy childRes = outRes.getChildren().iterator().next();
Type childStateType = childRes.getResourceStateType();
if (DataConstraintModel.typeJson.isAncestorOf(childStateType)) {
updateStatements.put(update, new AbstractMap.SimpleEntry<>(updateExp, childRes));
break;
}
ResourceHierarchy descendantRes = outRes;
Set<ResourceHierarchy> children = descendantRes.getChildren();
do {
descendantRes = children.iterator().next();
if (generatesComponent(descendantRes)) {
updateStatements.put(update, new AbstractMap.SimpleEntry<>(updateExp, new AbstractMap.SimpleEntry<>(outRes, descendantRes)));
updateExp = null;
break;
}
children = descendantRes.getChildren();
} while (children != null && children.size() == 1);
}
// Add statements to the update method.
String[] sideEffects = new String[] {""};
String newState = updateExp.toImplementation(sideEffects);
}
return new AbstractMap.SimpleEntry<>(constructorStatements, updateStatements);
}
private Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>>> declareInputMethodsInThisAndMainComponents(ResourceNode resourceNode, TypeDeclaration component,
private Map.Entry<List<String>, Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>>> declareInputMethodsInThisAndMainComponents(ResourceNode resourceNode, TypeDeclaration component,
TypeDeclaration parentComponent, TypeDeclaration mainComponent, DataTransferModel model, ILanguageSpecific langSpec) {
// Declare input methods.
String resName = resourceNode.getResourceName();
String resComponentName = langSpec.toComponentName(resName);
List<String> constructorStatements = new ArrayList<>();
Map<MethodDeclaration, Map.Entry<Expression, ResourceHierarchy>> inputStatements = new HashMap<>();
for (Channel ch : model.getInputChannels()) {
for (ChannelMember out : ((DataTransferChannel) ch).getOutputChannelMembers()) {
Map<MethodDeclaration, Map.Entry<Expression, Map.Entry<ResourceHierarchy, ResourceHierarchy>>> inputStatements = new HashMap<>();
for (Channel ch: model.getInputChannels()) {
for (ChannelMember out: ((DataTransferChannel) ch).getOutputChannelMembers()) {
if (resourceNode.getInSideResources().contains(out.getResource())) {
Expression message = out.getStateTransition().getMessageExpression();
MethodDeclaration input = null;
MethodDeclaration inputAccessor = null;
if (input != null) {
// Add a statement to update the state field to the input method.
try {
Expression updateExp = ((DataTransferChannel) ch).deriveUpdateExpressionOf(out, getRefAccessor()).getKey();
// Replace Json constructor with a constructor of the child resource.
// Replace Json constructor with a constructor of a descendant resource.
ResourceHierarchy outRes = out.getResource().getResourceHierarchy();
if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) {
ResourceHierarchy childRes = outRes.getChildren().iterator().next();
Type childStateType = childRes.getResourceStateType();
if (DataConstraintModel.typeJson.isAncestorOf(childStateType)) {
inputStatements.put(input, new AbstractMap.SimpleEntry<>(updateExp, childRes));
updateExp = null;
}
ResourceHierarchy descendantRes = outRes;
Set<ResourceHierarchy> children = descendantRes.getChildren();
do {
descendantRes = children.iterator().next();
if (generatesComponent(descendantRes)) {
inputStatements.put(input, new AbstractMap.SimpleEntry<>(updateExp, new AbstractMap.SimpleEntry<>(outRes, descendantRes)));
updateExp = null;
break;
}
children = descendantRes.getChildren();
} while (children != null && children.size() == 1);
}
// Add statements to the input method.
if (updateExp != null) {
String[] sideEffects = new String[] {""};
View
2
■■■
AlgebraicDataflowArchitectureModel/src/generators/JavaSpecific.java
}
 
@Override
public MethodDeclaration newMethodDeclaration(String methodName, boolean isConstructor, Type returnType, List<VariableDeclaration> parameters) {
if (returnType == null) {
if (returnType == null && !isConstructor) {
returnType = typeVoid;
}
return new MethodDeclaration(methodName, isConstructor, returnType, parameters);
}