Skip to content

Commit cb5d3a2

Browse files
committed
feat: Refactor the references support
References collect by appearance position in text, not just a name. Closes #702 Signed-off-by: Anton Grigorev <[email protected]>
1 parent 3a0a2e8 commit cb5d3a2

20 files changed

+326
-951
lines changed

server/src/main/java/com/broadcom/lsp/cobol/domain/modules/ServiceModule.java

+1-13
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ protected void configure() {
6262
bind(WatcherService.class).to(WatcherServiceImpl.class);
6363
bind(FileSystemService.class).to(WorkspaceFileService.class);
6464
bind(SubroutineService.class).to(SubroutineServiceImpl.class);
65+
bind(Occurrences.class).to(ElementOccurrences.class);
6566

6667
bindFormations();
6768
bindCompletions();
68-
bindReferences();
6969
bindCodeActions();
7070

7171
bindInterceptor(
@@ -103,18 +103,6 @@ private void bindCompletions() {
103103
bind(CompletionStorage.class).annotatedWith(named("Snippets")).to(Snippets.class);
104104
}
105105

106-
private void bindReferences() {
107-
bind(Occurrences.class).to(SemanticElementOccurrences.class);
108-
Multibinder<SemanticLocations> referenceBinding =
109-
newSetBinder(binder(), SemanticLocations.class);
110-
referenceBinding.addBinding().to(VariableLocations.class);
111-
referenceBinding.addBinding().to(ParagraphLocations.class);
112-
referenceBinding.addBinding().to(SectionLocations.class);
113-
referenceBinding.addBinding().to(CopybookLocations.class);
114-
referenceBinding.addBinding().to(ConstantLocations.class);
115-
referenceBinding.addBinding().to(SubroutineLocations.class);
116-
}
117-
118106
private void bindCodeActions() {
119107
bind(CodeActions.class);
120108
Multibinder<CodeActionProvider> codeActionBinding =

server/src/main/java/com/broadcom/lsp/cobol/service/delegates/references/ConstantLocations.java

-48
This file was deleted.

server/src/main/java/com/broadcom/lsp/cobol/service/delegates/references/CopybookLocations.java

-44
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright (c) 2020 Broadcom.
3+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
4+
*
5+
* This program and the accompanying materials are made
6+
* available under the terms of the Eclipse Public License 2.0
7+
* which is available at https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Broadcom, Inc. - initial API and implementation
13+
*
14+
*/
15+
package com.broadcom.lsp.cobol.service.delegates.references;
16+
17+
import com.broadcom.lsp.cobol.core.semantics.outline.RangeUtils;
18+
import com.broadcom.lsp.cobol.service.CobolDocumentModel;
19+
import com.broadcom.lsp.cobol.service.delegates.validations.AnalysisResult;
20+
import lombok.NonNull;
21+
import lombok.Value;
22+
import org.eclipse.lsp4j.*;
23+
24+
import javax.annotation.Nullable;
25+
import java.util.*;
26+
import java.util.function.Function;
27+
import java.util.function.Predicate;
28+
import java.util.stream.Collectors;
29+
import java.util.stream.Stream;
30+
31+
/**
32+
* This occurrences provider resolves the requests for the semantic elements based on its positions.
33+
*/
34+
public class ElementOccurrences implements Occurrences {
35+
@Override
36+
public @NonNull List<Location> findDefinitions(@Nullable CobolDocumentModel document, @NonNull TextDocumentPositionParams position) {
37+
if (document == null) return Collections.emptyList();
38+
return findElementByPosition(document, position).definitions;
39+
}
40+
41+
@Override
42+
public @NonNull List<Location> findReferences(@Nullable CobolDocumentModel document, @NonNull TextDocumentPositionParams position, @NonNull ReferenceContext context) {
43+
if (document == null) return Collections.emptyList();
44+
Element element = findElementByPosition(document, position);
45+
List<Location> references = element.usages;
46+
if (context.isIncludeDeclaration()) {
47+
references = new ArrayList<>(references);
48+
references.addAll(element.definitions);
49+
}
50+
return references;
51+
}
52+
53+
@Override
54+
public @NonNull List<DocumentHighlight> findHighlights(@Nullable CobolDocumentModel document, @NonNull TextDocumentPositionParams position) {
55+
if (document == null) return Collections.emptyList();
56+
return findReferences(document, position, new ReferenceContext(true)).stream()
57+
.filter(byUri(position))
58+
.map(toDocumentHighlight())
59+
.collect(Collectors.toList());
60+
}
61+
62+
private static Element findElementByPosition(CobolDocumentModel document, TextDocumentPositionParams position) {
63+
AnalysisResult result = document.getAnalysisResult();
64+
return findElementByPosition(result.getVariableDefinitions(), result.getVariableUsages(), position)
65+
.or(() -> findElementByPosition(result.getParagraphDefinitions(), result.getParagraphUsages(), position))
66+
.or(() -> findElementByPosition(result.getSectionDefinitions(), result.getSectionUsages(), position))
67+
.or(() -> findElementByPosition(result.getConstantDefinitions(), result.getConstantUsages(), position))
68+
.or(() -> findElementByPosition(result.getCopybookDefinitions(), result.getCopybookUsages(), position))
69+
.or(() -> findElementByPosition(result.getSubroutineDefinitions(), result.getSubroutineUsages(), position))
70+
.orElseGet(() -> new Element(List.of(), List.of()));
71+
}
72+
73+
@Value
74+
private static class Element {
75+
List<Location> definitions;
76+
List<Location> usages;
77+
}
78+
79+
private static Optional<Element> findElementByPosition(
80+
Map<String, List<Location>> definitions,
81+
Map<String, List<Location>> usages,
82+
TextDocumentPositionParams position) {
83+
return Stream.concat(definitions.entrySet().stream(), usages.entrySet().stream())
84+
.filter(entry -> entry.getValue().stream().anyMatch(location -> isInside(position, location)))
85+
.findFirst()
86+
.map(Map.Entry::getKey)
87+
.map(name -> new Element(definitions.getOrDefault(name, List.of()), usages.getOrDefault(name, List.of())));
88+
}
89+
90+
static boolean isInside(TextDocumentPositionParams position, Location location) {
91+
return position.getTextDocument().getUri().equals(location.getUri())
92+
&& !RangeUtils.isBefore(position.getPosition(), location.getRange().getStart())
93+
&& !RangeUtils.isAfter(position.getPosition(), location.getRange().getEnd());
94+
}
95+
96+
@NonNull
97+
private static Predicate<Location> byUri(@NonNull TextDocumentPositionParams position) {
98+
return location -> location.getUri().equals(position.getTextDocument().getUri());
99+
}
100+
101+
@NonNull
102+
private static Function<Location, DocumentHighlight> toDocumentHighlight() {
103+
return location -> new DocumentHighlight(location.getRange(), DocumentHighlightKind.Text);
104+
}
105+
}

server/src/main/java/com/broadcom/lsp/cobol/service/delegates/references/ParagraphLocations.java

-44
This file was deleted.

server/src/main/java/com/broadcom/lsp/cobol/service/delegates/references/SectionLocations.java

-45
This file was deleted.

0 commit comments

Comments
 (0)