From 7954031c301aec3b1902ad83a5ca59e8c195d36d Mon Sep 17 00:00:00 2001 From: rensink Date: Tue, 23 Jul 2024 17:14:29 +0200 Subject: [PATCH 1/2] Resolved github issue #797 --- .../nl/utwente/groove/control/CtrlLoader.java | 22 ++++-- .../utwente/groove/grammar/CheckPolicy.java | 2 +- .../groove/grammar/GrammarProperties.java | 75 ++++++++++++++++++- .../utwente/groove/io/store/SystemStore.java | 63 ++++------------ 4 files changed, 101 insertions(+), 61 deletions(-) diff --git a/src/main/java/nl/utwente/groove/control/CtrlLoader.java b/src/main/java/nl/utwente/groove/control/CtrlLoader.java index f389017ab..640efdf47 100644 --- a/src/main/java/nl/utwente/groove/control/CtrlLoader.java +++ b/src/main/java/nl/utwente/groove/control/CtrlLoader.java @@ -106,7 +106,8 @@ public Program buildProgram(Collection progNames) throws FormatExcepti errors.throwException(); if (!result.hasMain()) { // try to parse "any" for static semantic checks - Fragment main = addControl(QualName.name(DEFAULT_MAIN_NAME), getDefaultMain()).check() + Fragment main = addControl(QualName.name(DEFAULT_MAIN_NAME), getDefaultMain()) + .check() .toFragment(); result.add(main); } @@ -170,15 +171,15 @@ public Map changePriority(Map prioMap) { CtrlTree tree = this.controlTreeMap.get(controlName); assert tree != null : String.format("Parse tree of %s not found", controlName); CtrlTree recipeTree = tree.getProcs(Kind.RECIPE).get(recipeName); - assert recipeTree != null : String.format("Recipe declaration of %s not found", - recipeName); + assert recipeTree != null : String + .format("Recipe declaration of %s not found", recipeName); TokenRewriteStream rewriter = getRewriter(tree); boolean changed = false; if (recipeTree.getChildCount() == 3) { // no explicit priority if (newPriority != 0) { - rewriter.insertAfter(recipeTree.getChild(1).getToken(), - "priority " + newPriority); + rewriter + .insertAfter(recipeTree.getChild(1).getToken(), "priority " + newPriority); changed = true; } } else { @@ -198,7 +199,11 @@ public Map changePriority(Map prioMap) { private TokenRewriteStream getRewriter(CtrlTree tree) { CtrlLexer lexer = new CtrlLexer(null); - lexer.setCharStream(new ANTLRStringStream(tree.toInputString())); + var inputString = tree.toInputString(); + lexer + .setCharStream(new ANTLRStringStream(inputString == null + ? "" + : inputString)); TokenRewriteStream rewriter = new TokenRewriteStream(lexer); rewriter.fill(); return rewriter; @@ -241,8 +246,9 @@ public static void main(String[] args) { Grammar grammar = Groove.loadGrammar(grammarName).toGrammar(); for (int i = 1; i < args.length; i++) { String programName = CONTROL.stripExtension(args[1]); - System.out.printf("Control automaton for %s:%n%s", programName, - run(grammar, programName, new File(grammarName))); + System.out + .printf("Control automaton for %s:%n%s", programName, + run(grammar, programName, new File(grammarName))); } } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/nl/utwente/groove/grammar/CheckPolicy.java b/src/main/java/nl/utwente/groove/grammar/CheckPolicy.java index bd5c068c9..af8c85ef7 100644 --- a/src/main/java/nl/utwente/groove/grammar/CheckPolicy.java +++ b/src/main/java/nl/utwente/groove/grammar/CheckPolicy.java @@ -151,7 +151,7 @@ public String unparse(PolicyMap value) { if (e.getValue() != ERROR) { result.append(e.getKey()); result.append(ASSIGN_CHAR); - result.append(e.getValue()); + result.append(e.getValue().getName()); result.append(' '); } } diff --git a/src/main/java/nl/utwente/groove/grammar/GrammarProperties.java b/src/main/java/nl/utwente/groove/grammar/GrammarProperties.java index 7e1068934..821637f3f 100644 --- a/src/main/java/nl/utwente/groove/grammar/GrammarProperties.java +++ b/src/main/java/nl/utwente/groove/grammar/GrammarProperties.java @@ -2,9 +2,11 @@ import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.EnumMap; import java.util.EnumSet; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -341,8 +343,8 @@ public void setActiveNames(ResourceKind kind, List names) { * @return a (non-{@code null}, but possibly empty) set of active names */ public Set getActiveNames(ResourceKind kind) { - assert kind != ResourceKind.RULE; - if (kind == ResourceKind.CONFIG || kind == ResourceKind.GROOVY) { + if (kind == ResourceKind.CONFIG || kind == ResourceKind.GROOVY + || kind == ResourceKind.PROPERTIES || kind == ResourceKind.RULE) { return Collections.emptySet(); } List names = parsePropertyOrDefault(resourceKeyMap.get(kind)).getQualNameList(); @@ -512,6 +514,75 @@ public GrammarProperties relabel(TypeLabel oldLabel, TypeLabel newLabel) { : this; } + /** + * Returns a clone of this properties object where all occurrences of a + * given collection of resource names are deleted. + * @param names the names to be deleted + * @return a clone of these properties, or the properties themselves if + * {@code names} did not occur + */ + public GrammarProperties deleteResources(ResourceKind kind, Collection names) { + GrammarProperties result = clone(); + boolean hasChanged = false; + var activeNames = new HashSet<>(getActiveNames(kind)); + if (activeNames.removeAll(names)) { + hasChanged = true; + var orderedActiveNames = new ArrayList<>(activeNames); + orderedActiveNames.sort(null); + result.setActiveNames(kind, orderedActiveNames); + hasChanged = true; + } + // change the control labels + if (kind == ResourceKind.RULE) { + var actionPolicy = new PolicyMap(); + actionPolicy.putAll(getRulePolicy()); + var policyChanged = actionPolicy.keySet().removeAll(names); + if (policyChanged) { + result.setRulePolicy(actionPolicy); + hasChanged = true; + } + } + return hasChanged + ? result + : this; + } + + /** + * Returns a clone of this properties object where all occurrences of a + * given resource name are replaced by a new name. + * @param oldName the name to be replaced + * @param newName the new value for {@code oldName} + * @return a clone of these properties, or the properties themselves if + * {@code oldName} did not occur + */ + public GrammarProperties renameResource(ResourceKind kind, QualName oldName, QualName newName) { + GrammarProperties result = clone(); + boolean hasChanged = false; + var activeNames = new HashSet<>(getActiveNames(kind)); + if (activeNames.remove(oldName)) { + hasChanged = true; + activeNames.add(newName); + var orderedActiveNames = new ArrayList<>(activeNames); + orderedActiveNames.sort(null); + result.setActiveNames(kind, orderedActiveNames); + hasChanged = true; + } + // change the control labels + if (kind == ResourceKind.RULE) { + var actionPolicy = new PolicyMap(); + actionPolicy.putAll(getRulePolicy()); + var namePolicy = actionPolicy.remove(oldName); + if (namePolicy != null) { + actionPolicy.put(newName, namePolicy); + result.setRulePolicy(actionPolicy); + hasChanged = true; + } + } + return hasChanged + ? result + : this; + } + /** * Checks if the stored properties are valid in a given grammar. */ diff --git a/src/main/java/nl/utwente/groove/io/store/SystemStore.java b/src/main/java/nl/utwente/groove/io/store/SystemStore.java index 42214e441..787804dd2 100644 --- a/src/main/java/nl/utwente/groove/io/store/SystemStore.java +++ b/src/main/java/nl/utwente/groove/io/store/SystemStore.java @@ -16,9 +16,7 @@ */ package nl.utwente.groove.io.store; -import static nl.utwente.groove.grammar.model.ResourceKind.GROOVY; import static nl.utwente.groove.grammar.model.ResourceKind.PROPERTIES; -import static nl.utwente.groove.grammar.model.ResourceKind.RULE; import static nl.utwente.groove.io.FileType.GRAMMAR; import static nl.utwente.groove.io.store.EditType.LAYOUT; @@ -255,8 +253,6 @@ GraphBasedEdit doDeleteGraphs(ResourceKind kind, Collection names) throws IOException { testInit(); List deletedGraphs = new ArrayList<>(names.size()); - List activeNames = getRecordedActiveNames(kind); - boolean activeChanged = false; for (QualName name : names) { AspectGraph graph = getGraphMap(kind).remove(name); assert graph != null; @@ -264,14 +260,10 @@ GraphBasedEdit doDeleteGraphs(ResourceKind kind, this.marshaller.deleteGraph(oldFile); deleteEmptyDirectories(oldFile.getParentFile()); deletedGraphs.add(graph); - activeChanged |= activeNames.remove(name); - } - GrammarProperties oldProps = null; - GrammarProperties newProps = null; - if (activeChanged) { - oldProps = getProperties(); - newProps = getProperties().clone(); - newProps.setActiveNames(kind, activeNames); + } + GrammarProperties oldProps = getProperties(); + GrammarProperties newProps = oldProps.deleteResources(kind, names); + if (newProps != oldProps) { doPutProperties(newProps); } return new GraphBasedEdit(kind, EditType.DELETE, deletedGraphs, @@ -355,24 +347,18 @@ public Map deleteTexts(ResourceKind kind, TextBasedEdit doDeleteTexts(ResourceKind kind, Collection names) throws IOException { testInit(); Map oldTexts = new HashMap<>(); - boolean activeChanged = false; - var activeNames = getRecordedActiveNames(kind); for (QualName name : names) { assert name != null; String text = getTextMap(kind).remove(name); if (text != null) { oldTexts.put(name, text); createFile(kind, name).delete(); - activeChanged |= activeNames.remove(name); } } // change the control-related system properties, if necessary - GrammarProperties oldProps = null; - GrammarProperties newProps = null; - if (activeChanged) { - oldProps = getProperties(); - newProps = getProperties().clone(); - newProps.setActiveNames(kind, activeNames); + GrammarProperties oldProps = getProperties(); + GrammarProperties newProps = oldProps.deleteResources(kind, names); + if (newProps != oldProps) { doPutProperties(newProps); } return new TextBasedEdit(kind, EditType.DELETE, oldTexts, @@ -416,14 +402,9 @@ TextBasedEdit doRenameText(ResourceKind kind, QualName oldName, assert previous == null; newTexts.put(newName, text); // check if this affects the system properties - GrammarProperties oldProps = null; - GrammarProperties newProps = null; - List activeNames = getRecordedActiveNames(kind); - if (activeNames.remove(oldName)) { - oldProps = getProperties(); - newProps = getProperties().clone(); - activeNames.add(newName); - newProps.setActiveNames(kind, activeNames); + GrammarProperties oldProps = getProperties(); + GrammarProperties newProps = oldProps.renameResource(kind, oldName, newName); + if (newProps != oldProps) { doPutProperties(newProps); } return new TextBasedEdit(kind, EditType.RENAME, oldTexts, newTexts, oldProps, newProps); @@ -447,14 +428,9 @@ GraphBasedEdit doRenameGraph(ResourceKind kind, QualName oldName, this.marshaller.saveGraph(newGraph.toPlainGraph(), createFile(kind, newName)); deleteEmptyDirectories(oldFile.getParentFile()); // change the properties if there is a change in the enabled types - GrammarProperties oldProps = null; - GrammarProperties newProps = null; - List activeNames = getRecordedActiveNames(kind); - if (activeNames.remove(oldName)) { - oldProps = getProperties(); - newProps = oldProps.clone(); - activeNames.add(newName); - newProps.setActiveNames(kind, activeNames); + GrammarProperties oldProps = getProperties(); + GrammarProperties newProps = oldProps.renameResource(kind, oldName, newName); + if (newProps != oldProps) { doPutProperties(newProps); } return new GraphBasedEdit(kind, EditType.RENAME, Collections.singleton(oldGraph), @@ -731,19 +707,6 @@ public String toString() { return getName() + " - " + location; } - /** - * Returns a copy of the currently activated names of a given resource kind, - * as stored in the grammar properties. - */ - private List getRecordedActiveNames(ResourceKind kind) { - List result = new ArrayList<>(); - if (kind != RULE && kind != GROOVY && kind != PROPERTIES) { - result.addAll(getProperties().getActiveNames(kind)); - result.sort(null); - } - return result; - } - /** * Collects all aspect graphs from the {@link #file} directory with a given * extension, and a given role. From 370c5ecfdaee32bfc5589047a684532c5ce77dda Mon Sep 17 00:00:00 2001 From: rensink Date: Tue, 23 Jul 2024 17:48:49 +0200 Subject: [PATCH 2/2] Resolved gh issue #796 --- src/main/java/nl/utwente/groove/gui/tree/TypeTree.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/nl/utwente/groove/gui/tree/TypeTree.java b/src/main/java/nl/utwente/groove/gui/tree/TypeTree.java index 3d222af9b..74d26f283 100644 --- a/src/main/java/nl/utwente/groove/gui/tree/TypeTree.java +++ b/src/main/java/nl/utwente/groove/gui/tree/TypeTree.java @@ -342,7 +342,8 @@ private void addRelatedTypes(Set typeNodes, TypedEntryNode t Set relatedTypes = map.get(type); assert relatedTypes != null : String .format("Node type '%s' does not occur in type graph '%s'", type, map.keySet()); - for (TypeNode relType : relatedTypes) { + var orderedRelatedTypes = new TreeSet<>(relatedTypes); + for (TypeNode relType : orderedRelatedTypes) { // test if the node type label exists in the partial type graph if (typeNodes.contains(relType)) { TypedEntryNode subTypeNode = new TypedEntryNode(this, relType, false);