Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
1 merge request!101.0.0
Pipeline #12771 passed
...@@ -35,7 +35,7 @@ DumpListRelation : DumpRelation ::= InnerDumpNode* ; ...@@ -35,7 +35,7 @@ DumpListRelation : DumpRelation ::= InnerDumpNode* ;
// type of NTA // type of NTA
InvisiblePath ::= InnerDumpNode* ; InvisiblePath ::= InnerDumpNode* ;
ClassAnalysisResult ::= AnalysedMethod* ; ClassAnalysisResult ::= ContainmentMethod:AnalysedMethod* OtherMethod:AnalysedMethod* ;
abstract AnalysedMethod ::= <Method:java.lang.reflect.Method> <Name> ; abstract AnalysedMethod ::= <Method:java.lang.reflect.Method> <Name> ;
abstract SingleChildMethod : AnalysedMethod ; 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 { ...@@ -52,7 +52,7 @@ aspect GenerationBackend {
} else { } else {
node = new DumpNode(); node = new DumpNode();
node.setObject(obj); node.setObject(obj);
node.setName("node" + tti.transformed.size()); node.setName("node" + (tti.nodeCounter++));
tti.transformed.put(obj, node); tti.transformed.put(obj, node);
this.addDumpNode(node); this.addDumpNode(node);
} }
...@@ -73,53 +73,85 @@ aspect GenerationBackend { ...@@ -73,53 +73,85 @@ aspect GenerationBackend {
return node; return node;
} }
final ClassAnalysisResult car = analyzeClass(obj.getClass()); final ClassAnalysisResult car = analyzeClass(obj.getClass());
for (AnalysedMethod containmentMethod : car.getContainmentMethodList()) {
if (containmentMethod.isSingleChildMethod()) {
// -- singleChild -- // -- singleChild --
for (SingleChildMethod singleChildMethod : car.singleChildMethods()) { Object target = containmentMethod.getMethod().invoke(obj);
Object target = singleChildMethod.getMethod().invoke(obj); String childName = containmentMethod.getName();
String childName = singleChildMethod.getName();
DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName)), !getBuildConfig().getExcludeNullNodes()); DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName)), !getBuildConfig().getExcludeNullNodes());
if (targetNode != null) { if (targetNode != null) {
DumpNormalChildNode normalChild = new DumpNormalChildNode(); DumpNormalChildNode normalChild = new DumpNormalChildNode();
normalChild.setName(childName); normalChild.setName(childName);
normalChild.setDumpNode(targetNode); normalChild.setDumpNode(targetNode);
normalChild.setComputed(singleChildMethod.isNTASingleChildMethod()); normalChild.setComputed(false);
node.addDumpChildNode(normalChild); node.addDumpChildNode(normalChild);
} }
} } else if (containmentMethod.isListChildMethod()) {
// -- listChild -- // -- listChild --
for (ListChildMethod listChildMethod : car.listChildMethods()) { Iterable<?> targetList = (Iterable<?>) containmentMethod.getMethod().invoke(obj);
Iterable<?> targetList = (Iterable<?>) listChildMethod.getMethod().invoke(obj);
DumpListChildNode listChild = new DumpListChildNode(); DumpListChildNode listChild = new DumpListChildNode();
listChild.setComputed(listChildMethod.isNTAListChildMethod()); listChild.setComputed(false);
String childName = listChildMethod.getName(); String childName = containmentMethod.getName();
boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName); boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName);
listChild.setName(childName); listChild.setName(childName);
for (Object target : targetList) { for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble)); DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble));
if (target != null && targetNode != null) { if (target != null && targetNode != null) {
listChild.addInnerDumpNode(new InnerDumpNode(targetNode)); listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode));
} }
} }
if (listChild.getNumInnerDumpNode() > 0) { if (listChild.getNumInnerDumpNode() > 0) {
node.addDumpChildNode(listChild); node.addDumpChildNode(listChild);
} }
} else {
throw new RuntimeException("Unknown containment method type " + containmentMethod);
}
}
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 -- // -- singleRelation --
for (SingleRelationMethod singleRelationMethod : car.singleRelationMethods()) { Object target = otherMethod.getMethod().invoke(obj);
Object target = singleRelationMethod.getMethod().invoke(obj);
DumpNode targetNode = transform(tti, target, Source.RELATION); DumpNode targetNode = transform(tti, target, Source.RELATION);
if (target != null && targetNode != null) { if (target != null && targetNode != null) {
DumpNormalRelation normalRelation = new DumpNormalRelation(); DumpNormalRelation normalRelation = new DumpNormalRelation();
normalRelation.setName(singleRelationMethod.getName()); normalRelation.setName(otherMethod.getName());
normalRelation.setDumpNode(targetNode); normalRelation.setDumpNode(targetNode);
node.addDumpRelation(normalRelation); node.addDumpRelation(normalRelation);
} }
} } else if (otherMethod.isListRelationMethod()) {
// -- listRelation -- // -- listRelation --
for (ListRelationMethod listRelationMethod : car.listRelationMethods()) { Iterable<?> targetList = (Iterable<?>) otherMethod.getMethod().invoke(obj);
Iterable<?> targetList = (Iterable<?>) listRelationMethod.getMethod().invoke(obj);
DumpListRelation listRelation = new DumpListRelation(); DumpListRelation listRelation = new DumpListRelation();
listRelation.setName(listRelationMethod.getName()); listRelation.setName(otherMethod.getName());
for (Object target : targetList) { for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, Source.RELATION); DumpNode targetNode = transform(tti, target, Source.RELATION);
if (target != null && targetNode != null) { if (target != null && targetNode != null) {
...@@ -129,10 +161,9 @@ aspect GenerationBackend { ...@@ -129,10 +161,9 @@ aspect GenerationBackend {
if (listRelation.getNumInnerDumpNode() > 0) { if (listRelation.getNumInnerDumpNode() > 0) {
node.addDumpRelation(listRelation); node.addDumpRelation(listRelation);
} }
} } else if (otherMethod.isTokenMethod()) {
// -- token -- // -- token --
for (TokenMethod tokenMethod : car.tokenMethods()) { Object target = otherMethod.getMethod().invoke(obj);
Object target = tokenMethod.getMethod().invoke(obj);
if (target != null) { if (target != null) {
DumpNode targetNode = transform(tti, target, Source.RELATION); DumpNode targetNode = transform(tti, target, Source.RELATION);
DumpToken token = null; DumpToken token = null;
...@@ -148,11 +179,14 @@ aspect GenerationBackend { ...@@ -148,11 +179,14 @@ aspect GenerationBackend {
} }
} }
if (token != null) { if (token != null) {
token.setName(tokenMethod.getName()); token.setName(otherMethod.getName());
token.setComputed(tokenMethod.isAttributeMethod()); token.setComputed(otherMethod.asTokenMethod().isAttributeMethod());
node.addDumpToken(token); node.addDumpToken(token);
} }
} }
} else {
throw new RuntimeException("Unknown other method type " + otherMethod);
}
} }
return node; return node;
} }
...@@ -172,39 +206,43 @@ aspect GenerationBackend { ...@@ -172,39 +206,43 @@ aspect GenerationBackend {
syn nta ClassAnalysisResult DumpAst.analyzeClass(java.lang.Class<?> clazz) { syn nta ClassAnalysisResult DumpAst.analyzeClass(java.lang.Class<?> clazz) {
ClassAnalysisResult result = new ClassAnalysisResult(); ClassAnalysisResult result = new ClassAnalysisResult();
String clazzName = clazz.getSimpleName(); String clazzName = clazz.getSimpleName();
java.util.List<String> targetOrder = targetOrder(clazz);
for (java.lang.reflect.Method method : clazz.getMethods()) { for (java.lang.reflect.Method method : clazz.getMethods()) {
for (java.lang.annotation.Annotation annotation : method.getAnnotations()) { for (java.lang.annotation.Annotation annotation : method.getAnnotations()) {
String canonicalName = annotation.annotationType().getCanonicalName(); String canonicalName = annotation.annotationType().getCanonicalName();
if (canonicalName.startsWith(astNodeAnnotationPrefix())) { if (canonicalName.startsWith(astNodeAnnotationPrefix())) {
String simpleName = annotation.annotationType().getSimpleName(); String simpleName = annotation.annotationType().getSimpleName();
String contextNameToAdd = null;
AnalysedMethod containmentMethodToAdd = null;
switch (simpleName) { switch (simpleName) {
case "Child": case "Child":
String singleChildName = invokeName(annotation); contextNameToAdd = invokeName(annotation);
NormalSingleChildMethod singleChildMethod = new NormalSingleChildMethod(); NormalSingleChildMethod singleChildMethod = new NormalSingleChildMethod();
singleChildMethod.setMethod(method); singleChildMethod.setMethod(method);
singleChildMethod.setName(singleChildName); singleChildMethod.setName(contextNameToAdd);
result.addAnalysedMethod(singleChildMethod); containmentMethodToAdd = singleChildMethod;
break; break;
case "OptChild": case "OptChild":
String optChildName = invokeName(annotation); contextNameToAdd = invokeName(annotation);
try { try {
// the annotated method is "get???Opt", but we want "get???" // 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 normalSingleChildMethod = new NormalSingleChildMethod();
normalSingleChildMethod.setMethod(realGetter); normalSingleChildMethod.setMethod(realGetter);
normalSingleChildMethod.setName(optChildName); normalSingleChildMethod.setName(contextNameToAdd);
result.addAnalysedMethod(normalSingleChildMethod); containmentMethodToAdd = normalSingleChildMethod;
} catch (NoSuchMethodException e) { } 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); throw new RuntimeException(e);
} }
break; break;
case "ListChild": case "ListChild":
String listChildName = invokeName(annotation); String listChildName = invokeName(annotation);
contextNameToAdd = listChildName;
NormalListChildMethod normalListChildMethod = new NormalListChildMethod(); NormalListChildMethod normalListChildMethod = new NormalListChildMethod();
normalListChildMethod.setMethod(method); normalListChildMethod.setMethod(method);
normalListChildMethod.setName(listChildName); normalListChildMethod.setName(listChildName);
result.addAnalysedMethod(normalListChildMethod); containmentMethodToAdd = normalListChildMethod;
break; break;
case "Token": case "Token":
// heuristic for relations // heuristic for relations
...@@ -218,7 +256,7 @@ aspect GenerationBackend { ...@@ -218,7 +256,7 @@ aspect GenerationBackend {
SingleRelationMethod singleRelationMethod = new SingleRelationMethod(); SingleRelationMethod singleRelationMethod = new SingleRelationMethod();
singleRelationMethod.setMethod(relationMethod); singleRelationMethod.setMethod(relationMethod);
singleRelationMethod.setName(relationName); singleRelationMethod.setName(relationName);
result.addAnalysedMethod(singleRelationMethod); result.addOtherMethod(singleRelationMethod);
} }
continue; continue;
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
...@@ -232,7 +270,7 @@ aspect GenerationBackend { ...@@ -232,7 +270,7 @@ aspect GenerationBackend {
ListRelationMethod listRelationMethod = new ListRelationMethod(); ListRelationMethod listRelationMethod = new ListRelationMethod();
listRelationMethod.setMethod(relationMethod); listRelationMethod.setMethod(relationMethod);
listRelationMethod.setName(relationName); listRelationMethod.setName(relationName);
result.addAnalysedMethod(listRelationMethod); result.addOtherMethod(listRelationMethod);
} }
continue; continue;
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
...@@ -243,7 +281,7 @@ aspect GenerationBackend { ...@@ -243,7 +281,7 @@ aspect GenerationBackend {
IntrinsicTokenMethod tokenMethod = new IntrinsicTokenMethod(); IntrinsicTokenMethod tokenMethod = new IntrinsicTokenMethod();
tokenMethod.setMethod(method); tokenMethod.setMethod(method);
tokenMethod.setName(tokenName); tokenMethod.setName(tokenName);
result.addAnalysedMethod(tokenMethod); result.addOtherMethod(tokenMethod);
} }
break; break;
case "Attribute": case "Attribute":
...@@ -263,12 +301,12 @@ aspect GenerationBackend { ...@@ -263,12 +301,12 @@ aspect GenerationBackend {
NTAListChildMethod ntaListChildMethod = new NTAListChildMethod(); NTAListChildMethod ntaListChildMethod = new NTAListChildMethod();
ntaListChildMethod.setMethod(method); ntaListChildMethod.setMethod(method);
ntaListChildMethod.setName(attributeName); ntaListChildMethod.setName(attributeName);
result.addAnalysedMethod(ntaListChildMethod); result.addOtherMethod(ntaListChildMethod);
} else { } else {
NTASingleChildMethod ntaSingleChildMethod = new NTASingleChildMethod(); NTASingleChildMethod ntaSingleChildMethod = new NTASingleChildMethod();
ntaSingleChildMethod.setMethod(method); ntaSingleChildMethod.setMethod(method);
ntaSingleChildMethod.setName(attributeName); ntaSingleChildMethod.setName(attributeName);
result.addAnalysedMethod(ntaSingleChildMethod); result.addOtherMethod(ntaSingleChildMethod);
} }
} }
} else if (isAttributeEnabled(clazzName, attributeName)) { } else if (isAttributeEnabled(clazzName, attributeName)) {
...@@ -276,16 +314,53 @@ aspect GenerationBackend { ...@@ -276,16 +314,53 @@ aspect GenerationBackend {
AttributeMethod attributeMethod = new AttributeMethod(); AttributeMethod attributeMethod = new AttributeMethod();
attributeMethod.setMethod(method); attributeMethod.setMethod(method);
attributeMethod.setName(attributeName); 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; break;
} }
} }
result.addContainmentMethod(containmentMethodToAdd);
}
}
} }
} }
return result; 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) { private String DumpAst.titleCase(String s) {
if (s.isEmpty()) { if (s.isEmpty()) {
return s; return s;
...@@ -468,7 +543,7 @@ aspect GenerationBackend { ...@@ -468,7 +543,7 @@ aspect GenerationBackend {
java.util.List<DumpNode> result = new java.util.ArrayList<>(); java.util.List<DumpNode> result = new java.util.ArrayList<>();
for (DumpChildNode childNode : getDumpChildNodeList()) { for (DumpChildNode childNode : getDumpChildNodeList()) {
for (DumpNode inner : childNode.innerNodes(false)) { for (DumpNode inner : childNode.innerNodes(false)) {
if (inner.getInvisible()) { if (inner != null && inner.getInvisible()) {
result.addAll(inner.reachableThroughInvisible()); result.addAll(inner.reachableThroughInvisible());
} else if (this.getInvisible()) { } else if (this.getInvisible()) {
result.add(inner); result.add(inner);
...@@ -519,6 +594,7 @@ aspect GenerationBackend { ...@@ -519,6 +594,7 @@ aspect GenerationBackend {
class TransformationTransferInformation { class TransformationTransferInformation {
java.util.Map<Object, DumpNode> transformed = new java.util.HashMap<>(); java.util.Map<Object, DumpNode> transformed = new java.util.HashMap<>();
java.util.Map<DumpNode, Boolean> relationTargetsUnprocessed = new java.util.HashMap<>(); java.util.Map<DumpNode, Boolean> relationTargetsUnprocessed = new java.util.HashMap<>();
int nodeCounter = 0;
} }
syn String DumpAst.toYaml(boolean prependCreationComment) { syn String DumpAst.toYaml(boolean prependCreationComment) {
......
...@@ -5,18 +5,6 @@ aspect Navigation { ...@@ -5,18 +5,6 @@ aspect Navigation {
syn boolean DumpRelation.isList() = false; syn boolean DumpRelation.isList() = false;
eq DumpListRelation.isList() = true; 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 --- // --- buildConfig ---
inh BuildConfig DumpNode.buildConfig(); inh BuildConfig DumpNode.buildConfig();
eq DumpAst.getChild().buildConfig() = getBuildConfig(); eq DumpAst.getChild().buildConfig() = getBuildConfig();
...@@ -97,17 +85,4 @@ aspect Navigation { ...@@ -97,17 +85,4 @@ aspect Navigation {
coll java.util.List<TokenMethod> ClassAnalysisResult.tokenMethods() [new java.util.ArrayList<>()] root ClassAnalysisResult; coll java.util.List<TokenMethod> ClassAnalysisResult.tokenMethods() [new java.util.ArrayList<>()] root ClassAnalysisResult;
TokenMethod contributes this to ClassAnalysisResult.tokenMethods(); TokenMethod contributes this to ClassAnalysisResult.tokenMethods();
// --- isAttributeMethod ---
syn boolean TokenMethod.isAttributeMethod() = false;
eq AttributeMethod.isAttributeMethod() = true;
// --- isNTASingleChildMethod ---
syn boolean SingleChildMethod.isNTASingleChildMethod() = false;
eq NTASingleChildMethod.isNTASingleChildMethod() = true;
// --- isNTAListChildMethod ---
syn boolean ListChildMethod.isNTAListChildMethod() = false;
eq NTAListChildMethod.isNTAListChildMethod() = true;
} }
...@@ -22,7 +22,10 @@ aspect Printing { ...@@ -22,7 +22,10 @@ aspect Printing {
syn String DumpNode.label() = getLabel(); syn String DumpNode.label() = getLabel();
// --- bothVisible --- // --- bothVisible ---
syn boolean InnerDumpNode.bothVisible() = !containingDumpNode().getInvisible() && !getDumpNode().getInvisible(); boolean ASTNode.bothVisible(DumpNode one, DumpNode two) {
syn boolean DumpNormalChildNode.bothVisible() = !containingDumpNode().getInvisible() && !getDumpNode().getInvisible(); return one != null && two != null && !one.getInvisible() && !two.getInvisible();
syn boolean DumpNormalRelation.bothVisible() = !containingDumpNode().getInvisible() && !getDumpNode().getInvisible(); }
syn boolean InnerDumpNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
syn boolean DumpNormalChildNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
syn boolean DumpNormalRelation.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
} }
package de.tudresden.inf.st.jastadd.testDumper; package de.tudresden.inf.st.jastadd.testDumper;
import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpAst; import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpAst;
import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpListChildNode;
import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpNode; import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpNode;
import org.jastadd.testDumper.ast.A; import org.jastadd.testDumper.ast.A;
import org.jastadd.testDumper.ast.B; import org.jastadd.testDumper.ast.B;
import org.jastadd.testDumper.ast.C; import org.jastadd.testDumper.ast.C;
import org.jastadd.testDumper.ast.Root; import org.jastadd.testDumper.ast.Root;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class TestDumperMain { public class TestDumperMain {
...@@ -41,9 +45,28 @@ public class TestDumperMain { ...@@ -41,9 +45,28 @@ public class TestDumperMain {
DumpAst dumpAst = builder.build(); DumpAst dumpAst = builder.build();
System.out.println(dumpAst.toPlantUml()); System.out.println(dumpAst.toPlantUml());
String[] b = new String[]{"1"};
List<String> l = Arrays.asList(b);
DumpNode node = dumpAst.getDumpNode(0); DumpNode node = dumpAst.getDumpNode(0);
System.out.println(node.getName()); System.out.println(node.getName());
System.out.println(node.myChildren().stream().map(DumpNode::getName).collect(Collectors.joining(", "))); Function<? super DumpNode, String> printInfo = d ->
d.getName() + "(" + d.getLabel() +
", container: " + d.container() +
", succ: " + (d.successor() == null ? "null" : d.successor().getName()) +
", has_succ: " + d.hasSuccessor() + ")";
dumpAst.flushTreeCache();
dumpAst.treeResolveAll();
dumpAst.getRootNode().getDumpChildNodeList().forEach(d -> {
if (d instanceof DumpListChildNode) {
System.out.println("dump-list-node " + d.getName());
((DumpListChildNode) d).getInnerDumpNodeList().forEach(inner -> {
System.out.println(" inner: " + inner.getDumpNode().getName());
System.out.println(" <- " + inner.getDumpNode().getContainerOfInner());
});
}
});
System.out.println(node.myChildren().stream().map(printInfo).collect(Collectors.joining(", ")));
// System.out.println(">> YAML begin"); // System.out.println(">> YAML begin");
// System.out.println(builder.build().toYaml(true)); // System.out.println(builder.build().toYaml(true));
......
...@@ -11,8 +11,7 @@ import java.util.Optional; ...@@ -11,8 +11,7 @@ import java.util.Optional;
import static de.tudresden.inf.st.jastadd.testDumper.TestUtils.*; import static de.tudresden.inf.st.jastadd.testDumper.TestUtils.*;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class TestSimple { public class TestSimple {
...@@ -91,10 +90,11 @@ public class TestSimple { ...@@ -91,10 +90,11 @@ public class TestSimple {
@Test @Test
public void testOrderedListChildren() { public void testOrderedListChildren() {
Root root = createRoot(null, null, createB(B1_NAME), createB(B2_NAME), createB(B3_NAME)); Root root = createRoot(createA(A_NAME), createC(C_NAME), createB(B1_NAME), createB(B2_NAME), createB(B3_NAME));
List<DumpNode> nodes = TestUtils.dumpModel(root, DumpBuilder::orderChildren); List<DumpNode> nodes = TestUtils.dumpModel(root, DumpBuilder::orderChildren);
assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, B1_NAME, B2_NAME, B3_NAME); assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(
ROOT_NAME, A_NAME, B1_NAME, B2_NAME, B3_NAME, C_NAME);
DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME); DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME);
// in grammar: DumpAst ::= [...] DumpNode* [...]; // in grammar: DumpAst ::= [...] DumpNode* [...];
...@@ -102,7 +102,30 @@ public class TestSimple { ...@@ -102,7 +102,30 @@ public class TestSimple {
assertTrue(((DumpAst) actualRoot.getParent().getParent()).getPrintConfig().getOrderChildren()); assertTrue(((DumpAst) actualRoot.getParent().getParent()).getPrintConfig().getOrderChildren());
List<DumpNode> children = actualRoot.myChildren(); List<DumpNode> children = actualRoot.myChildren();
assertThat(children).extracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(B1_NAME, B2_NAME, B3_NAME); assertThat(children).extracting(NAME_EXTRACTOR).containsExactly(
A_NAME, B1_NAME, B2_NAME, B3_NAME, C_NAME);
DumpNode actualA = TestUtils.findByName(nodes, A_NAME);
DumpNode actualB1 = TestUtils.findByName(nodes, B1_NAME);
DumpNode actualB2 = TestUtils.findByName(nodes, B2_NAME);
DumpNode actualB3 = TestUtils.findByName(nodes, B3_NAME);
DumpNode actualC = TestUtils.findByName(nodes, C_NAME);
for (DumpNode d : children) {
System.out.println(d.getName() + "/" + d.getLabel() + " = " + d);
}
assertEquals(actualB1, actualA.successor(), actualA.successor().getName());
assertEquals(actualB2, actualB1.successor(), actualB1.successor().getName());
assertEquals(actualB3, actualB2.successor(), actualB2.successor().getName());
assertEquals(actualC, actualB3.successor(), actualB3.successor().getName());
assertNull(actualC.successor());
assertTrue(actualA.hasSuccessor());
assertTrue(actualB1.hasSuccessor());
assertTrue(actualB2.hasSuccessor());
assertTrue(actualB3.hasSuccessor());
assertFalse(actualC.hasSuccessor());
} }
@Test @Test
......
...@@ -187,7 +187,7 @@ public class TestUtils { ...@@ -187,7 +187,7 @@ public class TestUtils {
if (!dumpChildNode.isList()) { if (!dumpChildNode.isList()) {
// then it is a DumpNormalChildNode // then it is a DumpNormalChildNode
DumpNode target = ((DumpNormalChildNode) dumpChildNode).getDumpNode(); DumpNode target = ((DumpNormalChildNode) dumpChildNode).getDumpNode();
if (!target.getInvisible()) { if (target != null && !target.getInvisible()) {
result.put(dumpChildNode.getName(), target); result.put(dumpChildNode.getName(), target);
} }
} }
...@@ -201,7 +201,7 @@ public class TestUtils { ...@@ -201,7 +201,7 @@ public class TestUtils {
if (dumpChildNode.isList()) { if (dumpChildNode.isList()) {
// then it is a DumpListChildNode // then it is a DumpListChildNode
((DumpListChildNode) dumpChildNode).getInnerDumpNodeList().forEach(inner -> { ((DumpListChildNode) dumpChildNode).getInnerDumpNodeList().forEach(inner -> {
if (!inner.getDumpNode().getInvisible()) { if (inner.getDumpNode() != null && !inner.getDumpNode().getInvisible()) {
result.computeIfAbsent(dumpChildNode.getName(), key -> new ArrayList<>()).add(inner.getDumpNode()); result.computeIfAbsent(dumpChildNode.getName(), key -> new ArrayList<>()).add(inner.getDumpNode());
} }
}); });
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment