Skip to content

Commit 60b6ca2

Browse files
committed
Implement related node selection generically
1 parent 396f6be commit 60b6ca2

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
3939
import net.sourceforge.pmd.lang.symboltable.Scope;
4040
import net.sourceforge.pmd.lang.symboltable.ScopedNode;
41+
import net.sourceforge.pmd.util.designerbindings.RelatedNodesSelector;
4142
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;
4243

4344
import com.sun.javafx.fxml.builder.ProxyBuilder;
@@ -305,7 +306,11 @@ public static Optional<String> stackTraceToXPath(Throwable e) {
305306
}
306307

307308

308-
public static List<NameOccurrence> getNameOccurrences(ScopedNode node) {
309+
public static RelatedNodesSelector getDefaultRelatedNodesSelector() {
310+
return node -> node instanceof ScopedNode ? getNameOccurrences((ScopedNode) node) : Collections.emptyList();
311+
}
312+
313+
private static List<Node> getNameOccurrences(ScopedNode node) {
309314

310315
// For MethodNameDeclaration the scope is the method scope, which is not the scope it is declared
311316
// in but the scope it declares! That means that getDeclarations().get(declaration) returns null
@@ -336,6 +341,7 @@ public static List<NameOccurrence> getNameOccurrences(ScopedNode node) {
336341

337342
return usages;
338343
})
344+
.map(it -> it.stream().<Node>map(NameOccurrence::getLocation).collect(Collectors.toList()))
339345
.orElse(Collections.emptyList());
340346
}
341347

src/main/java/net/sourceforge/pmd/util/fxdesigner/util/controls/NodeEditionCodeArea.java

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.util.Objects;
2222
import java.util.Optional;
2323
import java.util.function.IntFunction;
24-
import java.util.stream.Collectors;
2524

2625
import org.checkerframework.checker.nullness.qual.NonNull;
2726
import org.fxmisc.richtext.LineNumberFactory;
@@ -34,9 +33,11 @@
3433
import org.reactfx.value.Var;
3534

3635
import net.sourceforge.pmd.lang.Language;
36+
import net.sourceforge.pmd.lang.LanguageVersion;
37+
import net.sourceforge.pmd.lang.LanguageVersionHandler;
3738
import net.sourceforge.pmd.lang.ast.Node;
38-
import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
39-
import net.sourceforge.pmd.lang.symboltable.ScopedNode;
39+
import net.sourceforge.pmd.util.designerbindings.DesignerBindings;
40+
import net.sourceforge.pmd.util.designerbindings.RelatedNodesSelector;
4041
import net.sourceforge.pmd.util.fxdesigner.SourceEditorController;
4142
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;
4243
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource;
@@ -84,28 +85,37 @@ public class NodeEditionCodeArea extends HighlightLayerCodeArea<StyleLayerIds> i
8485
private final Var<Node> currentFocusNode = Var.newSimpleVar(null);
8586
private final Var<List<Node>> currentRuleResults = Var.newSimpleVar(Collections.emptyList());
8687
private final Var<List<Node>> currentErrorNodes = Var.newSimpleVar(Collections.emptyList());
87-
private final Var<List<NameOccurrence>> currentNameOccurrences = Var.newSimpleVar(Collections.emptyList());
88+
private final Var<List<Node>> currentRelatedNodes = Var.newSimpleVar(Collections.emptyList());
8889
private final DesignerRoot designerRoot;
8990
private final EventSource<NodeSelectionEvent> selectionEvts = new EventSource<>();
9091

91-
92+
private final Val<RelatedNodesSelector> relatedNodesSelector;
9293

9394
/** Only provided for scenebuilder, not used at runtime. */
9495
public NodeEditionCodeArea() {
9596
super(StyleLayerIds.class);
96-
designerRoot = null;
97+
this.designerRoot = null;
98+
this.relatedNodesSelector = null;
9799
}
98100

99101
public NodeEditionCodeArea(@NamedArg("designerRoot") DesignerRoot root) {
100102
super(StyleLayerIds.class);
101103

102104
this.designerRoot = root;
105+
this.relatedNodesSelector =
106+
root.getService(DesignerRoot.AST_MANAGER)
107+
.languageVersionProperty()
108+
.map(LanguageVersion::getLanguageVersionHandler)
109+
.map(LanguageVersionHandler::getDesignerBindings)
110+
.map(DesignerBindings::getRelatedNodesSelector)
111+
.orElseConst(DesignerUtil.getDefaultRelatedNodesSelector());
112+
103113

104114
setParagraphGraphicFactory(defaultLineNumberFactory());
105115

106116
currentRuleResultsProperty().values().subscribe(this::highlightXPathResults);
107117
currentErrorNodesProperty().values().subscribe(this::highlightErrorNodes);
108-
currentNameOccurrences.values().subscribe(this::highlightNameOccurrences);
118+
currentRelatedNodesProperty().values().subscribe(this::highlightRelatedNodes);
109119

110120
initNodeSelectionHandling(designerRoot, selectionEvts, true);
111121

@@ -251,8 +261,8 @@ public final Var<List<Node>> currentErrorNodesProperty() {
251261
}
252262

253263

254-
public Var<List<NameOccurrence>> currentNameOccurrencesProperty() {
255-
return currentNameOccurrences;
264+
public Var<List<Node>> currentRelatedNodesProperty() {
265+
return currentRelatedNodes;
256266
}
257267

258268

@@ -263,8 +273,8 @@ private void highlightXPathResults(Collection<? extends Node> nodes) {
263273

264274

265275
/** Highlights name occurrences (secondary highlight). */
266-
private void highlightNameOccurrences(Collection<? extends NameOccurrence> occs) {
267-
styleNodes(occs.stream().map(NameOccurrence::getLocation).collect(Collectors.toList()), StyleLayerIds.NAME_OCCURRENCE, true);
276+
private void highlightRelatedNodes(Collection<? extends Node> occs) {
277+
styleNodes(occs, StyleLayerIds.NAME_OCCURRENCE, true);
268278
}
269279

270280

@@ -305,10 +315,13 @@ public void setFocusNode(final Node node, DataHolder options) {
305315
// editor is only restyled if the selection has changed
306316
Platform.runLater(() -> styleNodes(node == null ? emptyList() : singleton(node), StyleLayerIds.FOCUS, true));
307317

308-
if (node instanceof ScopedNode) {
309-
// not null as well
310-
Platform.runLater(() -> highlightNameOccurrences(DesignerUtil.getNameOccurrences((ScopedNode) node)));
311-
}
318+
Platform.runLater(() -> relatedNodesSelector.ifPresent(selector -> {
319+
List<Node> nodes = selector.getHighlightedNodesWhenSelecting(node);
320+
highlightRelatedNodes(Objects.requireNonNull(nodes,
321+
"RelatedNodesSelection for language "
322+
+ globalLanguageProperty().getValue().getName()
323+
+ " returned null"));
324+
}));
312325
}
313326

314327

0 commit comments

Comments
 (0)