Commit 8e910ed0 authored by René Schöne's avatar René Schöne
Browse files

Null nodes have separate ids, and working ordered output.

- grammar order was not taken into account so far, but is now, see #7
- whenever a DumpNode is created, a counter is increased, so all null nodes get different ids, see #10
- some relations seem to point to null after this change, maybe resulting in new bugs, let's see
parent 5d9c8485
Pipeline #12771 passed with stages
in 3 minutes and 20 seconds
......@@ -35,7 +35,7 @@ DumpListRelation : DumpRelation ::= InnerDumpNode* ;
// type of NTA
InvisiblePath ::= InnerDumpNode* ;
ClassAnalysisResult ::= AnalysedMethod* ;
ClassAnalysisResult ::= ContainmentMethod:AnalysedMethod* OtherMethod:AnalysedMethod* ;
abstract AnalysedMethod ::= <Method:java.lang.reflect.Method> <Name> ;
abstract SingleChildMethod : AnalysedMethod ;
......
aspect Navigation {
/** Tests if TokenMethod is a IntrinsicTokenMethod.
* @return 'true' if this is a IntrinsicTokenMethod, otherwise 'false'
*/
syn boolean TokenMethod.isIntrinsicTokenMethod() = false;
eq IntrinsicTokenMethod.isIntrinsicTokenMethod() = true;
/** Tests if TokenMethod is a AttributeMethod.
* @return 'true' if this is a AttributeMethod, otherwise 'false'
*/
syn boolean TokenMethod.isAttributeMethod() = false;
eq AttributeMethod.isAttributeMethod() = true;
/** Tests if AnalysedMethod is a SingleChildMethod.
* @return 'true' if this is a SingleChildMethod, otherwise 'false'
*/
syn boolean AnalysedMethod.isSingleChildMethod() = false;
eq SingleChildMethod.isSingleChildMethod() = true;
/** Tests if AnalysedMethod is a ListChildMethod.
* @return 'true' if this is a ListChildMethod, otherwise 'false'
*/
syn boolean AnalysedMethod.isListChildMethod() = false;
eq ListChildMethod.isListChildMethod() = true;
/** Tests if AnalysedMethod is a SingleRelationMethod.
* @return 'true' if this is a SingleRelationMethod, otherwise 'false'
*/
syn boolean AnalysedMethod.isSingleRelationMethod() = false;
eq SingleRelationMethod.isSingleRelationMethod() = true;
/** Tests if AnalysedMethod is a ListRelationMethod.
* @return 'true' if this is a ListRelationMethod, otherwise 'false'
*/
syn boolean AnalysedMethod.isListRelationMethod() = false;
eq ListRelationMethod.isListRelationMethod() = true;
/** Tests if AnalysedMethod is a TokenMethod.
* @return 'true' if this is a TokenMethod, otherwise 'false'
*/
syn boolean AnalysedMethod.isTokenMethod() = false;
eq TokenMethod.isTokenMethod() = true;
/** Tests if DumpRelation is a DumpNormalRelation.
* @return 'true' if this is a DumpNormalRelation, otherwise 'false'
*/
syn boolean DumpRelation.isDumpNormalRelation() = false;
eq DumpNormalRelation.isDumpNormalRelation() = true;
/** Tests if DumpRelation is a DumpListRelation.
* @return 'true' if this is a DumpListRelation, otherwise 'false'
*/
syn boolean DumpRelation.isDumpListRelation() = false;
eq DumpListRelation.isDumpListRelation() = true;
/** Tests if DumpChildNode is a DumpNormalChildNode.
* @return 'true' if this is a DumpNormalChildNode, otherwise 'false'
*/
syn boolean DumpChildNode.isDumpNormalChildNode() = false;
eq DumpNormalChildNode.isDumpNormalChildNode() = true;
/** Tests if DumpChildNode is a DumpListChildNode.
* @return 'true' if this is a DumpListChildNode, otherwise 'false'
*/
syn boolean DumpChildNode.isDumpListChildNode() = false;
eq DumpListChildNode.isDumpListChildNode() = true;
/** Tests if ListChildMethod is a NormalListChildMethod.
* @return 'true' if this is a NormalListChildMethod, otherwise 'false'
*/
syn boolean ListChildMethod.isNormalListChildMethod() = false;
eq NormalListChildMethod.isNormalListChildMethod() = true;
/** Tests if ListChildMethod is a NTAListChildMethod.
* @return 'true' if this is a NTAListChildMethod, otherwise 'false'
*/
syn boolean ListChildMethod.isNTAListChildMethod() = false;
eq NTAListChildMethod.isNTAListChildMethod() = true;
/** Tests if SingleChildMethod is a NormalSingleChildMethod.
* @return 'true' if this is a NormalSingleChildMethod, otherwise 'false'
*/
syn boolean SingleChildMethod.isNormalSingleChildMethod() = false;
eq NormalSingleChildMethod.isNormalSingleChildMethod() = true;
/** Tests if SingleChildMethod is a NTASingleChildMethod.
* @return 'true' if this is a NTASingleChildMethod, otherwise 'false'
*/
syn boolean SingleChildMethod.isNTASingleChildMethod() = false;
eq NTASingleChildMethod.isNTASingleChildMethod() = true;
/** Tests if DumpToken is a DumpReferenceToken.
* @return 'true' if this is a DumpReferenceToken, otherwise 'false'
*/
syn boolean DumpToken.isDumpReferenceToken() = false;
eq DumpReferenceToken.isDumpReferenceToken() = true;
/** Tests if DumpToken is a DumpValueToken.
* @return 'true' if this is a DumpValueToken, otherwise 'false'
*/
syn boolean DumpToken.isDumpValueToken() = false;
eq DumpValueToken.isDumpValueToken() = true;
/** casts a TokenMethod into a IntrinsicTokenMethod if possible.
* @return 'this' cast to a IntrinsicTokenMethod or 'null'
*/
syn IntrinsicTokenMethod TokenMethod.asIntrinsicTokenMethod();
eq TokenMethod.asIntrinsicTokenMethod() = null;
eq IntrinsicTokenMethod.asIntrinsicTokenMethod() = this;
/** casts a TokenMethod into a AttributeMethod if possible.
* @return 'this' cast to a AttributeMethod or 'null'
*/
syn AttributeMethod TokenMethod.asAttributeMethod();
eq TokenMethod.asAttributeMethod() = null;
eq AttributeMethod.asAttributeMethod() = this;
/** casts a AnalysedMethod into a SingleChildMethod if possible.
* @return 'this' cast to a SingleChildMethod or 'null'
*/
syn SingleChildMethod AnalysedMethod.asSingleChildMethod();
eq AnalysedMethod.asSingleChildMethod() = null;
eq SingleChildMethod.asSingleChildMethod() = this;
/** casts a AnalysedMethod into a ListChildMethod if possible.
* @return 'this' cast to a ListChildMethod or 'null'
*/
syn ListChildMethod AnalysedMethod.asListChildMethod();
eq AnalysedMethod.asListChildMethod() = null;
eq ListChildMethod.asListChildMethod() = this;
/** casts a AnalysedMethod into a SingleRelationMethod if possible.
* @return 'this' cast to a SingleRelationMethod or 'null'
*/
syn SingleRelationMethod AnalysedMethod.asSingleRelationMethod();
eq AnalysedMethod.asSingleRelationMethod() = null;
eq SingleRelationMethod.asSingleRelationMethod() = this;
/** casts a AnalysedMethod into a ListRelationMethod if possible.
* @return 'this' cast to a ListRelationMethod or 'null'
*/
syn ListRelationMethod AnalysedMethod.asListRelationMethod();
eq AnalysedMethod.asListRelationMethod() = null;
eq ListRelationMethod.asListRelationMethod() = this;
/** casts a AnalysedMethod into a TokenMethod if possible.
* @return 'this' cast to a TokenMethod or 'null'
*/
syn TokenMethod AnalysedMethod.asTokenMethod();
eq AnalysedMethod.asTokenMethod() = null;
eq TokenMethod.asTokenMethod() = this;
/** casts a DumpRelation into a DumpNormalRelation if possible.
* @return 'this' cast to a DumpNormalRelation or 'null'
*/
syn DumpNormalRelation DumpRelation.asDumpNormalRelation();
eq DumpRelation.asDumpNormalRelation() = null;
eq DumpNormalRelation.asDumpNormalRelation() = this;
/** casts a DumpRelation into a DumpListRelation if possible.
* @return 'this' cast to a DumpListRelation or 'null'
*/
syn DumpListRelation DumpRelation.asDumpListRelation();
eq DumpRelation.asDumpListRelation() = null;
eq DumpListRelation.asDumpListRelation() = this;
/** casts a DumpChildNode into a DumpNormalChildNode if possible.
* @return 'this' cast to a DumpNormalChildNode or 'null'
*/
syn DumpNormalChildNode DumpChildNode.asDumpNormalChildNode();
eq DumpChildNode.asDumpNormalChildNode() = null;
eq DumpNormalChildNode.asDumpNormalChildNode() = this;
/** casts a DumpChildNode into a DumpListChildNode if possible.
* @return 'this' cast to a DumpListChildNode or 'null'
*/
syn DumpListChildNode DumpChildNode.asDumpListChildNode();
eq DumpChildNode.asDumpListChildNode() = null;
eq DumpListChildNode.asDumpListChildNode() = this;
/** casts a ListChildMethod into a NormalListChildMethod if possible.
* @return 'this' cast to a NormalListChildMethod or 'null'
*/
syn NormalListChildMethod ListChildMethod.asNormalListChildMethod();
eq ListChildMethod.asNormalListChildMethod() = null;
eq NormalListChildMethod.asNormalListChildMethod() = this;
/** casts a ListChildMethod into a NTAListChildMethod if possible.
* @return 'this' cast to a NTAListChildMethod or 'null'
*/
syn NTAListChildMethod ListChildMethod.asNTAListChildMethod();
eq ListChildMethod.asNTAListChildMethod() = null;
eq NTAListChildMethod.asNTAListChildMethod() = this;
/** casts a SingleChildMethod into a NormalSingleChildMethod if possible.
* @return 'this' cast to a NormalSingleChildMethod or 'null'
*/
syn NormalSingleChildMethod SingleChildMethod.asNormalSingleChildMethod();
eq SingleChildMethod.asNormalSingleChildMethod() = null;
eq NormalSingleChildMethod.asNormalSingleChildMethod() = this;
/** casts a SingleChildMethod into a NTASingleChildMethod if possible.
* @return 'this' cast to a NTASingleChildMethod or 'null'
*/
syn NTASingleChildMethod SingleChildMethod.asNTASingleChildMethod();
eq SingleChildMethod.asNTASingleChildMethod() = null;
eq NTASingleChildMethod.asNTASingleChildMethod() = this;
/** casts a DumpToken into a DumpReferenceToken if possible.
* @return 'this' cast to a DumpReferenceToken or 'null'
*/
syn DumpReferenceToken DumpToken.asDumpReferenceToken();
eq DumpToken.asDumpReferenceToken() = null;
eq DumpReferenceToken.asDumpReferenceToken() = this;
/** casts a DumpToken into a DumpValueToken if possible.
* @return 'this' cast to a DumpValueToken or 'null'
*/
syn DumpValueToken DumpToken.asDumpValueToken();
eq DumpToken.asDumpValueToken() = null;
eq DumpValueToken.asDumpValueToken() = this;
}
......@@ -52,7 +52,7 @@ aspect GenerationBackend {
} else {
node = new DumpNode();
node.setObject(obj);
node.setName("node" + tti.transformed.size());
node.setName("node" + (tti.nodeCounter++));
tti.transformed.put(obj, node);
this.addDumpNode(node);
}
......@@ -73,85 +73,119 @@ aspect GenerationBackend {
return node;
}
final ClassAnalysisResult car = analyzeClass(obj.getClass());
// -- singleChild --
for (SingleChildMethod singleChildMethod : car.singleChildMethods()) {
Object target = singleChildMethod.getMethod().invoke(obj);
String childName = singleChildMethod.getName();
DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName)), !getBuildConfig().getExcludeNullNodes());
if (targetNode != null) {
DumpNormalChildNode normalChild = new DumpNormalChildNode();
normalChild.setName(childName);
normalChild.setDumpNode(targetNode);
normalChild.setComputed(singleChildMethod.isNTASingleChildMethod());
node.addDumpChildNode(normalChild);
}
}
// -- listChild --
for (ListChildMethod listChildMethod : car.listChildMethods()) {
Iterable<?> targetList = (Iterable<?>) listChildMethod.getMethod().invoke(obj);
DumpListChildNode listChild = new DumpListChildNode();
listChild.setComputed(listChildMethod.isNTAListChildMethod());
String childName = listChildMethod.getName();
boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName);
listChild.setName(childName);
for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble));
if (target != null && targetNode != null) {
listChild.addInnerDumpNode(new InnerDumpNode(targetNode));
for (AnalysedMethod containmentMethod : car.getContainmentMethodList()) {
if (containmentMethod.isSingleChildMethod()) {
// -- singleChild --
Object target = containmentMethod.getMethod().invoke(obj);
String childName = containmentMethod.getName();
DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName)), !getBuildConfig().getExcludeNullNodes());
if (targetNode != null) {
DumpNormalChildNode normalChild = new DumpNormalChildNode();
normalChild.setName(childName);
normalChild.setDumpNode(targetNode);
normalChild.setComputed(false);
node.addDumpChildNode(normalChild);
}
}
if (listChild.getNumInnerDumpNode() > 0) {
node.addDumpChildNode(listChild);
}
}
// -- singleRelation --
for (SingleRelationMethod singleRelationMethod : car.singleRelationMethods()) {
Object target = singleRelationMethod.getMethod().invoke(obj);
DumpNode targetNode = transform(tti, target, Source.RELATION);
if (target != null && targetNode != null) {
DumpNormalRelation normalRelation = new DumpNormalRelation();
normalRelation.setName(singleRelationMethod.getName());
normalRelation.setDumpNode(targetNode);
node.addDumpRelation(normalRelation);
} else if (containmentMethod.isListChildMethod()) {
// -- listChild --
Iterable<?> targetList = (Iterable<?>) containmentMethod.getMethod().invoke(obj);
DumpListChildNode listChild = new DumpListChildNode();
listChild.setComputed(false);
String childName = containmentMethod.getName();
boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName);
listChild.setName(childName);
for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble));
if (target != null && targetNode != null) {
listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode));
}
}
if (listChild.getNumInnerDumpNode() > 0) {
node.addDumpChildNode(listChild);
}
} else {
throw new RuntimeException("Unknown containment method type " + containmentMethod);
}
}
// -- listRelation --
for (ListRelationMethod listRelationMethod : car.listRelationMethods()) {
Iterable<?> targetList = (Iterable<?>) listRelationMethod.getMethod().invoke(obj);
DumpListRelation listRelation = new DumpListRelation();
listRelation.setName(listRelationMethod.getName());
for (Object target : targetList) {
for (AnalysedMethod otherMethod : car.getOtherMethodList()) {
if (otherMethod.isSingleChildMethod()) {
// -- singleChild --
Object target = otherMethod.getMethod().invoke(obj);
String childName = otherMethod.getName();
DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName)), !getBuildConfig().getExcludeNullNodes());
if (targetNode != null) {
DumpNormalChildNode normalChild = new DumpNormalChildNode();
normalChild.setName(childName);
normalChild.setDumpNode(targetNode);
normalChild.setComputed(otherMethod.asSingleChildMethod().isNTASingleChildMethod());
node.addDumpChildNode(normalChild);
}
} else if (otherMethod.isListChildMethod()) {
// -- listChild --
Iterable<?> targetList = (Iterable<?>) otherMethod.getMethod().invoke(obj);
DumpListChildNode listChild = new DumpListChildNode();
listChild.setComputed(otherMethod.asListChildMethod().isNTAListChildMethod());
String childName = otherMethod.getName();
boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName);
listChild.setName(childName);
for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble));
if (target != null && targetNode != null) {
listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode));
}
}
if (listChild.getNumInnerDumpNode() > 0) {
node.addDumpChildNode(listChild);
}
} else if (otherMethod.isSingleRelationMethod()) {
// -- singleRelation --
Object target = otherMethod.getMethod().invoke(obj);
DumpNode targetNode = transform(tti, target, Source.RELATION);
if (target != null && targetNode != null) {
listRelation.addInnerDumpNode(new InnerDumpNode(targetNode));
DumpNormalRelation normalRelation = new DumpNormalRelation();
normalRelation.setName(otherMethod.getName());
normalRelation.setDumpNode(targetNode);
node.addDumpRelation(normalRelation);
}
}
if (listRelation.getNumInnerDumpNode() > 0) {
node.addDumpRelation(listRelation);
}
}
// -- token --
for (TokenMethod tokenMethod : car.tokenMethods()) {
Object target = tokenMethod.getMethod().invoke(obj);
if (target != null) {
DumpNode targetNode = transform(tti, target, Source.RELATION);
DumpToken token = null;
// TODO check, if Iterable.isAssignableFrom(target.getClass()).
// if so, check isAstNode for first non-null to add DumpReferenceToken's, otherwise DumpValueToken's
if (targetNode != null && targetNode.isAstNode()) {
token = new DumpReferenceToken().setValue(targetNode);
} else {
if (target != null && (getBuildConfig().getIncludeEmptyString() || !target.toString().isEmpty())) {
DumpValueToken valueToken = new DumpValueToken();
valueToken.setValue(target);
token = valueToken;
} else if (otherMethod.isListRelationMethod()) {
// -- listRelation --
Iterable<?> targetList = (Iterable<?>) otherMethod.getMethod().invoke(obj);
DumpListRelation listRelation = new DumpListRelation();
listRelation.setName(otherMethod.getName());
for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, Source.RELATION);
if (target != null && targetNode != null) {
listRelation.addInnerDumpNode(new InnerDumpNode(targetNode));
}
}
if (token != null) {
token.setName(tokenMethod.getName());
token.setComputed(tokenMethod.isAttributeMethod());
node.addDumpToken(token);
if (listRelation.getNumInnerDumpNode() > 0) {
node.addDumpRelation(listRelation);
}
} else if (otherMethod.isTokenMethod()) {
// -- token --
Object target = otherMethod.getMethod().invoke(obj);
if (target != null) {
DumpNode targetNode = transform(tti, target, Source.RELATION);
DumpToken token = null;
// TODO check, if Iterable.isAssignableFrom(target.getClass()).
// if so, check isAstNode for first non-null to add DumpReferenceToken's, otherwise DumpValueToken's
if (targetNode != null && targetNode.isAstNode()) {
token = new DumpReferenceToken().setValue(targetNode);
} else {
if (target != null && (getBuildConfig().getIncludeEmptyString() || !target.toString().isEmpty())) {
DumpValueToken valueToken = new DumpValueToken();
valueToken.setValue(target);
token = valueToken;
}
}
if (token != null) {
token.setName(otherMethod.getName());
token.setComputed(otherMethod.asTokenMethod().isAttributeMethod());
node.addDumpToken(token);
}
}
} else {
throw new RuntimeException("Unknown other method type " + otherMethod);
}
}
return node;
......@@ -172,39 +206,43 @@ aspect GenerationBackend {
syn nta ClassAnalysisResult DumpAst.analyzeClass(java.lang.Class<?> clazz) {
ClassAnalysisResult result = new ClassAnalysisResult();
String clazzName = clazz.getSimpleName();
java.util.List<String> targetOrder = targetOrder(clazz);
for (java.lang.reflect.Method method : clazz.getMethods()) {
for (java.lang.annotation.Annotation annotation : method.getAnnotations()) {
String canonicalName = annotation.annotationType().getCanonicalName();
if (canonicalName.startsWith(astNodeAnnotationPrefix())) {
String simpleName = annotation.annotationType().getSimpleName();
String contextNameToAdd = null;
AnalysedMethod containmentMethodToAdd = null;
switch (simpleName) {
case "Child":
String singleChildName = invokeName(annotation);
contextNameToAdd = invokeName(annotation);
NormalSingleChildMethod singleChildMethod = new NormalSingleChildMethod();
singleChildMethod.setMethod(method);
singleChildMethod.setName(singleChildName);
result.addAnalysedMethod(singleChildMethod);
singleChildMethod.setName(contextNameToAdd);
containmentMethodToAdd = singleChildMethod;
break;
case "OptChild":
String optChildName = invokeName(annotation);
contextNameToAdd = invokeName(annotation);
try {
// the annotated method is "get???Opt", but we want "get???"
java.lang.reflect.Method realGetter = clazz.getMethod("get" + optChildName);
java.lang.reflect.Method realGetter = clazz.getMethod("get" + contextNameToAdd);
NormalSingleChildMethod normalSingleChildMethod = new NormalSingleChildMethod();
normalSingleChildMethod.setMethod(realGetter);
normalSingleChildMethod.setName(optChildName);
result.addAnalysedMethod(normalSingleChildMethod);
normalSingleChildMethod.setName(contextNameToAdd);
containmentMethodToAdd = normalSingleChildMethod;
} catch (NoSuchMethodException e) {
System.err.println("Could not find getter for Opt-child " + optChildName + " in " + clazzName);
System.err.println("Could not find getter for Opt-child " + contextNameToAdd + " in " + clazzName);
throw new RuntimeException(e);
}
break;
case "ListChild":
String listChildName = invokeName(annotation);
contextNameToAdd = listChildName;
NormalListChildMethod normalListChildMethod = new NormalListChildMethod();
normalListChildMethod.setMethod(method);
normalListChildMethod.setName(listChildName);
result.addAnalysedMethod(normalListChildMethod);
containmentMethodToAdd = normalListChildMethod;
break;
case "Token":
// heuristic for relations
......@@ -218,7 +256,7 @@ aspect GenerationBackend {
SingleRelationMethod singleRelationMethod = new SingleRelationMethod();
singleRelationMethod.setMethod(relationMethod);
singleRelationMethod.setName(relationName);
result.addAnalysedMethod(singleRelationMethod);
result.addOtherMethod(singleRelationMethod);
}
continue;
} catch (NoSuchMethodException e) {
......@@ -232,7 +270,7 @@ aspect GenerationBackend {
ListRelationMethod listRelationMethod = new ListRelationMethod();
listRelationMethod.setMethod(relationMethod);
listRelationMethod.setName(relationName);
result.addAnalysedMethod(listRelationMethod);
result.addOtherMethod(listRelationMethod);
}
continue;
} catch (NoSuchMethodException e) {
......@@ -243,7 +281,7 @@ aspect GenerationBackend {
IntrinsicTokenMethod tokenMethod = new IntrinsicTokenMethod();
tokenMethod.setMethod(method);
tokenMethod.setName(tokenName);
result.addAnalysedMethod(tokenMethod);
result.addOtherMethod(tokenMethod);
}
break;
case "Attribute":
......@@ -263,12 +301,12 @@ aspect GenerationBackend {
NTAListChildMethod ntaListChildMethod = new NTAListChildMethod();
ntaListChildMethod.setMethod(method);
ntaListChildMethod.setName(attributeName);
result.addAnalysedMethod(ntaListChildMethod);
result.addOtherMethod(ntaListChildMethod);
} else {
NTASingleChildMethod ntaSingleChildMethod = new NTASingleChildMethod();
ntaSingleChildMethod.setMethod(method);
ntaSingleChildMethod.setName(attributeName);
result.addAnalysedMethod(ntaSingleChildMethod);
result.addOtherMethod(ntaSingleChildMethod);
}
}
} else if (isAttributeEnabled(clazzName, attributeName)) {
......@@ -276,16 +314,53 @@ aspect GenerationBackend {
AttributeMethod attributeMethod = new AttributeMethod();
attributeMethod.setMethod(method);
attributeMethod.setName(attributeName);
result.addAnalysedMethod(attributeMethod);
result.addOtherMethod(attributeMethod);
}
break;
}
if (containmentMethodToAdd != null) {
int indexOfContextInTarget = targetOrder.indexOf(contextNameToAdd);
if (indexOfContextInTarget == 0) {
result.getContainmentMethodList().insertChild(containmentMethodToAdd, 0);
continue;
}
if (indexOfContextInTarget == targetOrder.size() - 1) {
result.addContainmentMethod(containmentMethodToAdd);
continue;
}
for (int i = 0, size = result.getNumContainmentMethod(); i < size; i++) {
String currentContextName = result.getContainmentMethod(i).getName();
int indexOfCurrentInTarget = targetOrder.indexOf(currentContextName);
if (indexOfCurrentInTarget > indexOfContextInTarget) {
result.getContainmentMethodList().insertChild(containmentMethodToAdd, i);
break;
}
}
result.addContainmentMethod(containmentMethodToAdd);
}
}
}
}
return result;
}
syn java.util.List<String> DumpAst.targetOrder(Class<?> clazz) {
for (java.lang.reflect.Constructor<?> method : clazz.getConstructors()) {
for (java.lang.annotation.Annotation annotation : method.getAnnotations()) {
String canonicalName = annotation.annotationType().getCanonicalName();
if (canonicalName.startsWith(astNodeAnnotationPrefix())) {
String simpleName = annotation.annotationType().getSimpleName();
if (simpleName.equals("Constructor")) {
return java.util.Arrays.asList((String[]) invokeMethod("name", annotation));
}
}
}
}
// there is no constructor with an annotation, iff the nonterminal has no children
return null;
}
private String DumpAst.titleCase(String s) {
if (s.isEmpty()) {
return s;
......@@ -468,7 +543,7 @@ aspect GenerationBackend {
java.util.List<DumpNode> result = new java.util.ArrayList<>();
for (DumpChildNode childNode : getDumpChildNodeList()) {
for (DumpNode inner : childNode.innerNodes(false)) {
if (inner.getInvisible()) {
if (inner != null && inner.getInvisible()) {
result.addAll(inner.reachableThroughInvisible());
} else if (this.getInvisible()) {
result.add(inner);
......@@ -519,6 +594,7 @@ aspect GenerationBackend {
class TransformationTransferInformation {
java.util.Map<Object, DumpNode> transformed = new java.util.HashMap<>();
java.util.Map<DumpNode, Boolean> relationTargetsUnprocessed = new java.util.HashMap<>();
int nodeCounter = 0;
}
syn String DumpAst.toYaml(boolean prependCreationComment) {
......
......@@ -5,18 +5,6 @@ aspect Navigation {
syn boolean DumpRelation.isList() = false;
eq DumpListRelation.isList() = true;
// --- isDumpValueToken ---
syn boolean DumpToken.isDumpValueToken() = false;
eq DumpValueToken.isDumpValueToken() = true;
// --- asDumpValueToken ---
syn DumpValueToken DumpToken.asDumpValueToken() = null;
eq DumpValueToken.asDumpValueToken() = this;
// --- asDumpReferenceToken ---
syn DumpReferenceToken DumpToken.asDumpReferenceToken() = null;
eq DumpReferenceToken.asDumpReferenceToken() = this;
// --- buildConfig ---
inh BuildConfig DumpNode.buildConfig();
eq DumpAst.getChild().buildConfig() = getBuildConfig();
......@@ -97,17 +85,4 @@ aspect Navigation {
coll java.util.List<TokenMethod> ClassAnalysisResult.tokenMethods() [new java.util.ArrayList<>()] root ClassAnalysisResult;
TokenMethod contributes this to ClassAnalysisResult.tokenMethods();
// --- isAttributeMethod ---
syn boolean TokenMethod.isAttributeMethod() = false;
eq AttributeMethod.isAttributeMethod() = true;
// --- isNTASingleChildMethod ---
syn boolean SingleChildMethod.isNTASingleChildMethod() = false;