Skip to content
Snippets Groups Projects
Commit cbc61e9a authored by René Schöne's avatar René Schöne
Browse files

Merge branch 'better-api-generation' into 'master'

Better api generation

See merge request !13
parents 625a5809 d68b4dde
Branches
No related tags found
1 merge request!13Better api generation
Pipeline #6294 passed
Showing
with 453 additions and 475 deletions
...@@ -30,6 +30,7 @@ dependencies { ...@@ -30,6 +30,7 @@ dependencies {
testCompile 'org.assertj:assertj-core:3.12.1' testCompile 'org.assertj:assertj-core:3.12.1'
compile 'com.fasterxml.jackson.core:jackson-core:2.9.8' compile 'com.fasterxml.jackson.core:jackson-core:2.9.8'
compile 'com.fasterxml.jackson.core:jackson-databind:2.9.8' compile 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
compile 'org.jastadd:jastadd:2.3.4'
runtime 'org.jastadd:jastadd:2.3.4' runtime 'org.jastadd:jastadd:2.3.4'
compile group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' compile group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0' compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0'
...@@ -159,7 +160,7 @@ task firstRelationsRun(type: RelastTest) { ...@@ -159,7 +160,7 @@ task firstRelationsRun(type: RelastTest) {
grammarName = 'src/test/jastadd/relations/Relations' grammarName = 'src/test/jastadd/relations/Relations'
useJastAddNames = true useJastAddNames = true
packageName = 'relations.ast' packageName = 'relations.ast'
moreInputFiles 'src/test/jastadd/Utils.jadd' moreInputFiles 'src/test/jastadd/Utils.jadd', 'src/test/jastadd/relations/Relations.jrag'
} }
task secondRelationsRun(type: RelastTest, dependsOn: firstRelationsRun) { task secondRelationsRun(type: RelastTest, dependsOn: firstRelationsRun) {
...@@ -185,7 +186,7 @@ task compileDefaultNamesTest(type: RelastTest) { ...@@ -185,7 +186,7 @@ task compileDefaultNamesTest(type: RelastTest) {
relastFiles 'src/test/jastadd/relations/Relations.relast' relastFiles 'src/test/jastadd/relations/Relations.relast'
grammarName = 'src/test/jastadd/relations/Relations3' grammarName = 'src/test/jastadd/relations/Relations3'
packageName = 'defaultnames.ast' packageName = 'defaultnames.ast'
moreInputFiles 'src/test/jastadd/Utils.jadd' moreInputFiles 'src/test/jastadd/Utils.jadd', 'src/test/jastadd/relations/Relations.jrag'
} }
task compileDefaultNamesResolverTest(type: RelastTest) { task compileDefaultNamesResolverTest(type: RelastTest) {
...@@ -253,6 +254,7 @@ task compileListNamesTest(type: RelastTest) { ...@@ -253,6 +254,7 @@ task compileListNamesTest(type: RelastTest) {
grammarName = 'src/test/jastadd/listnames/ListNames' grammarName = 'src/test/jastadd/listnames/ListNames'
useJastAddNames = true useJastAddNames = true
jastAddList = 'ListyMcListface' jastAddList = 'ListyMcListface'
listClass = 'java.util.LinkedList'
packageName = 'listnames.ast' packageName = 'listnames.ast'
moreInputFiles 'src/test/jastadd/Utils.jadd' moreInputFiles 'src/test/jastadd/Utils.jadd'
} }
......
...@@ -36,13 +36,13 @@ aspect ComponentAnalysis { ...@@ -36,13 +36,13 @@ aspect ComponentAnalysis {
eq Program.getChild().enclosingTypeDecl() = null; eq Program.getChild().enclosingTypeDecl() = null;
//--- otherSide --- //--- otherSide ---
inh RelationComponent RelationComponent.otherSide(); inh RelationComponent RelationComponent.opposite();
eq Relation.getLeft().otherSide() = getRight(); eq Relation.getLeft().opposite() = getRight();
eq Relation.getRight().otherSide() = getLeft(); eq Relation.getRight().opposite() = getLeft();
eq Program.getChild().otherSide() = null; eq Program.getChild().opposite() = null;
//--- ofTypeDecl --- //--- ofTypeDecl ---
syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().getTypeUse().decl(); syn TypeDecl RelationComponent.ofTypeDecl() = opposite().getTypeUse().decl();
//--- isAlreadyDeclared --- //--- isAlreadyDeclared ---
/** /**
...@@ -141,7 +141,7 @@ aspect ComponentAnalysis { ...@@ -141,7 +141,7 @@ aspect ComponentAnalysis {
//--- relationComponentsTransitive --- //--- relationComponentsTransitive ---
syn Collection<RelationComponent> TypeDecl.relationComponentsTransitive() { syn Collection<RelationComponent> TypeDecl.relationComponentsTransitive() {
ArrayList<RelationComponent> list = new ArrayList<>(); Collection<RelationComponent> list = new ArrayList<>();
if (hasSuper() && getSuper().decl() != null) { if (hasSuper() && getSuper().decl() != null) {
list.addAll(getSuper().decl().relationComponentsTransitive()); list.addAll(getSuper().decl().relationComponentsTransitive());
} }
...@@ -170,10 +170,14 @@ aspect ComponentAnalysis { ...@@ -170,10 +170,14 @@ aspect ComponentAnalysis {
//--- isList --- //--- isList ---
syn boolean Component.isList() = false; syn boolean Component.isList() = false;
eq ListComponent.isList() = true; eq ListComponent.isList() = true;
eq NTAListComponent.isList() = true;
eq ManyRelationComponent.isList() = true;
//--- isOpt --- //--- isOpt ---
syn boolean Component.isOpt() = false; syn boolean Component.isOpt() = false;
eq OptComponent.isOpt() = true; eq OptComponent.isOpt() = true;
eq NTAOptComponent.isOpt() = true;
eq OptionalRelationComponent.isOpt() = true;
//--- isNullable --- //--- isNullable ---
syn boolean Component.isNullable() = false; syn boolean Component.isNullable() = false;
...@@ -188,7 +192,7 @@ aspect InstanceSupplier { ...@@ -188,7 +192,7 @@ aspect InstanceSupplier {
//--- subTypeDecls --- //--- subTypeDecls ---
syn Collection<TypeDecl> TypeDecl.subTypeDecls() { syn Collection<TypeDecl> TypeDecl.subTypeDecls() {
java.util.List<TypeDecl> subDecls = new ArrayList(); Collection<TypeDecl> subDecls = new ArrayList();
for (TypeDecl decl : program().getTypeDeclList()) { for (TypeDecl decl : program().getTypeDeclList()) {
if (decl.hasSuper() && decl.getSuper().getID().equals(getID())) { if (decl.hasSuper() && decl.getSuper().getID().equals(getID())) {
subDecls.add(decl); subDecls.add(decl);
...@@ -248,10 +252,6 @@ aspect Constructors { ...@@ -248,10 +252,6 @@ aspect Constructors {
aspect Utils { aspect Utils {
//--- isMany ---
syn boolean RelationComponent.isMany() = false;
eq ManyRelationComponent.isMany() = true;
//--- toString --- //--- toString ---
public String SimpleTypeUse.toString() { public String SimpleTypeUse.toString() {
return getID(); return getID();
......
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
// We have been careful to not import many types here because the imports are added for
// _ALL_ AST nodes and can cause collisions in the abstract grammar namespace.
aspect DumpTree { aspect DumpTree {
private static final String ASTNode.DUMP_TREE_INDENT = " "; private static final String ASTNode.DUMP_TREE_INDENT = " ";
public String ASTNode.dumpTree() { public String ASTNode.dumpTree() {
ByteArrayOutputStream bytes = new ByteArrayOutputStream(); java.io.ByteArrayOutputStream bytes = new java.io.ByteArrayOutputStream();
dumpTree(new PrintStream(bytes)); dumpTree(new java.io.PrintStream(bytes));
return bytes.toString(); return bytes.toString();
} }
public void ASTNode.dumpTree(PrintStream out) { public void ASTNode.dumpTree(java.io.PrintStream out) {
dumpTree(out, ""); dumpTree(out, "");
out.flush(); out.flush();
} }
public void ASTNode.dumpTree(PrintStream out, String indent) { public void ASTNode.dumpTree(java.io.PrintStream out, String indent) {
out.print(indent + getClass().getSimpleName()); out.print(indent + getClass().getSimpleName());
out.print(getTokens()); out.print(getTokens());
String extra = extraDumpInfo(); String extra = extraDumpInfo();
...@@ -40,26 +33,21 @@ aspect DumpTree { ...@@ -40,26 +33,21 @@ aspect DumpTree {
public String ASTNode.extraDumpInfo() { return ""; } public String ASTNode.extraDumpInfo() { return ""; }
public String ASTNode.getTokens() { public String ASTNode.getTokens() {
java.util.TreeSet<java.lang.reflect.Method> methods = new java.util.TreeSet<>( java.util.TreeSet<java.lang.reflect.Method> methods = new java.util.TreeSet<>(Comparator.comparing(java.lang.reflect.Method::getName));
new java.util.Comparator<java.lang.reflect.Method>() {
public int compare(java.lang.reflect.Method m1, java.lang.reflect.Method m2) {
return m1.getName().compareTo(m2.getName());
}
});
methods.addAll(java.util.Arrays.asList(getClass().getMethods())); methods.addAll(java.util.Arrays.asList(getClass().getMethods()));
String result = ""; StringBuilder result = new StringBuilder();
for (java.lang.reflect.Method method : methods) { for (java.lang.reflect.Method method : methods) {
ASTNodeAnnotation.Token token = method.getAnnotation(ASTNodeAnnotation.Token.class); ASTNodeAnnotation.Token token = method.getAnnotation(ASTNodeAnnotation.Token.class);
if (token != null) { if (token != null) {
try { try {
result += String.format(" %s=\"%s\"", token.name(), method.invoke(this)); result.append(String.format(" %s=\"%s\"", token.name(), method.invoke(this)));
} catch (IllegalAccessException ignored) { } catch (IllegalAccessException ignored) {
} catch (InvocationTargetException ignored) { } catch (java.lang.reflect.InvocationTargetException ignored) {
} }
} }
} }
return result; return result.toString();
} }
} }
aspect BackendAPI { aspect BackendAPI {
public void Relation.generateAPI(StringBuilder sb) { public void Relation.generateAPI(StringBuilder sb) {
sb.append(ind(1) + "// " + prettyPrint() + "\n"); sb.append(ind(1) + "// api for " + prettyPrint() + "\n");
getDirection().generateAPI(sb); if (getLeft().isNavigable()) {
sb.append(ind(1) + "// left direction for " + prettyPrint() + "\n");
getLeft().generateAPI(sb);
}
if (getRight().isNavigable()) {
sb.append(ind(1) + "// right direction for " + prettyPrint() + "\n");
getRight().generateAPI(sb);
}
sb.append("\n"); sb.append("\n");
} }
public abstract void Direction.generateAPI(StringBuilder sb);
public void RelationComponent.generateAPI(StringBuilder sb) {
if (opposite().isNavigable()) {
if (multiplicityOne() || multiplicityOpt()) {
generateGetOne(sb);
if (opposite().multiplicityOne() || opposite().multiplicityOpt()) {
generateBiOneOne(sb);
} else if (opposite().multiplicityMany()) {
generateBiOneMany(sb);
}
if (isOpt()) {
generateExtraOptAPI(sb);
}
} else if (multiplicityMany()) {
if (opposite().multiplicityOne() || opposite().multiplicityOpt()) {
generateBiManyOne(sb);
} else if (opposite().multiplicityMany()) {
generateBiManyMany(sb);
}
}
} else {
if (multiplicityOne() || multiplicityOpt()) {
generateGetOne(sb);
generateDirectedZeroOneAPI(sb);
if (isOpt()) {
generateExtraOptAPI(sb);
}
} else if (multiplicityMany()) {
generateDirectedManyAPI(sb);
}
}
}
public void RelationComponent.generateGetOne(StringBuilder sb) {
sb.append(ind(1) + "public " + ofTypeDecl() + " " + getTypeUse().decl() + ".");
if (useJastAddNames) {
sb.append("get" + nameCapitalized());
} else {
sb.append(name());
}
sb.append("() {\n");
if (resolverHelper | serializer) {
sb.append(ind(2) + "if (" + getImplAttributeField() + " != null && " + getImplAttributeField() + "." + isUnresolvedMethod + "()) {\n");
sb.append(ind(3) + "if (" + getImplAttributeField() + "." + asUnresolvedMethod + "().get" + unresolvedPrefix + "ResolveOpposite()) {\n");
sb.append(ind(4) + "set" + nameCapitalized() + "(resolve" + nameCapitalized() + resolvePostfix + "(" + getImplAttributeField() + "." + asUnresolvedMethod + "().get" + unresolvedPrefix + "Token()));\n");
sb.append(ind(3) + "} else {\n");
sb.append(ind(4) + "set" + getImplAttributeName() + "(resolve" + nameCapitalized() + resolvePostfix + "(" + getImplAttributeField() + "." + asUnresolvedMethod + "().get" + unresolvedPrefix + "Token()));\n");
sb.append(ind(3) + "}\n");
sb.append(ind(2) + "}\n");
}
sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n");
sb.append(ind(1) + "}\n");
}
public void RelationComponent.generateExtraOptAPI(StringBuilder sb) {
// has
sb.append(ind(1) + "public boolean " + getTypeUse().decl());
sb.append(".has" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "return ");
if (useJastAddNames) {
sb.append("get" + nameCapitalized());
} else {
sb.append(name());
}
sb.append("() != null;\n");
sb.append(ind(1) + "}\n");
// clear
sb.append(ind(1) + "public void " + getTypeUse().decl());
sb.append(".clear" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "set" + nameCapitalized() + "(null);\n");
sb.append(ind(1) + "}\n");
}
inh Relation Direction.relation(); inh Relation Direction.relation();
inh Relation RelationComponent.relation();
eq Relation.getChild().relation() = this; eq Relation.getChild().relation() = this;
eq Program.getChild().relation() = null; eq Program.getChild().relation() = null;
inh boolean RelationComponent.isNavigable();
eq Relation.getLeft().isNavigable() = getDirection().isNavigableLeftToRight();
eq Relation.getRight().isNavigable() = getDirection().isNavigableRightToLeft();
eq Program.getChild().isNavigable() = false;
syn boolean Direction.isNavigableRightToLeft() = true;
eq RightDirection.isNavigableRightToLeft() = false;
syn boolean Direction.isNavigableLeftToRight() = true;
eq LeftDirection.isNavigableLeftToRight() = false;
public String RelationComponent.nameCapitalized() { public String RelationComponent.nameCapitalized() {
return name().substring(0,1).toUpperCase() + name().substring(1); return name().substring(0,1).toUpperCase() + name().substring(1);
} }
......
aspect BackendAbstractGrammar { aspect BackendAbstractGrammar {
public static String ASTNode.listClass = "ArrayList"; public static String ASTNode.listInterface = "java.util.List";
public static String ASTNode.listClass = "java.util.ArrayList";
public static String ASTNode.jastAddListType = "List"; public static String ASTNode.jastAddListType = "List";
public static String ASTNode.jastAddOptType = "Opt";
public static boolean ASTNode.resolverHelper = false; public static boolean ASTNode.resolverHelper = false;
public static boolean ASTNode.serializer = false; public static boolean ASTNode.serializer = false;
...@@ -21,47 +23,6 @@ aspect BackendAbstractGrammar { ...@@ -21,47 +23,6 @@ aspect BackendAbstractGrammar {
} }
} }
public void TypeDecl.generateUnresolvedClass(StringBuilder sb) {
if (getAbstract()) {
sb.append(ind(1) + "abstract ");
} else {
sb.append(ind(1));
}
sb.append("class " + "Unresolved$" + getID() + " extends " + getID() + " implements Unresolved$Node {\n");
sb.append(ind(2) + "private String unresolved$Token;\n");
sb.append(ind(2) + "public String getUnresolved$Token() {\n");
sb.append(ind(3) + "return unresolved$Token;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "void setUnresolved$Token(String token) {\n");
sb.append(ind(3) + "this.unresolved$Token = token;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "private boolean unresolved$ResolveOpposite;\n");
sb.append(ind(2) + "public boolean getUnresolved$ResolveOpposite() {\n");
sb.append(ind(3) + "return unresolved$ResolveOpposite;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "void setUnresolved$ResolveOpposite(boolean resolveOpposite) {\n");
sb.append(ind(3) + "this.unresolved$ResolveOpposite = resolveOpposite;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "Unresolved$Node " + getID() + ".as$Unresolved() {\n");
sb.append(ind(2) + "return null;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "Unresolved$Node Unresolved$" + getID() + ".as$Unresolved() {\n");
sb.append(ind(2) + "return this;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "boolean " + getID() + ".is$Unresolved() {\n");
sb.append(ind(2) + "return false;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "boolean Unresolved$" + getID() + ".is$Unresolved() {\n");
sb.append(ind(2) + "return true;\n");
sb.append(ind(1) + "}\n");
}
public void TypeDecl.generateAbstractGrammar(StringBuilder sb) { public void TypeDecl.generateAbstractGrammar(StringBuilder sb) {
if (getAbstract()) { if (getAbstract()) {
sb.append("abstract "); sb.append("abstract ");
...@@ -119,7 +80,7 @@ aspect BackendAbstractGrammar { ...@@ -119,7 +80,7 @@ aspect BackendAbstractGrammar {
return "<" + getImplAttributeName() + ":" + ofTypeDecl() + ">"; return "<" + getImplAttributeName() + ":" + ofTypeDecl() + ">";
} }
public String ManyRelationComponent.generateAbstractGrammar() { public String ManyRelationComponent.generateAbstractGrammar() {
return "<" + getImplAttributeName() + ":" + ASTNode.listClass + "<" + ofTypeDecl() + ">>"; return "<" + getImplAttributeName() + ":" + ASTNode.listInterface + "<" + ofTypeDecl() + ">>";
} }
public String RelationComponent.getImplAttributeName() { public String RelationComponent.getImplAttributeName() {
...@@ -128,11 +89,11 @@ aspect BackendAbstractGrammar { ...@@ -128,11 +89,11 @@ aspect BackendAbstractGrammar {
public String RelationComponent.getImplAttributeField() { public String RelationComponent.getImplAttributeField() {
// tt.bind("TypeInSignature", ASTNode.convTypeNameToSignature(type())); // tt.bind("TypeInSignature", ASTNode.convTypeNameToSignature(type()));
return "token" + ofTypeDecl() + "__impl_" + getID(); return "token" + org.jastadd.ast.AST.ASTNode.convTypeNameToSignature(ofTypeDecl().toString()) + "__impl_" + getID();
} }
public String ManyRelationComponent.getImplAttributeField() { public String ManyRelationComponent.getImplAttributeField() {
// tt.bind("TypeInSignature", ASTNode.convTypeNameToSignature(type())); // tt.bind("TypeInSignature", ASTNode.convTypeNameToSignature(type()));
return "token" + listClass + "_" + ofTypeDecl() + "___impl_" + getID(); return "token" + org.jastadd.ast.AST.ASTNode.convTypeNameToSignature(ASTNode.listInterface) + "_" + ofTypeDecl() + "___impl_" + getID();
} }
} }
...@@ -6,10 +6,6 @@ aspect BackendAspect { ...@@ -6,10 +6,6 @@ aspect BackendAspect {
} }
public void Program.generateAspect(StringBuilder sb) { public void Program.generateAspect(StringBuilder sb) {
sb.append("import java.util.ArrayList;\n");
sb.append("import java.util.Collections;\n");
sb.append("import java.time.Instant;\n");
sb.append("import java.time.Period;\n");
sb.append("aspect RelAstAPI {\n"); sb.append("aspect RelAstAPI {\n");
for (TypeDecl td: getTypeDecls()) { for (TypeDecl td: getTypeDecls()) {
...@@ -53,7 +49,7 @@ aspect BackendAspect { ...@@ -53,7 +49,7 @@ aspect BackendAspect {
return ASTNode.jastAddListType + "<" + getTypeUse() + "> " + getID(); return ASTNode.jastAddListType + "<" + getTypeUse() + "> " + getID();
} }
public String OptComponent.constructorParameter() { public String OptComponent.constructorParameter() {
return "Opt<" + getTypeUse() + "> " + getID(); return ASTNode.jastAddOptType + "<" + getTypeUse() + "> " + getID();
} }
public String Component.constructorSetMethod() { public String Component.constructorSetMethod() {
return "set" + getID(); return "set" + getID();
......
This diff is collapsed.
aspect BackendDirectedAPI { aspect BackendDirectedAPI {
public void RightDirection.generateAPI(StringBuilder sb) {
relation().getLeft().generateDirectedAPI(sb);
}
public void LeftDirection.generateAPI(StringBuilder sb) {
relation().getRight().generateDirectedAPI(sb);
}
public abstract void RelationComponent.generateDirectedAPI(StringBuilder sb); public void RelationComponent.generateDirectedZeroOneAPI(StringBuilder sb) {
public void OneRelationComponent.generateDirectedAPI(StringBuilder sb) { String setMethodDecl = getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized() + "(" + ofTypeDecl() + " o)";
generateDirectedZeroOneAPI(sb, false);
}
public void OptionalRelationComponent.generateDirectedAPI(StringBuilder sb) {
generateDirectedZeroOneAPI(sb, true);
generateExtraOptAPI(sb);
}
public void RelationComponent.generateDirectedZeroOneAPI(StringBuilder sb, boolean optional) {
// Get
generateGetOne(sb);
// Set // Set
sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl()); sb.append(ind(1) + "public " + setMethodDecl + " {\n");
sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); if (!isOpt()) {
if (!optional) {
sb.append(ind(2) + "assertNotNull(o);\n"); sb.append(ind(2) + "assertNotNull(o);\n");
} }
sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n");
...@@ -30,31 +13,33 @@ aspect BackendDirectedAPI { ...@@ -30,31 +13,33 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) { public void RelationComponent.generateDirectedManyAPI(StringBuilder sb) {
// Get // Get
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
if (useJastAddNames) { if (useJastAddNames) {
String getMethodDecl1 = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".get" + nameCapitalized() + "s()";
String getMethodDecl2 = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".get" + nameCapitalized() + "List()";
// getXs // getXs
sb.append("get" + nameCapitalized() + "s() {\n"); sb.append(ind(1) + "public " + getMethodDecl1 + " {\n");
sb.append(ind(2) + "return get" + nameCapitalized() + "List();\n"); sb.append(ind(2) + "return get" + nameCapitalized() + "List();\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// getXList // getXList
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl()); sb.append(ind(1) + "public " + getMethodDecl2 + " {\n");
sb.append(".get" + nameCapitalized() + "List() {\n");
} else { } else {
sb.append(name() + "() {\n"); String getMethodDecl = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + "." + name() + "()";
sb.append("public " + getMethodDecl + " {\n");
} }
sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n");
// resolve the entire list // resolve the entire list
if (resolverHelper | serializer) { if (resolverHelper | serializer) {
sb.append(ind(2) + "if (l != null) {\n"); sb.append(ind(2) + "if (l != null) {\n");
sb.append(ind(3) + "boolean changed = false;\n"); sb.append(ind(3) + "boolean changed = false;\n");
sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n"); sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n");
sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n"); sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n");
sb.append(ind(4) + "if (element.is$Unresolved()) {\n"); sb.append(ind(4) + "if (element." + isUnresolvedMethod + "()) {\n");
sb.append(ind(5) + "changed = true;\n"); sb.append(ind(5) + "changed = true;\n");
sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n"); sb.append(ind(5) + ofTypeDecl() + " resolvedElement = " + resolvePrefix + "" + nameCapitalized() + "" + resolvePostfix + "(element." + asUnresolvedMethod + "().get" + unresolvedTokenMethod + "(), i);\n");
sb.append(ind(5) + "l.set(i, resolvedElement);\n"); sb.append(ind(5) + "l.set(i, resolvedElement);\n");
sb.append(ind(4) + "}\n"); sb.append(ind(4) + "}\n");
sb.append(ind(3) + "}\n"); sb.append(ind(3) + "}\n");
...@@ -63,17 +48,14 @@ aspect BackendDirectedAPI { ...@@ -63,17 +48,14 @@ aspect BackendDirectedAPI {
sb.append(ind(3) + "}\n"); sb.append(ind(3) + "}\n");
sb.append(ind(2) + "}\n"); sb.append(ind(2) + "}\n");
} }
sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n"); sb.append(ind(2) + "return l != null ? java.util.Collections.unmodifiableList(l) : java.util.Collections.emptyList();\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Add // Add
sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add"); String addMethodDecl1 = "void " + getTypeUse().decl() + ".add" + (useJastAddNames ? "" : "To") + nameCapitalized() + "(" + ofTypeDecl() + " o)";
if (!useJastAddNames) { sb.append(ind(1) + "public " + addMethodDecl1 + " {\n");
sb.append("To");
}
sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
sb.append(ind(2) + "assertNotNull(o);\n"); sb.append(ind(2) + "assertNotNull(o);\n");
sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n");
sb.append(ind(2) + "if (list == null) {\n"); sb.append(ind(2) + "if (list == null) {\n");
sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n"); sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n");
sb.append(ind(2) + "}\n"); sb.append(ind(2) + "}\n");
...@@ -82,13 +64,10 @@ aspect BackendDirectedAPI { ...@@ -82,13 +64,10 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Insert / add at specific position // Insert / add at specific position
sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add"); String addMethodDecl2 = "void " + getTypeUse().decl() + ".add" + (useJastAddNames ? "" : "To") + nameCapitalized() + "(int index, " + ofTypeDecl() + " o)";
if (!useJastAddNames) { sb.append(ind(1) + "public " + addMethodDecl2 + " {\n");
sb.append("To");
}
sb.append(nameCapitalized() + "(int index, " + ofTypeDecl() + " o) {\n");
sb.append(ind(2) + "assertNotNull(o);\n"); sb.append(ind(2) + "assertNotNull(o);\n");
sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n");
sb.append(ind(2) + "if (list == null) {\n"); sb.append(ind(2) + "if (list == null) {\n");
sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n"); sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n");
sb.append(ind(2) + "}\n"); sb.append(ind(2) + "}\n");
...@@ -97,57 +76,13 @@ aspect BackendDirectedAPI { ...@@ -97,57 +76,13 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Remove // Remove
sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove"); String removeMethodDecl = "void " + getTypeUse().decl() + ".remove" + (useJastAddNames ? "" : "From") + nameCapitalized() + "(" + ofTypeDecl() + " o)";
if (!useJastAddNames) { sb.append(ind(1) + "public " + removeMethodDecl + " {\n");
sb.append("From");
}
sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
sb.append(ind(2) + "assertNotNull(o);\n"); sb.append(ind(2) + "assertNotNull(o);\n");
sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n");
sb.append(ind(2) + "if (list != null && list.remove(o)) {\n"); sb.append(ind(2) + "if (list != null && list.remove(o)) {\n");
sb.append(ind(3) + "set" + getImplAttributeName() + "(list);\n"); sb.append(ind(3) + "set" + getImplAttributeName() + "(list);\n");
sb.append(ind(2) + "}\n"); sb.append(ind(2) + "}\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
public void RelationComponent.generateGetOne(StringBuilder sb) {
sb.append(ind(1) + "public " + ofTypeDecl() + " " + getTypeUse().decl() + ".");
if (useJastAddNames) {
sb.append("get" + nameCapitalized());
} else {
sb.append(name());
}
sb.append("() {\n");
if (resolverHelper | serializer) {
sb.append(ind(2) + "if (" + getImplAttributeField() + " != null && " + getImplAttributeField() + ".is$Unresolved()) {\n");
sb.append(ind(3) + "if (" + getImplAttributeField() + ".as$Unresolved().getUnresolved$ResolveOpposite()) {\n");
sb.append(ind(4) + "set" + nameCapitalized() + "(resolve" + nameCapitalized() + "ByToken(" + getImplAttributeField() + ".as$Unresolved().getUnresolved$Token()));\n");
sb.append(ind(3) + "} else {\n");
sb.append(ind(4) + "set" + getImplAttributeName() + "(resolve" + nameCapitalized() + "ByToken(" + getImplAttributeField() + ".as$Unresolved().getUnresolved$Token()));\n");
sb.append(ind(3) + "}\n");
sb.append(ind(2) + "}\n");
}
sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n");
sb.append(ind(1) + "}\n");
}
public void RelationComponent.generateExtraOptAPI(StringBuilder sb) {
// has
sb.append(ind(1) + "public boolean " + getTypeUse().decl());
sb.append(".has" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "return ");
if (useJastAddNames) {
sb.append("get" + nameCapitalized());
} else {
sb.append(name());
}
sb.append("() != null;\n");
sb.append(ind(1) + "}\n");
// clear
sb.append(ind(1) + "public void " + getTypeUse().decl());
sb.append(".clear" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "set" + nameCapitalized() + "(null);\n");
sb.append(ind(1) + "}\n");
}
} }
...@@ -6,7 +6,7 @@ aspect LowerBoundCheck { ...@@ -6,7 +6,7 @@ aspect LowerBoundCheck {
sb.append(ind(1) + "public java.util.List<Pair<ASTNode, String>> " sb.append(ind(1) + "public java.util.List<Pair<ASTNode, String>> "
+ "ASTNode.getLowerBoundsViolations() {\n"); + "ASTNode.getLowerBoundsViolations() {\n");
sb.append(ind(2) + "ArrayList<Pair<ASTNode, String>> list = new ArrayList<>();\n"); sb.append(ind(2) + "" + ASTNode.listInterface + "<Pair<ASTNode, String>> list = new " + ASTNode.listClass + "<>();\n");
sb.append(ind(2) + "computeLowerBoundsViolations(list);\n"); sb.append(ind(2) + "computeLowerBoundsViolations(list);\n");
sb.append(ind(2) + "return list;\n"); sb.append(ind(2) + "return list;\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
......
aspect NameResolutionHelper { aspect NameResolutionHelper {
protected static final String ASTNode.unresolvedPrefix = "Unresolved$";
protected static final String ASTNode.isUnresolvedMethod = "is$Unresolved";
protected static final String ASTNode.asUnresolvedMethod = "as$Unresolved";
protected static final String ASTNode.unresolvedTokenMethod = unresolvedPrefix + "Token";
protected static final String ASTNode.unresolvedResolveOppositeMethod = unresolvedPrefix + "ResolveOpposite";
protected static final String ASTNode.createReferenceMethod = "createReference";
protected static final String ASTNode.createRefMethod = "createRef";
protected static final String ASTNode.createRefDirectionMethod = "createRefDirection";
protected static final String ASTNode.resolvePrefix = "resolve";
protected static final String ASTNode.globallyResolvePrefix = "globallyResolve";
protected static final String ASTNode.resolvePostfix = "ByToken";
protected static final String ASTNode.resolveAllMethod = "resolveAll";
protected static final String ASTNode.treeResolveAllMethod = "treeResolveAll";
protected static final String ASTNode.unresolvedNodeInterface = unresolvedPrefix + "Node$Interface";
public void TypeDecl.generateUnresolvedClass(StringBuilder sb) {
if (getAbstract()) {
sb.append(ind(1) + "abstract ");
} else {
sb.append(ind(1));
}
sb.append("class " + unresolvedPrefix + getID() + " extends " + getID() + " implements " + unresolvedNodeInterface + " {\n");
sb.append(ind(2) + "private String unresolved$Token;\n");
sb.append(ind(2) + "public String get" + unresolvedTokenMethod + "() {\n");
sb.append(ind(3) + "return unresolved$Token;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "void set" + unresolvedTokenMethod + "(String token) {\n");
sb.append(ind(3) + "this.unresolved$Token = token;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "private boolean unresolved$ResolveOpposite;\n");
sb.append(ind(2) + "public boolean get" + unresolvedResolveOppositeMethod + "() {\n");
sb.append(ind(3) + "return unresolved$ResolveOpposite;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "void set" + unresolvedResolveOppositeMethod + "(boolean resolveOpposite) {\n");
sb.append(ind(3) + "this.unresolved$ResolveOpposite = resolveOpposite;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + unresolvedNodeInterface + " " + getID() + "." + asUnresolvedMethod + "() {\n");
sb.append(ind(2) + "return null;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + unresolvedNodeInterface + " " + unresolvedPrefix + getID() + "." + asUnresolvedMethod + "() {\n");
sb.append(ind(2) + "return this;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "boolean " + getID() + "." + isUnresolvedMethod + "() {\n");
sb.append(ind(2) + "return false;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "boolean " + unresolvedPrefix + getID() + "." + isUnresolvedMethod + "() {\n");
sb.append(ind(2) + "return true;\n");
sb.append(ind(1) + "}\n");
}
public String Program.generateRewriteToSuperTypeStub() { public String Program.generateRewriteToSuperTypeStub() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
generateRewriteToSuperTypeStub(sb); generateRewriteToSuperTypeStub(sb);
...@@ -48,8 +104,8 @@ aspect NameResolutionHelper { ...@@ -48,8 +104,8 @@ aspect NameResolutionHelper {
public void Program.generateGenericRefCreation(StringBuilder sb) { public void Program.generateGenericRefCreation(StringBuilder sb) {
sb.append(ind(1) + "// generic reference creation\n"); sb.append(ind(1) + "// generic reference creation\n");
sb.append(ind(1) + "syn String ASTNode.createReference();\n"); sb.append(ind(1) + "syn String ASTNode." + createReferenceMethod + "();\n");
sb.append(ind(1) + "eq ASTNode.createReference() {\n"); sb.append(ind(1) + "eq ASTNode." + createReferenceMethod + "() {\n");
sb.append(ind(2) + "throw new RuntimeException(\"Generic reference creation not implemented.\");\n"); sb.append(ind(2) + "throw new RuntimeException(\"Generic reference creation not implemented.\");\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
...@@ -74,17 +130,17 @@ aspect NameResolutionHelper { ...@@ -74,17 +130,17 @@ aspect NameResolutionHelper {
public void RelationComponent.generateContextDependentRefCreation(StringBuilder sb) { public void RelationComponent.generateContextDependentRefCreation(StringBuilder sb) {
sb.append(ind(1) + "// context-dependent reference creation\n"); sb.append(ind(1) + "// context-dependent reference creation\n");
sb.append(ind(1) + "syn String " + getTypeUse().decl() + ".createRefTo" + nameCapitalized() + "(" + ofTypeDecl() + " target) {\n"); sb.append(ind(1) + "syn String " + getTypeUse().decl() + "." + createRefMethod + "To" + nameCapitalized() + "(" + ofTypeDecl() + " target) {\n");
sb.append(ind(2) + "// default to context-independent reference creation\n"); sb.append(ind(2) + "// default to context-independent reference creation\n");
sb.append(ind(2) + "return target.createReference();\n"); sb.append(ind(2) + "return target." + createReferenceMethod + "();\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
public void TypeDecl.generateContextIndependentRefCreation(StringBuilder sb) { public void TypeDecl.generateContextIndependentRefCreation(StringBuilder sb) {
sb.append(ind(1) + "// context-independent reference creation\n"); sb.append(ind(1) + "// context-independent reference creation\n");
sb.append(ind(1) + "eq " + getID() + ".createReference() {\n"); sb.append(ind(1) + "eq " + getID() + "." + createReferenceMethod + "() {\n");
sb.append(ind(2) + "// default to generic reference creation\n"); sb.append(ind(2) + "// default to generic reference creation\n");
sb.append(ind(2) + "return super.createReference();\n"); sb.append(ind(2) + "return super." + createReferenceMethod + "();\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
...@@ -110,9 +166,9 @@ aspect NameResolutionHelper { ...@@ -110,9 +166,9 @@ aspect NameResolutionHelper {
sb.append("aspect RefResolverHelpers {\n\n"); sb.append("aspect RefResolverHelpers {\n\n");
sb.append(ind(1) + "interface Unresolved$Node {\n"); sb.append(ind(1) + "interface " + unresolvedNodeInterface + " {\n");
sb.append(ind(2) + "String getUnresolved$Token();\n"); sb.append(ind(2) + "String get" + unresolvedTokenMethod + "();\n");
sb.append(ind(2) + "boolean getUnresolved$ResolveOpposite();\n"); sb.append(ind(2) + "boolean get" + unresolvedResolveOppositeMethod + "();\n");
sb.append(ind(1) + "}\n\n"); sb.append(ind(1) + "}\n\n");
for (TypeDecl td: getTypeDecls()) { for (TypeDecl td: getTypeDecls()) {
...@@ -131,30 +187,30 @@ aspect NameResolutionHelper { ...@@ -131,30 +187,30 @@ aspect NameResolutionHelper {
throw new RuntimeException("unable to find instantiable subtype for " + getID()); throw new RuntimeException("unable to find instantiable subtype for " + getID());
} }
sb.append(ind(1) + "public static " + getID() + " " + getID() + ".createRef(String ref) {\n"); sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefMethod + "(String ref) {\n");
sb.append(ind(2) + "Unresolved$" + instantiableSubType.getID() + " unresolvedNode = new Unresolved$" + instantiableSubType.getID() + "();\n"); sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.setUnresolved$Token(ref);\n"); sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n");
sb.append(ind(2) + "unresolvedNode.setUnresolved$ResolveOpposite(true);\n"); sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(true);\n");
sb.append(ind(2) + "return unresolvedNode;\n"); sb.append(ind(2) + "return unresolvedNode;\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
sb.append(ind(1) + "public static " + getID() + " " + getID() + ".createRefDirection(String ref) {\n"); sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefDirectionMethod + "(String ref) {\n");
sb.append(ind(2) + "Unresolved$" + instantiableSubType.getID() + " unresolvedNode = new Unresolved$" + instantiableSubType.getID() + "();\n"); sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.setUnresolved$Token(ref);\n"); sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n");
sb.append(ind(2) + "unresolvedNode.setUnresolved$ResolveOpposite(false);\n"); sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(false);\n");
sb.append(ind(2) + "return unresolvedNode;\n"); sb.append(ind(2) + "return unresolvedNode;\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
public void TypeDecl.generateContextIndependentNameResolution(StringBuilder sb) { public void TypeDecl.generateContextIndependentNameResolution(StringBuilder sb) {
sb.append(ind(1) + "// context-independent name resolution\n"); sb.append(ind(1) + "// context-independent name resolution\n");
sb.append(ind(1) + "uncache ASTNode.globallyResolve" + getID() + "ByToken(String id);\n"); sb.append(ind(1) + "uncache ASTNode." + globallyResolvePrefix + getID() + resolvePostfix + "(String id);\n");
sb.append(ind(1) + "syn " + getID() + " ASTNode.globallyResolve" + getID() + "ByToken(String id) {\n"); sb.append(ind(1) + "syn " + getID() + " ASTNode." + globallyResolvePrefix + getID() + resolvePostfix + "(String id) {\n");
if (serializer && !manualReferences) { if (serializer && !manualReferences) {
if (jsonPointer) { if (jsonPointer) {
sb.append(ind(2) + "return (" + getID() + ") resolveJsonPointer(id);\n"); sb.append(ind(2) + "return (" + getID() + ") resolveJsonPointer(id);\n");
} else { } else {
sb.append(ind(2) + "return (" + getID() + ") globallyResolveASTNodeByUID(id);\n"); sb.append(ind(2) + "return (" + getID() + ") " + globallyResolvePrefix + "ASTNodeByUID(id);\n");
} }
} else { } else {
sb.append(ind(2) + "// perform context independent name resolution here using the id\n"); sb.append(ind(2) + "// perform context independent name resolution here using the id\n");
...@@ -193,56 +249,56 @@ aspect NameResolutionHelper { ...@@ -193,56 +249,56 @@ aspect NameResolutionHelper {
public void ManyRelationComponent.generateContextDependentNameResolution(StringBuilder sb) { public void ManyRelationComponent.generateContextDependentNameResolution(StringBuilder sb) {
if (serializer && !resolverHelper) { if (serializer && !resolverHelper) {
sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n"); sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id, int position) {\n");
sb.append(ind(2) + "return (" + ofTypeDecl() + ") globallyResolveASTNodeByUID(id);\n"); sb.append(ind(2) + "return (" + ofTypeDecl() + ") " + globallyResolvePrefix + "ASTNodeByUID(id);\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} else { } else {
sb.append(ind(1) + "// context-dependent name resolution\n"); sb.append(ind(1) + "// context-dependent name resolution\n");
sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position);\n"); sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id, int position);\n");
sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n"); sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id, int position) {\n");
sb.append(ind(2) + "// default to context-independent name resolution\n"); sb.append(ind(2) + "// default to context-independent name resolution\n");
sb.append(ind(2) + "return globallyResolve" + ofTypeDecl() + "ByToken(id);\n"); sb.append(ind(2) + "return " + globallyResolvePrefix + ofTypeDecl() + resolvePostfix + "(id);\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
} }
public void RelationComponent.generateDirectedContextDependentNameResolution(StringBuilder sb) { public void RelationComponent.generateDirectedContextDependentNameResolution(StringBuilder sb) {
if (serializer && !resolverHelper) { if (serializer && !resolverHelper) {
sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n"); sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id) {\n");
sb.append(ind(2) + "return (" + ofTypeDecl() + ") globallyResolveASTNodeByUID(id);\n"); sb.append(ind(2) + "return (" + ofTypeDecl() + ") " + globallyResolvePrefix + "ASTNodeByUID(id);\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} else { } else {
sb.append(ind(1) + "// context-dependent name resolution\n"); sb.append(ind(1) + "// context-dependent name resolution\n");
sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id);\n"); sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id);\n");
sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n"); sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id) {\n");
sb.append(ind(2) + "// default to context-independent name resolution\n"); sb.append(ind(2) + "// default to context-independent name resolution\n");
sb.append(ind(2) + "return globallyResolve" + ofTypeDecl() + "ByToken(id);\n"); sb.append(ind(2) + "return " + globallyResolvePrefix + ofTypeDecl() + resolvePostfix + "(id);\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
} }
public void Program.resolveAll(StringBuilder sb) { public void Program.resolveAll(StringBuilder sb) {
sb.append(ind(1) + "// enforce resolving of all non-containment relations of the current non-terminal\n"); sb.append(ind(1) + "// enforce resolving of all non-containment relations of the current non-terminal\n");
sb.append(ind(1) + "public void ASTNode.resolveAll() {\n"); sb.append(ind(1) + "public void ASTNode." + resolveAllMethod + "() {\n");
sb.append(ind(1) + "}\n\n"); sb.append(ind(1) + "}\n\n");
sb.append(ind(1) + "// enforce resolving in the entire subtree\n"); sb.append(ind(1) + "// enforce resolving in the entire subtree\n");
sb.append(ind(1) + "public void ASTNode.treeResolveAll() {\n"); sb.append(ind(1) + "public void ASTNode." + treeResolveAllMethod + "() {\n");
sb.append(ind(2) + "if (children != null) {\n"); sb.append(ind(2) + "if (children != null) {\n");
sb.append(ind(3) + "for (int i = 0; i < numChildren; ++i) {\n"); sb.append(ind(3) + "for (int i = 0; i < numChildren; ++i) {\n");
sb.append(ind(4) + "ASTNode child = children[i];\n"); sb.append(ind(4) + "ASTNode child = children[i];\n");
sb.append(ind(4) + "if (child != null) {\n"); sb.append(ind(4) + "if (child != null) {\n");
sb.append(ind(5) + "child.treeResolveAll();\n"); sb.append(ind(5) + "child." + treeResolveAllMethod + "();\n");
sb.append(ind(4) + "}\n"); sb.append(ind(4) + "}\n");
sb.append(ind(3) + "}\n"); sb.append(ind(3) + "}\n");
sb.append(ind(2) + "}\n"); sb.append(ind(2) + "}\n");
sb.append(ind(2) + "resolveAll();\n"); sb.append(ind(2) + resolveAllMethod + "();\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
public void TypeDecl.resolveAll(StringBuilder sb) { public void TypeDecl.resolveAll(StringBuilder sb) {
sb.append(ind(1) + "// enforce resolving of all non-containment relations of the current non-terminal\n"); sb.append(ind(1) + "// enforce resolving of all non-containment relations of the current non-terminal\n");
sb.append(ind(1) + "public void " + getID() + ".resolveAll() {\n"); sb.append(ind(1) + "public void " + getID() + "." + resolveAllMethod + "() {\n");
for (RelationComponent relationComponent : relationComponents()) { for (RelationComponent relationComponent : relationComponents()) {
sb.append(ind(2)); sb.append(ind(2));
if (useJastAddNames) { if (useJastAddNames) {
...@@ -250,9 +306,9 @@ aspect NameResolutionHelper { ...@@ -250,9 +306,9 @@ aspect NameResolutionHelper {
} else { } else {
sb.append(relationComponent.name()); sb.append(relationComponent.name());
} }
sb.append(relationComponent.isMany() && useJastAddNames ? "List" : "").append("();\n"); sb.append(relationComponent.isList() && useJastAddNames ? "List" : "").append("();\n");
} }
sb.append(ind(2) + "super.resolveAll();\n"); sb.append(ind(2) + "super." + resolveAllMethod + "();\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} }
} }
...@@ -33,10 +33,10 @@ aspect PrettyPrinting { ...@@ -33,10 +33,10 @@ aspect PrettyPrinting {
aspect Utils { aspect Utils {
public String ASTNode.ind(int n) { public String ASTNode.ind(int n) {
String s = ""; StringBuilder s = new StringBuilder();
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
s += " "; s.append(" ");
} }
return s; return s.toString();
} }
} }
...@@ -169,10 +169,10 @@ aspect Serializer { ...@@ -169,10 +169,10 @@ aspect Serializer {
case "String": case "String":
sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "());\n"); sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "());\n");
break; break;
case "Instant": case "java.time.Instant":
sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().toString());\n"); sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().toString());\n");
break; break;
case "Period": case "java.time.Period":
sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().toString());\n"); sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().toString());\n");
break; break;
default: default:
...@@ -209,7 +209,7 @@ aspect Serializer { ...@@ -209,7 +209,7 @@ aspect Serializer {
if (jsonPointer) { if (jsonPointer) {
sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().jsonPointer());\n"); sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().jsonPointer());\n");
} else if (manualReferences) { } else if (manualReferences) {
sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", createRefTo" + getID() + "(" + getID() + "()));\n"); sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", " + createRefMethod + "To" + getID() + "(" + getID() + "()));\n");
} else { } else {
sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().unique$Id());\n"); sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().unique$Id());\n");
} }
...@@ -217,7 +217,7 @@ aspect Serializer { ...@@ -217,7 +217,7 @@ aspect Serializer {
if (jsonPointer) { if (jsonPointer) {
sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().jsonPointer());\n"); sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().jsonPointer());\n");
} else if (manualReferences) { } else if (manualReferences) {
sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", createRefTo" + getID() + "(" + getID() + "()));\n"); sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", " + createRefMethod + "To" + getID() + "(" + getID() + "()));\n");
} else { } else {
sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().unique$Id());\n"); sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().unique$Id());\n");
} }
...@@ -238,7 +238,7 @@ aspect Serializer { ...@@ -238,7 +238,7 @@ aspect Serializer {
if (jsonPointer) { if (jsonPointer) {
sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().jsonPointer());\n"); sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().jsonPointer());\n");
} else if (manualReferences) { } else if (manualReferences) {
sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + "createRefTo" + getID() + "(" + getID() + "()));\n"); sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + "" + createRefMethod + "To" + getID() + "(" + getID() + "()));\n");
} else { } else {
sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().unique$Id());\n"); sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().unique$Id());\n");
} }
...@@ -256,7 +256,7 @@ aspect Serializer { ...@@ -256,7 +256,7 @@ aspect Serializer {
if (jsonPointer) { if (jsonPointer) {
sb.append(ind(indent + 1) + "g.writeString(child.jsonPointer());\n"); sb.append(ind(indent + 1) + "g.writeString(child.jsonPointer());\n");
} else if (manualReferences) { } else if (manualReferences) {
sb.append(ind(indent + 1) + "g.writeString(createRefTo" + getID() + "(child));\n"); sb.append(ind(indent + 1) + "g.writeString(" + createRefMethod + "To" + getID() + "(child));\n");
}else { }else {
sb.append(ind(indent + 1) + "g.writeString(child.unique$Id());\n"); sb.append(ind(indent + 1) + "g.writeString(child.unique$Id());\n");
} }
...@@ -390,11 +390,11 @@ aspect Serializer { ...@@ -390,11 +390,11 @@ aspect Serializer {
case "String": case "String":
sb.append(ind(indent) + "element.set" + getID() + "(children.get(\"" + getID() + "\").asText());\n"); sb.append(ind(indent) + "element.set" + getID() + "(children.get(\"" + getID() + "\").asText());\n");
break; break;
case "Instant": case "java.time.Instant":
sb.append(ind(indent) + "element.set" + getID() + "(Instant.parse(children.get(\"" + getID() + "\").asText()));\n"); sb.append(ind(indent) + "element.set" + getID() + "(java.time.Instant.parse(children.get(\"" + getID() + "\").asText()));\n");
break; break;
case "Period": case "java.time.Period":
sb.append(ind(indent) + "element.set" + getID() + "(Period.parse(children.get(\"" + getID() + "\").asText()));\n"); sb.append(ind(indent) + "element.set" + getID() + "(java.time.Period.parse(children.get(\"" + getID() + "\").asText()));\n");
break; break;
default: default:
// assume that the type is an enum. there is no way of checking this here // assume that the type is an enum. there is no way of checking this here
...@@ -565,11 +565,11 @@ aspect Serializer { ...@@ -565,11 +565,11 @@ aspect Serializer {
sb.append(ind(1) + " return null;\n"); sb.append(ind(1) + " return null;\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
sb.append("\n"); sb.append("\n");
sb.append(ind(1) + "ASTNode ASTNode.globallyResolveASTNodeByUID(String uid) {\n"); sb.append(ind(1) + "ASTNode ASTNode." + globallyResolvePrefix + "ASTNodeByUID(String uid) {\n");
sb.append(ind(2) + "if (getParent() == null) {\n"); sb.append(ind(2) + "if (getParent() == null) {\n");
sb.append(ind(3) + "return uid$Map().get(uid).get();\n"); sb.append(ind(3) + "return uid$Map().get(uid).get();\n");
sb.append(ind(2) + "} else {\n"); sb.append(ind(2) + "} else {\n");
sb.append(ind(3) + "return getParent().globallyResolveASTNodeByUID(uid);\n"); sb.append(ind(3) + "return getParent()." + globallyResolvePrefix + "ASTNodeByUID(uid);\n");
sb.append(ind(2) + "}\n"); sb.append(ind(2) + "}\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
sb.append("\n"); sb.append("\n");
...@@ -616,18 +616,18 @@ aspect Serializer { ...@@ -616,18 +616,18 @@ aspect Serializer {
} }
public void OneRelationComponent.deserialize(StringBuilder sb, int indent) { public void OneRelationComponent.deserialize(StringBuilder sb, int indent) {
sb.append(ind(indent) + "element.set" + nameCapitalized() + "(" + ofTypeDecl().getID() + ".createRefDirection(relations.get(\"" + getID() + "\").asText()));\n"); sb.append(ind(indent) + "element.set" + nameCapitalized() + "(" + ofTypeDecl().getID() + "." + createRefMethod + "Direction(relations.get(\"" + getID() + "\").asText()));\n");
sb.append(ind(indent - 1) + "} else {\n"); sb.append(ind(indent - 1) + "} else {\n");
sb.append(ind(indent) + "throw new DeserializationException(\"deserializer of missing mandatory relation child " + getID() + "\");\n"); sb.append(ind(indent) + "throw new DeserializationException(\"deserializer of missing mandatory relation child " + getID() + "\");\n");
} }
public void OptionalRelationComponent.deserialize(StringBuilder sb, int indent) { public void OptionalRelationComponent.deserialize(StringBuilder sb, int indent) {
sb.append(ind(indent) + "element.set" + nameCapitalized() + "(" + ofTypeDecl().getID() + ".createRefDirection(relations.get(\"" + getID() + "\").asText()));\n"); sb.append(ind(indent) + "element.set" + nameCapitalized() + "(" + ofTypeDecl().getID() + "." + createRefMethod + "Direction(relations.get(\"" + getID() + "\").asText()));\n");
} }
public void ManyRelationComponent.deserialize(StringBuilder sb, int indent) { public void ManyRelationComponent.deserialize(StringBuilder sb, int indent) {
sb.append(ind(indent) + "for (" + jsonNodeType + " child : relations.get(\"" + getID() + "\")) {\n"); sb.append(ind(indent) + "for (" + jsonNodeType + " child : relations.get(\"" + getID() + "\")) {\n");
sb.append(ind(indent + 1) + "element.add" + (useJastAddNames?"":"To") + nameCapitalized() + "(" + ofTypeDecl().getID() + ".createRefDirection(child.asText()));\n"); sb.append(ind(indent + 1) + "element.add" + (useJastAddNames?"":"To") + nameCapitalized() + "(" + ofTypeDecl().getID() + "." + createRefMethod + "Direction(child.asText()));\n");
sb.append(ind(indent) + "}\n"); sb.append(ind(indent) + "}\n");
} }
} }
import java.util.ArrayList;
aspect NTA {
// E ::= ... /<NT1>/ ... ;
syn String E.getNT1() = "";
// E ::= ... /<NT2:String>/ ... ;
syn String E.getNT2() = "";
// E ::= ... /<NT3:boolean>/ ... ;
syn boolean E.getNT3() = false;
// E ::= ... /<NT4:int>/ ... ;
syn int E.getNT4() = 1;
// E ::= ... /<NT5:float>/ ... ;
syn float E.getNT5() = 1.0f;
// E ::= ... /<NT6:double>/ ... ;
syn double E.getNT6() = 1.0d;
// E ::= ... /<NT7:long>/ ... ;
syn long E.getNT7() = 1l;
// E ::= ... /[NT8:A]/ ... ;
syn Opt<A> E.getNT8Opt() = new Opt<A>();
// E ::= ... /[A]/ ... ;
syn Opt<A> E.getAOpt() = new Opt<A>();
// E ::= ... /NT10:A*/ ... ;
syn List<A> E.getNT10List() = new List<A>();
// E ::= ... /B*/ ... ;
syn List<B> E.getBList() = new List<B>();
}
...@@ -51,9 +51,10 @@ D ::= SingleA:A ListOfA:A* [OptionalA:A] /NTAA:A/ ; ...@@ -51,9 +51,10 @@ D ::= SingleA:A ListOfA:A* [OptionalA:A] /NTAA:A/ ;
// production with tokens, nonterminal-tokens, multi-line // production with tokens, nonterminal-tokens, multi-line
E ::= <T1> <T2:String> <T3:boolean> <T4:int> <T5:float> <T6:double> <T7:long> E ::= <T1> <T2:String> <T3:boolean> <T4:int> <T5:float> <T6:double> <T7:long>
<T8:java.lang.Object> <T9:ArrayList<String>> <T10:java.util.ArrayList<java.lang.String>> <T8:java.lang.Object> <T9:ArrayList<String>> <T10:java.util.ArrayList<java.lang.String>>
/<NT2:String>/ /<NT3:boolean>/ /<NT4:int>/ /<NT5:float>/ /<NT6:double>/ /<NT7:long>/ ; /<NT1>/ /<NT2:String>/ /<NT3:boolean>/ /<NT4:int>/ /<NT5:float>/ /<NT6:double>/ /<NT7:long>/
/[NT8:A]/ /[A]/ /NT10:A*/ /B*/;
rel E.NT1 -> A ; rel E.R1 -> A ;
// inheritance and empty // inheritance and empty
F : A ; F : A ;
......
...@@ -13,8 +13,8 @@ C:NamedElement ::= D1:D [D2:D] D3:D* ...@@ -13,8 +13,8 @@ C:NamedElement ::= D1:D [D2:D] D3:D*
<C1:char> <C2:Character> <C1:char> <C2:Character>
<T1:String> <T1:String>
<T2> <T2>
<N:Instant> <N:java.time.Instant>
<P:Period> <P:java.time.Period>
<Day:Weekday>; <Day:Weekday>;
D:NamedElement; D:NamedElement;
......
...@@ -13,8 +13,8 @@ C:NamedElement ::= D1:D [D2:D] D3:D* ...@@ -13,8 +13,8 @@ C:NamedElement ::= D1:D [D2:D] D3:D*
<C1:char> <C2:Character> <C1:char> <C2:Character>
<T1:String> <T1:String>
<T2> <T2>
<N:Instant> <N:java.time.Instant>
<P:Period> <P:java.time.Period>
<Day:Weekday>; <Day:Weekday>;
D:NamedElement; D:NamedElement;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment