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

2.0.3

- add "?" to label for optional children and relations
- use "[]" for empty lists (styled like null-nodes)
parent 36706d86
No related branches found
No related tags found
1 merge request!133.0.1
Pipeline #14762 failed
......@@ -48,29 +48,28 @@ aspect ClassAnalysis {
String tokenName = invokeName(annotation);
if (tokenName.startsWith("_impl_")) {
String relationName = titleCase(tokenName.substring(6));
try {
java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName);
if (present(getMethod(clazz, "get" + relationName), relationMethod -> {
// normal get + token-name -> singleRelation
SingleRelationMethod singleRelationMethod = new SingleRelationMethod();
SingleRelationMethod singleRelationMethod = getMethod(clazz, "has" + relationName).isPresent() ?
new OptRelationMethod() : new SingleRelationMethod();
singleRelationMethod.setMethod(relationMethod);
singleRelationMethod.setName(relationName);
result.addOtherMethod(singleRelationMethod);
})) {
continue;
} catch (NoSuchMethodException e) {
// ignore, but we know this is probably not a single relation
}
// we know here this is probably not a single or opt relation
// try list-relation next
try {
java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName + "List");
if (present(getMethod(clazz, "get" + relationName + "List"), relationMethod -> {
// normal get + token-name + "List" -> listRelation
ListRelationMethod listRelationMethod = new ListRelationMethod();
listRelationMethod.setMethod(relationMethod);
listRelationMethod.setName(relationName);
result.addOtherMethod(listRelationMethod);
})) {
continue;
} catch (NoSuchMethodException e) {
// ignore, but we know this is probably not a relation at all
}
// we know here this is probably not a relation at all
}
IntrinsicTokenMethod tokenMethod = new IntrinsicTokenMethod();
tokenMethod.setMethod(method);
......@@ -201,6 +200,20 @@ aspect ClassAnalysis {
}
}
private static java.util.Optional<java.lang.reflect.Method> DumpAst.getMethod(Class<?> clazz, String methodName) {
try {
java.lang.reflect.Method method = clazz.getMethod(methodName);
return java.util.Optional.of(method);
} catch (NoSuchMethodException e) {
return java.util.Optional.empty();
}
}
private static <T> boolean DumpAst.present(java.util.Optional<T> optional, java.util.function.Consumer<T> callback) {
optional.ifPresent(callback);
return optional.isPresent();
}
// --- astNodeAnnotationPrefix ---
syn String DumpAst.astNodeAnnotationPrefix() = getPackageName() + ".ASTNodeAnnotation";
inh String DumpNode.astNodeAnnotationPrefix();
......
......@@ -6,13 +6,13 @@ DumpNode ::= DumpChildNode* DumpToken* DumpRelation*
/InvisiblePath/ ;
InnerDumpNode ::= <OriginalIndex:int>;
rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner ;
rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner? ;
InnerRelationDumpNode ::= <OriginalIndex:int>;
rel InnerRelationDumpNode.DumpNode -> DumpNode ; // .ContainerOfInner*
rel InnerRelationDumpNode.DumpNode <-> DumpNode.ContainerOfRelationInner* ;
abstract DumpChildNode ::= <Name> <Computed:boolean> ;
DumpNormalChildNode : DumpChildNode ;
rel DumpNormalChildNode.DumpNode <-> DumpNode.ContainerOfNormalChild ;
rel DumpNormalChildNode.DumpNode <-> DumpNode.ContainerOfNormalChild? ;
DumpListChildNode : DumpChildNode ::= InnerDumpNode* ;
abstract DumpToken ::= <Name> <Computed:boolean> ;
......@@ -45,6 +45,7 @@ NormalListChildMethod : ListChildMethod ;
NTAListChildMethod : ListChildMethod ;
SingleRelationMethod : AnalysedMethod ;
OptRelationMethod : SingleRelationMethod ;
ListRelationMethod : AnalysedMethod ;
// TODO can the refine bug also happen for refined attributes?
......
......@@ -36,6 +36,12 @@ aspect Navigation {
syn boolean AnalysedMethod.isSingleRelationMethod() = false;
eq SingleRelationMethod.isSingleRelationMethod() = true;
/** Tests if SingleRelationMethod is a OptRelationMethod.
* @return 'true' if this is a OptRelationMethod, otherwise 'false'
*/
syn boolean SingleRelationMethod.isOptRelationMethod() = false;
eq OptRelationMethod.isOptRelationMethod() = true;
/** Tests if AnalysedMethod is a ListRelationMethod.
* @return 'true' if this is a ListRelationMethod, otherwise 'false'
*/
......
......@@ -85,10 +85,10 @@ aspect Navigation {
return result;
}
// --- innerNotNull ---
syn boolean DumpNormalRelation.innerNotNull() = !printConfig().getRelationWithRank() && getDumpNode() != null && getDumpNode().getObject() != null;
syn boolean DumpReferenceToken.innerNotNull() = !printConfig().getRelationWithRank() && getValue() != null && getValue().getObject() != null;
syn boolean InnerRelationDumpNode.innerNotNull() = !printConfig().getRelationWithRank() && getDumpNode() != null && getDumpNode().getObject() != null;
// --- innerNotNullOrEmpty ---
syn boolean DumpNormalRelation.innerNotNullOrEmpty() = !printConfig().getRelationWithRank() && getDumpNode() != null && getDumpNode().getObject() != null && getDumpNode().getObject() != DumpAst.EMPTY;
syn boolean DumpReferenceToken.innerNotNullOrEmpty() = !printConfig().getRelationWithRank() && getValue() != null && getValue().getObject() != null && getValue().getObject() != DumpAst.EMPTY;
syn boolean InnerRelationDumpNode.innerNotNullOrEmpty() = !printConfig().getRelationWithRank() && getDumpNode() != null && getDumpNode().getObject() != null && getDumpNode().getObject() != DumpAst.EMPTY;
// === Method naviagtion ===
coll java.util.List<SingleChildMethod> ClassAnalysisResult.singleChildMethods() [new java.util.ArrayList<>()] root ClassAnalysisResult;
......
......@@ -25,10 +25,14 @@ aspect Printing {
syn String DumpNode.label() = getLabel();
inh String InnerDumpNode.label();
inh String InnerRelationDumpNode.label();
eq DumpListChildNode.getInnerDumpNode(int index).label() = label() + "[" +
chooseIndex(getInnerDumpNode(index).getOriginalIndex(), index) + "]";
eq DumpListRelation.getInnerRelationDumpNode(int index).label() = label() + "[" +
chooseIndex(getInnerRelationDumpNode(index).getOriginalIndex(), index) + "]";
eq DumpListChildNode.getInnerDumpNode(int index).label() = label() +
(getInnerDumpNode(index).getDumpNode().isEmpty() ?
"" :
"[" + chooseIndex(getInnerDumpNode(index).getOriginalIndex(), index) + "]");
eq DumpListRelation.getInnerRelationDumpNode(int index).label() = label() +
(getInnerRelationDumpNode(index).getDumpNode().isEmpty() ?
"" :
"[" + chooseIndex(getInnerRelationDumpNode(index).getOriginalIndex(), index) + "]");
eq DumpReferenceListToken.getInnerRelationDumpNode(int index).label() = label() + "[" + index + "]";
eq InvisiblePath.getInnerRelationDumpNode(int index).label() = null;
protected int ASTNode.chooseIndex(int originalIndex, int inheritedIndex) {
......
......@@ -8,6 +8,11 @@ aspect TemplateContext {
return getObject() == null;
}
// --- isEmpty ---
syn boolean DumpNode.isEmpty() {
return getObject() == DumpAst.EMPTY;
}
// --- isAstNode ---
syn boolean DumpNode.isAstNode() {
if (getObject() == null) {
......
......@@ -71,6 +71,7 @@ aspect ToYaml {
// attributes
if (!fromRelation) {
result.put("isNull", isNull());
result.put("isEmpty", isEmpty());
result.put("isAstNode", isAstNode());
result.put("labelAndTextColor", labelAndTextColor());
result.put("stereotypeList", stereotypeList());
......@@ -137,7 +138,7 @@ aspect ToYaml {
MappingElement result = super.toYaml(fromRelation);
// attributes
result.put("innerNodeName", innerNodeName());
result.put("innerNotNull", innerNotNull());
result.put("innerNotNullOrEmpty", innerNotNullOrEmpty());
result.put("outerNodeName", outerNodeName());
return result;
}
......@@ -170,7 +171,7 @@ aspect ToYaml {
// attributes
result.put("bothVisible", bothVisible());
result.put("innerNodeName", innerNodeName());
result.put("innerNotNull", innerNotNull());
result.put("innerNotNullOrEmpty", innerNotNullOrEmpty());
return result;
}
......@@ -196,7 +197,7 @@ aspect ToYaml {
// attributes
result.put("bothVisible", bothVisible());
result.put("innerNodeName", innerNodeName());
result.put("innerNotNull", innerNotNull());
result.put("innerNotNullOrEmpty", innerNotNullOrEmpty());
result.put("outerNodeName", outerNodeName());
result.put("label", label());
return result;
......
......@@ -53,6 +53,8 @@ aspect Transform {
return new TransformationOptions(Source.NORMAL, false, false);
}
public static final Object DumpAst.EMPTY = new Object();
// --- transform --- (need to be a method, because it alters the AST while traversing the object structure)
protected DumpNode DumpAst.transform(TransformationTransferInformation tti, Object obj)
throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException {
......@@ -81,7 +83,7 @@ aspect Transform {
}
DumpNode node;
String objClassName;
if (obj == null) {
if (obj == null || obj == EMPTY) {
node = null;
objClassName = "null";
} else {
......@@ -114,8 +116,8 @@ aspect Transform {
if (options.invisible || !isTypeEnabled(objClassName)) {
node.setInvisible(true);
}
if (obj == null) {
// for a null object, we do not need any further analysis
if (obj == null || obj == EMPTY) {
// for a null or empty object, we do not need any further analysis
return node;
}
final ClassAnalysisResult car = analyzeClass(obj.getClass());
......@@ -143,7 +145,7 @@ aspect Transform {
DumpNode targetNode = transform(tti, target, options.asNormal(false).allowNullObjectsOnce());
if (targetNode != null) {
DumpNormalChildNode normalChild = new DumpNormalChildNode();
normalChild.setName(childName);
normalChild.setName(childName + (containmentMethod.isOptChildMethod() ? "?" : ""));
normalChild.setDumpNode(targetNode);
normalChild.setComputed(false);
node.addDumpChildNode(normalChild);
......@@ -166,9 +168,11 @@ aspect Transform {
listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode).setOriginalIndex(index));
}
}
if (listChild.getNumInnerDumpNode() > 0) {
node.addDumpChildNode(listChild);
if (listChild.getNumInnerDumpNode() == 0) {
listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(transform(tti, EMPTY,
options.asNormal(false).allowNullObjectsOnce())));
}
node.addDumpChildNode(listChild);
} else {
throw new RuntimeException("Unknown containment method type " + containmentMethod);
}
......@@ -222,7 +226,8 @@ aspect Transform {
DumpNode targetNode = transform(tti, target, options.asRelation());
if (targetNode != null) {
DumpNormalRelation normalRelation = new DumpNormalRelation();
normalRelation.setName(otherMethod.getName());
normalRelation.setName(otherMethod.getName() +
(otherMethod.asSingleRelationMethod().isOptRelationMethod() ? "?" : ""));
normalRelation.setDumpNode(targetNode);
node.addDumpRelation(normalRelation);
}
......@@ -243,9 +248,11 @@ aspect Transform {
.setOriginalIndex(index));
}
}
if (listRelation.getNumInnerRelationDumpNode() > 0) {
node.addDumpRelation(listRelation);
if (listRelation.getNumInnerRelationDumpNode() == 0) {
listRelation.addInnerRelationDumpNode(new InnerRelationDumpNode().setDumpNode(transform(tti, EMPTY,
options.asNormal(false).allowNullObjectsOnce())));
}
node.addDumpRelation(listRelation);
} else if (otherMethod.isTokenMethod()) {
// -- token --
TokenMethod tokenMethod = otherMethod.asTokenMethod();
......
......@@ -22,6 +22,9 @@ scale {{{scale}}}
{{#isNull}}
object "null" as {{{name}}}<<null>>
{{/isNull}}
{{#isEmpty}}
object "[]" as {{{name}}}<<null>>
{{/isEmpty}}
{{#isAstNode}}
object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroundColor}}#{{{backgroundColor}}}{{/backgroundColor}} {
{{#DumpTokens}}
......@@ -40,13 +43,13 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun
{{#isList}}
{{#InnerRelationDumpNode}}
{{#bothVisible}}
{{{outerNodeName}}} .[#black{{#computed}},#{{{computedColor}}}{{/computed}}{{#innerNotNull}},norank{{/innerNotNull}}].> {{{innerNodeName}}} : {{{label}}}
{{{outerNodeName}}} .[#black{{#computed}},#{{{computedColor}}}{{/computed}}{{#innerNotNullOrEmpty}},norank{{/innerNotNullOrEmpty}}].> {{{innerNodeName}}} : {{{label}}}
{{/bothVisible}}
{{/InnerRelationDumpNode}}
{{/isList}}
{{^isList}}
{{^isDumpValueToken}}
{{{outerNodeName}}} .[#black{{#computed}},#{{{computedColor}}}{{/computed}}{{#innerNotNull}},norank{{/innerNotNull}}].> {{{innerNodeName}}} : {{{label}}}
{{{outerNodeName}}} .[#black{{#computed}},#{{{computedColor}}}{{/computed}}{{#innerNotNullOrEmpty}},norank{{/innerNotNullOrEmpty}}].> {{{innerNodeName}}} : {{{label}}}
{{/isDumpValueToken}}
{{/isList}}
{{/invisible}}
......@@ -69,13 +72,13 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun
{{#isList}}
{{#InnerRelationDumpNode}}
{{#bothVisible}}
{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}-{{#innerNotNull}}[norank]{{/innerNotNull}}-> {{{innerNodeName}}} : {{{label}}}
{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}-{{#innerNotNullOrEmpty}}[norank]{{/innerNotNullOrEmpty}}-> {{{innerNodeName}}} : {{{label}}}
{{/bothVisible}}
{{/InnerRelationDumpNode}}
{{/isList}}
{{^isList}}
{{#bothVisible}}
{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}-{{#innerNotNull}}[norank]{{/innerNotNull}}-> {{{innerNodeName}}} : {{{label}}}
{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}-{{#innerNotNullOrEmpty}}[norank]{{/innerNotNullOrEmpty}}-> {{{innerNodeName}}} : {{{label}}}
{{/bothVisible}}
{{/isList}}
{{/DumpRelations}}
......
#Thu Oct 06 10:00:14 CEST 2022
version=2.0.2
#Fri Oct 07 16:26:50 CEST 2022
version=2.0.3
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment