GitLab update scheduled for Friday, January 21th between 08:15 and 08:45 CET. If unpleasant, please contact René or Martin.

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
Pipeline #6294 passed with stages
in 4 minutes and 5 seconds
...@@ -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();
} }
} }
\ No newline at end of file
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();
......
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,50 +13,49 @@ aspect BackendDirectedAPI { ...@@ -30,50 +13,49 @@ 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");
sb.append(ind(3) + "if (changed) {\n"); sb.append(ind(3) + "if (changed) {\n");
sb.append(ind(4) + "set" + getImplAttributeName() + "(l);\n"); sb.append(ind(4) + "set" + getImplAttributeName() + "(l);\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) + "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)";