From 2ea8709a23cd0eb4ad2d744ee15acaeec0b42825 Mon Sep 17 00:00:00 2001 From: rschoene <rene.schoene@tu-dresden.de> Date: Mon, 13 Feb 2023 13:45:37 +0100 Subject: [PATCH] Fix bugs with TokenComponents not handled correctly after introduction of inheritance. - needProxyToken and normalTokenSendDef check self and ownedByOther components - temporary fix in mustache if value of KeyValuePair is null - fix for RagConnectObserver in case value of entry is null --- .../src/main/jastadd/Analysis.jrag | 14 +++++---- .../src/main/jastadd/Intermediate.jadd | 29 +++++++++++++++---- .../src/main/jastadd/IntermediateToYAML.jrag | 26 ++++++++++++++++- ragconnect.base/src/main/jastadd/Util.jadd | 3 ++ .../resources/RagConnectObserver.mustache | 4 +-- .../main/resources/tokenComponent.mustache | 4 +-- 6 files changed, 64 insertions(+), 16 deletions(-) diff --git a/ragconnect.base/src/main/jastadd/Analysis.jrag b/ragconnect.base/src/main/jastadd/Analysis.jrag index 3b99df8..e1ec0f2 100644 --- a/ragconnect.base/src/main/jastadd/Analysis.jrag +++ b/ragconnect.base/src/main/jastadd/Analysis.jrag @@ -101,14 +101,18 @@ aspect Analysis { syn boolean TokenComponent.needProxyToken() { for (Component comp : meOwnedByOthers()) { TokenComponent tokenComp = comp.asTokenComponent(); - if (!tokenComp.getDependencySourceDefinitionList().isEmpty() || - tokenComp.getTokenPortTargetList().stream() - .map(PortTarget::containingPortDefinition) - .anyMatch(PortDefinition::shouldNotResetValue)) { + if (tokenComp.directNeedProxyToken()) { return true; } } - return false; + return directNeedProxyToken(); + } + + syn boolean TokenComponent.directNeedProxyToken() { + return !getDependencySourceDefinitionList().isEmpty() || + getTokenPortTargetList().stream() + .map(PortTarget::containingPortDefinition) + .anyMatch(PortDefinition::shouldNotResetValue); } // --- effectiveUsedAt --- diff --git a/ragconnect.base/src/main/jastadd/Intermediate.jadd b/ragconnect.base/src/main/jastadd/Intermediate.jadd index 5cd7019..60fe493 100644 --- a/ragconnect.base/src/main/jastadd/Intermediate.jadd +++ b/ragconnect.base/src/main/jastadd/Intermediate.jadd @@ -632,20 +632,27 @@ containingPortDefinition().getIndexBasedListAccess()); aspect MustacheTokenComponent { // === TokenComponent === + syn java.util.List<DependencyDefinition> TokenComponent.dependencySourceDefinitionsOwnedByMe() { + java.util.List<DependencyDefinition> result = new java.util.ArrayList<>(); + result.addAll(getDependencySourceDefinitions()); + for (Component comp : meOwnedByOthers()) { + result.addAll(comp.asTokenComponent().getDependencySourceDefinitions()); + } + return result; + } + syn String TokenComponent.internalName() = needProxyToken() ? ragconnect().internalRagConnectPrefix() + getName() : getName(); syn String TokenComponent.javaType() = effectiveJavaTypeUse().prettyPrint(); syn PortDefinition TokenComponent.normalTokenSendDef() { for (Component comp : meOwnedByOthers()) { - TokenComponent tokenComp = comp.asTokenComponent(); - for (PortTarget target : tokenComp.getTokenPortTargetList()) { - if (target.isTokenPortTarget() && target.containingPortDefinition().shouldNotResetValue()) { - return target.containingPortDefinition(); - } + PortDefinition maybeResult = comp.asTokenComponent().directNormalTokenSendDef(); + if (maybeResult != null) { + return maybeResult; } } - return null; + return directNormalTokenSendDef(); } syn String TokenComponent.parentTypeName() = containingTypeDecl().getName(); @@ -673,6 +680,16 @@ aspect MustacheTokenComponent { } // > see MustacheSend for updateMethodName, writeMethodName + + // === attributes needed for computing above ones === + syn PortDefinition TokenComponent.directNormalTokenSendDef() { + for (PortTarget target : getTokenPortTargetList()) { + if (target.isTokenPortTarget() && target.containingPortDefinition().shouldNotResetValue()) { + return target.containingPortDefinition(); + } + } + return null; + } } aspect MustacheTypeDecl { diff --git a/ragconnect.base/src/main/jastadd/IntermediateToYAML.jrag b/ragconnect.base/src/main/jastadd/IntermediateToYAML.jrag index c247d9d..5aa0f8c 100644 --- a/ragconnect.base/src/main/jastadd/IntermediateToYAML.jrag +++ b/ragconnect.base/src/main/jastadd/IntermediateToYAML.jrag @@ -181,7 +181,8 @@ aspect IntermediateToYAML { result.put("DependencySourceDefinitions" , dependencySourceDefinitions); result.put("javaType" , javaType()); - result.put("normalTokenSendDef" , normalTokenSendDef().toYAML()); + result.put("normalTokenSendDef" , ASTNode.<PortDefinition,MappingElement>safeCall( + normalTokenSendDef(), def -> def.toYAML())); result.put("parentTypeName" , parentTypeName()); return result; } @@ -209,6 +210,29 @@ aspect IntermediateToYAML { protected StringElement ASTNode.sanitizeValueForYAML(String value) { return StringElement.of(value.replace("\"" , "\\\"").replace("\n" , "\\n")); } + + // FIXME: remove refine once fixed in upstream mustache + refine Printing protected StringBuilder KeyValuePair.prettyPrint(StringBuilder sb, boolean printIndent, String indent) { + if (printIndent) sb.append(indent); + if (isCollapsed()) { + sb.append("\""); + } + sb.append(getKey()); + if (isCollapsed()) { + sb.append("\""); + } + sb.append(":"); + if (getValue() == null) { + sb.append(" null"); + } else if (getValue().isComplexElement() && !getValue().isEmpty() && !getValue().isCollapsed()) { + sb.append("\n"); + getValue().prettyPrint(sb, true, indent + PRINT_INDENT); + } else { + sb.append(" "); + getValue().prettyPrint(sb, false, indent); + } + return sb; + } } aspect Navigation { diff --git a/ragconnect.base/src/main/jastadd/Util.jadd b/ragconnect.base/src/main/jastadd/Util.jadd index 174f8cd..7c8f5e6 100644 --- a/ragconnect.base/src/main/jastadd/Util.jadd +++ b/ragconnect.base/src/main/jastadd/Util.jadd @@ -4,6 +4,9 @@ aspect Util { if (s.isEmpty()) return ""; return Character.toUpperCase(s.charAt(0)) + s.substring(1); } + static <Input,Result> Result ASTNode.safeCall(Input input, java.util.function.Function<Input, Result> function) { + return input == null ? null : function.apply(input); + } protected T JastAddList.firstChild() { return getChild(0); } protected T JastAddList.lastChild() { return getChild(getNumChild() - 1); } diff --git a/ragconnect.base/src/main/resources/RagConnectObserver.mustache b/ragconnect.base/src/main/resources/RagConnectObserver.mustache index 67ba811..4414782 100644 --- a/ragconnect.base/src/main/resources/RagConnectObserver.mustache +++ b/ragconnect.base/src/main/resources/RagConnectObserver.mustache @@ -119,8 +119,8 @@ aspect RagConnectObserver { } RagConnectObserverStartEntry startEntry = startEntries.peekFirst(); if (node == startEntry.node && - attribute.equals(startEntry.attributeString) && - value.equals(startEntry.flushIncToken)) { + java.util.Objects.equals(attribute, startEntry.attributeString) && + java.util.Objects.equals(value, startEntry.flushIncToken)) { // create a copy of the queue to avoid entering this again causing an endless recursion RagConnectObserverEntry[] entriesToProcess = entryQueue.toArray(new RagConnectObserverEntry[entryQueue.size()]); entryQueue.clear(); diff --git a/ragconnect.base/src/main/resources/tokenComponent.mustache b/ragconnect.base/src/main/resources/tokenComponent.mustache index 12238f4..3d90c34 100644 --- a/ragconnect.base/src/main/resources/tokenComponent.mustache +++ b/ragconnect.base/src/main/resources/tokenComponent.mustache @@ -1,6 +1,6 @@ public {{parentTypeName}} {{parentTypeName}}.set{{Name}}({{javaType}} value) { set{{internalName}}(value); - {{#DependencySourceDefinitions}} + {{#dependencySourceDefinitionsOwnedByMe}} for ({{targetParentTypeName}} target : get{{internalRelationPrefix}}TargetList()) { {{#targetPortDefinition}} if (target.{{updateMethodName}}()) { @@ -8,7 +8,7 @@ public {{parentTypeName}} {{parentTypeName}}.set{{Name}}({{javaType}} value) { } {{/targetPortDefinition}} } - {{/DependencySourceDefinitions}} + {{/dependencySourceDefinitionsOwnedByMe}} {{#normalTokenSendDef}} if ({{updateMethodName}}()) { {{writeMethodName}}(); -- GitLab