From 9b54cbc5ea84e8f26a2e0f0f2a80e3d2211e2e8a Mon Sep 17 00:00:00 2001 From: Efratror Date: Sun, 19 Mar 2023 08:38:03 +0100 Subject: [PATCH] Add reference searching --- .../mode/java/lsp/PdeSymbolFinder.java | 48 ++++++++++++++++++- .../mode/java/lsp/PdeTextDocumentService.java | 33 +++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/java/src/processing/mode/java/lsp/PdeSymbolFinder.java b/java/src/processing/mode/java/lsp/PdeSymbolFinder.java index 919c4e62d..e8f850bc6 100644 --- a/java/src/processing/mode/java/lsp/PdeSymbolFinder.java +++ b/java/src/processing/mode/java/lsp/PdeSymbolFinder.java @@ -18,8 +18,7 @@ import processing.app.SketchCode; import processing.mode.java.PreprocSketch; import processing.mode.java.SketchInterval; -import static processing.mode.java.ASTUtils.getSimpleNameAt; -import static processing.mode.java.ASTUtils.resolveBinding; +import static processing.mode.java.ASTUtils.*; public class PdeSymbolFinder { @@ -85,6 +84,51 @@ public class PdeSymbolFinder { } + /** + * searches all reference nodes for a provided character offset + * + * @param ps processed sketch, for AST-nodes and sketch + * @param javaOffset character offset for the node we want to look up + * + * @return Location list of all references found, else an empty list. + */ + static public List searchReference(PreprocSketch ps, + int javaOffset + ) { + ASTNode root = ps.compilationUnit; + + SimpleName simpleName = getSimpleNameAt(root, javaOffset, javaOffset); + if (simpleName == null) { + System.out.println("no simple name found at location"); + return Collections.emptyList(); + } + + IBinding binding = resolveBinding(simpleName); + if (binding == null) { + System.out.println("binding not resolved"); + return Collections.emptyList(); + } + + // Find usages + String bindingKey = binding.getKey(); + List referenceIntervals = + findAllOccurrences(ps.compilationUnit, bindingKey).stream() + .map(ps::mapJavaToSketch) + // remove occurrences which fall into generated header + .filter(ps::inRange) + // remove empty intervals (happens when occurence was inserted) + .filter(in -> in.startPdeOffset < in.stopPdeOffset) + .collect(java.util.stream.Collectors.toList()); + + List referenceList = new ArrayList<>(); + for (SketchInterval referenceInterval: referenceIntervals) { + referenceList.add(findLocation(ps, referenceInterval)); + } + + return referenceList; + } + + /** * Looks for a location(range) for a given sketchInterval * diff --git a/java/src/processing/mode/java/lsp/PdeTextDocumentService.java b/java/src/processing/mode/java/lsp/PdeTextDocumentService.java index 4ac167ab8..89f8340dc 100644 --- a/java/src/processing/mode/java/lsp/PdeTextDocumentService.java +++ b/java/src/processing/mode/java/lsp/PdeTextDocumentService.java @@ -17,6 +17,7 @@ import org.eclipse.lsp4j.DocumentFormattingParams; import org.eclipse.lsp4j.TextEdit; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.LocationLink; +import org.eclipse.lsp4j.ReferenceParams; import java.util.Collections; import java.net.URI; @@ -137,4 +138,36 @@ class PdeTextDocumentService implements TextDocumentService { ); } + + @Override + public CompletableFuture> references( + ReferenceParams params + ) { + + System.out.println("searching for references"); + URI uri = URI.create(params.getTextDocument().getUri()); + int lineNumber = params.getPosition().getLine(); + int colNumber = params.getPosition().getCharacter(); + + Optional adapterOptional = pls.getAdapter(uri); + if (adapterOptional.isEmpty()) { + System.out.println("pde adapter not found"); + return CompletableFutures.computeAsync(_x -> Collections.emptyList()); + } + PdeAdapter adapter = adapterOptional.get(); + PreprocSketch preprocSketch = adapter.ps; + + Optional optionalJavaOffset = + adapter.findJavaOffset(uri, lineNumber, colNumber); + if (optionalJavaOffset.isEmpty()) { + System.out.println("javaOffset not found"); + return CompletableFutures.computeAsync(_x -> (Collections.emptyList())); + } + + int javaOffset = optionalJavaOffset.get(); + List locations; + locations = PdeSymbolFinder.searchReference(preprocSketch, javaOffset); + + return CompletableFutures.computeAsync(_x -> locations); + } }