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 {
testCompile 'org.assertj:assertj-core:3.12.1'
compile 'com.fasterxml.jackson.core:jackson-core: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'
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'
......@@ -159,7 +160,7 @@ task firstRelationsRun(type: RelastTest) {
grammarName = 'src/test/jastadd/relations/Relations'
useJastAddNames = true
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) {
......@@ -185,7 +186,7 @@ task compileDefaultNamesTest(type: RelastTest) {
relastFiles 'src/test/jastadd/relations/Relations.relast'
grammarName = 'src/test/jastadd/relations/Relations3'
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) {
......@@ -253,6 +254,7 @@ task compileListNamesTest(type: RelastTest) {
grammarName = 'src/test/jastadd/listnames/ListNames'
useJastAddNames = true
jastAddList = 'ListyMcListface'
listClass = 'java.util.LinkedList'
packageName = 'listnames.ast'
moreInputFiles 'src/test/jastadd/Utils.jadd'
}
......
......@@ -36,13 +36,13 @@ aspect ComponentAnalysis {
eq Program.getChild().enclosingTypeDecl() = null;
//--- otherSide ---
inh RelationComponent RelationComponent.otherSide();
eq Relation.getLeft().otherSide() = getRight();
eq Relation.getRight().otherSide() = getLeft();
eq Program.getChild().otherSide() = null;
inh RelationComponent RelationComponent.opposite();
eq Relation.getLeft().opposite() = getRight();
eq Relation.getRight().opposite() = getLeft();
eq Program.getChild().opposite() = null;
//--- ofTypeDecl ---
syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().getTypeUse().decl();
syn TypeDecl RelationComponent.ofTypeDecl() = opposite().getTypeUse().decl();
//--- isAlreadyDeclared ---
/**
......@@ -141,7 +141,7 @@ aspect ComponentAnalysis {
//--- relationComponentsTransitive ---
syn Collection<RelationComponent> TypeDecl.relationComponentsTransitive() {
ArrayList<RelationComponent> list = new ArrayList<>();
Collection<RelationComponent> list = new ArrayList<>();
if (hasSuper() && getSuper().decl() != null) {
list.addAll(getSuper().decl().relationComponentsTransitive());
}
......@@ -170,10 +170,14 @@ aspect ComponentAnalysis {
//--- isList ---
syn boolean Component.isList() = false;
eq ListComponent.isList() = true;
eq NTAListComponent.isList() = true;
eq ManyRelationComponent.isList() = true;
//--- isOpt ---
syn boolean Component.isOpt() = false;
eq OptComponent.isOpt() = true;
eq NTAOptComponent.isOpt() = true;
eq OptionalRelationComponent.isOpt() = true;
//--- isNullable ---
syn boolean Component.isNullable() = false;
......@@ -188,7 +192,7 @@ aspect InstanceSupplier {
//--- subTypeDecls ---
syn Collection<TypeDecl> TypeDecl.subTypeDecls() {
java.util.List<TypeDecl> subDecls = new ArrayList();
Collection<TypeDecl> subDecls = new ArrayList();
for (TypeDecl decl : program().getTypeDeclList()) {
if (decl.hasSuper() && decl.getSuper().getID().equals(getID())) {
subDecls.add(decl);
......@@ -248,10 +252,6 @@ aspect Constructors {
aspect Utils {
//--- isMany ---
syn boolean RelationComponent.isMany() = false;
eq ManyRelationComponent.isMany() = true;
//--- toString ---
public String SimpleTypeUse.toString() {
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 {
private static final String ASTNode.DUMP_TREE_INDENT = " ";
public String ASTNode.dumpTree() {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
dumpTree(new PrintStream(bytes));
java.io.ByteArrayOutputStream bytes = new java.io.ByteArrayOutputStream();
dumpTree(new java.io.PrintStream(bytes));
return bytes.toString();
}
public void ASTNode.dumpTree(PrintStream out) {
public void ASTNode.dumpTree(java.io.PrintStream out) {
dumpTree(out, "");
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(getTokens());
String extra = extraDumpInfo();
......@@ -40,26 +33,21 @@ aspect DumpTree {
public String ASTNode.extraDumpInfo() { return ""; }
public String ASTNode.getTokens() {
java.util.TreeSet<java.lang.reflect.Method> methods = new java.util.TreeSet<>(
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());
}
});
java.util.TreeSet<java.lang.reflect.Method> methods = new java.util.TreeSet<>(Comparator.comparing(java.lang.reflect.Method::getName));
methods.addAll(java.util.Arrays.asList(getClass().getMethods()));
String result = "";
StringBuilder result = new StringBuilder();
for (java.lang.reflect.Method method : methods) {
ASTNodeAnnotation.Token token = method.getAnnotation(ASTNodeAnnotation.Token.class);
if (token != null) {
try {
result += String.format(" %s=\"%s\"", token.name(), method.invoke(this));
} catch (IllegalAccessException ignored) {
} catch (InvocationTargetException ignored) {
result.append(String.format(" %s=\"%s\"", token.name(), method.invoke(this)));
} catch (IllegalAccessException ignored) {
} catch (java.lang.reflect.InvocationTargetException ignored) {
}
}
}
return result;
return result.toString();
}
}
\ No newline at end of file
}
aspect BackendAPI {
public void Relation.generateAPI(StringBuilder sb) {
sb.append(ind(1) + "// " + prettyPrint() + "\n");
getDirection().generateAPI(sb);
sb.append(ind(1) + "// api for " + prettyPrint() + "\n");
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");
}
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 RelationComponent.relation();
eq Relation.getChild().relation() = this;
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() {
return name().substring(0,1).toUpperCase() + name().substring(1);
}
......
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.jastAddOptType = "Opt";
public static boolean ASTNode.resolverHelper = false;
public static boolean ASTNode.serializer = false;
......@@ -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) {
if (getAbstract()) {
sb.append("abstract ");
......@@ -119,7 +80,7 @@ aspect BackendAbstractGrammar {
return "<" + getImplAttributeName() + ":" + ofTypeDecl() + ">";
}
public String ManyRelationComponent.generateAbstractGrammar() {
return "<" + getImplAttributeName() + ":" + ASTNode.listClass + "<" + ofTypeDecl() + ">>";
return "<" + getImplAttributeName() + ":" + ASTNode.listInterface + "<" + ofTypeDecl() + ">>";
}
public String RelationComponent.getImplAttributeName() {
......@@ -128,11 +89,11 @@ aspect BackendAbstractGrammar {
public String RelationComponent.getImplAttributeField() {
// 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() {
// 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 {
}
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");
for (TypeDecl td: getTypeDecls()) {
......@@ -53,7 +49,7 @@ aspect BackendAspect {
return ASTNode.jastAddListType + "<" + getTypeUse() + "> " + getID();
}
public String OptComponent.constructorParameter() {
return "Opt<" + getTypeUse() + "> " + getID();
return ASTNode.jastAddOptType + "<" + getTypeUse() + "> " + getID();
}
public String Component.constructorSetMethod() {
return "set" + getID();
......
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 OneRelationComponent.generateDirectedAPI(StringBuilder sb) {
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);
public void RelationComponent.generateDirectedZeroOneAPI(StringBuilder sb) {
String setMethodDecl = getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized() + "(" + ofTypeDecl() + " o)";
// Set
sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl());
sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
if (!optional) {
sb.append(ind(1) + "public " + setMethodDecl + " {\n");
if (!isOpt()) {
sb.append(ind(2) + "assertNotNull(o);\n");
}
sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n");
......@@ -30,50 +13,49 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n");
}
public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) {
public void RelationComponent.generateDirectedManyAPI(StringBuilder sb) {
// Get
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
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
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(1) + "}\n");
// getXList
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl());
sb.append(".get" + nameCapitalized() + "List() {\n");
sb.append(ind(1) + "public " + getMethodDecl2 + " {\n");
} 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
if (resolverHelper | serializer) {
sb.append(ind(2) + "if (l != null) {\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(4) + ofTypeDecl() + " element = l.get(i);\n");
sb.append(ind(4) + "if (element.is$Unresolved()) {\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) + "l.set(i, resolvedElement);\n");
sb.append(ind(4) + "}\n");
sb.append(ind(3) + "}\n");
sb.append(ind(3) + "if (changed) {\n");
sb.append(ind(4) + "set" + getImplAttributeName() + "(l);\n");
sb.append(ind(3) + "}\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(4) + ofTypeDecl() + " element = l.get(i);\n");
sb.append(ind(4) + "if (element." + isUnresolvedMethod + "()) {\n");
sb.append(ind(5) + "changed = true;\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(4) + "}\n");
sb.append(ind(3) + "}\n");
sb.append(ind(3) + "if (changed) {\n");
sb.append(ind(4) + "set" + getImplAttributeName() + "(l);\n");
sb.append(ind(3) + "}\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");
// Add
sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
if (!useJastAddNames) {
sb.append("To");
}
sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
String addMethodDecl1 = "void " + getTypeUse().decl() + ".add" + (useJastAddNames ? "" : "To") + nameCapitalized() + "(" + ofTypeDecl() + " o)";
sb.append(ind(1) + "public " + addMethodDecl1 + " {\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(3) + "list = new " + ASTNode.listClass + "<>();\n");
sb.append(ind(2) + "}\n");
......@@ -82,13 +64,10 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n");
// Insert / add at specific position
sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
if (!useJastAddNames) {
sb.append("To");
}
sb.append(nameCapitalized() + "(int index, " + ofTypeDecl() + " o) {\n");
String addMethodDecl2 = "void " + getTypeUse().decl() + ".add" + (useJastAddNames ? "" : "To") + nameCapitalized() + "(int index, " + ofTypeDecl() + " o)";
sb.append(ind(1) + "public " + addMethodDecl2 + " {\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(3) + "list = new " + ASTNode.listClass + "<>();\n");
sb.append(ind(2) + "}\n");
......@@ -97,57 +76,13 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n");
// Remove
sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove");
if (!useJastAddNames) {
sb.append("From");
}
sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
String removeMethodDecl = "void " + getTypeUse().decl() + ".remove" + (useJastAddNames ? "" : "From") + nameCapitalized() + "(" + ofTypeDecl() + " o)";
sb.append(ind(1) + "public " + removeMethodDecl + " {\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(3) + "set" + getImplAttributeName() + "(list);\n");
sb.append(ind(2) + "}\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 {
sb.append(ind(1) + "public java.util.List<Pair<ASTNode, String>> "
+ "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) + "return list;\n");
sb.append(ind(1) + "}\n");
......
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() {
StringBuilder sb = new StringBuilder();
generateRewriteToSuperTypeStub(sb);
......@@ -48,8 +104,8 @@ aspect NameResolutionHelper {
public void Program.generateGenericRefCreation(StringBuilder sb) {
sb.append(ind(1) + "// generic reference creation\n");
sb.append(ind(1) + "syn String ASTNode.createReference();\n");
sb.append(ind(1) + "eq ASTNode.createReference() {\n");
sb.append(ind(1) + "syn String ASTNode." + createReferenceMethod + "();\n");
sb.append(ind(1) + "eq ASTNode." + createReferenceMethod + "() {\n");
sb.append(ind(2) + "throw new RuntimeException(\"Generic reference creation not implemented.\");\n");