Skip to content

Commit cee3b08

Browse files
authored
fix: Skip analysis for not used copybook (#1996)
fix: Skip analysis for not used copybook
1 parent 813703f commit cee3b08

File tree

19 files changed

+262
-311
lines changed

19 files changed

+262
-311
lines changed

clients/cobol-lsp-vscode-extension/src/services/util/FSUtils.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ function globSearch(
158158
pattern = pattern + suffix;
159159
const result = globSync(pattern, { cwd, dot: true });
160160
// TODO report the case with more then one copybook fit the pattern.
161-
return result[0] ? path.resolve(cwd, result[0]) : undefined;
161+
return result[0]
162+
? normalizePath(fs.realpathSync.native(path.resolve(cwd, result[0])))
163+
: undefined;
162164
}
163165

164166
export function getProgramNameFromUri(

server/dialect-daco/src/test/java/org/eclipse/lsp/cobol/dialects/daco/utils/UseCaseInitializerService.java

-3
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
import org.eclipse.lsp.cobol.service.SubroutineServiceImpl;
3636
import org.eclipse.lsp.cobol.service.WatcherService;
3737
import org.eclipse.lsp.cobol.service.WatcherServiceImpl;
38-
import org.eclipse.lsp.cobol.service.copybooks.CopybookReferenceRepo;
39-
import org.eclipse.lsp.cobol.service.copybooks.CopybookReferenceRepoImpl;
4038
import org.eclipse.lsp.cobol.service.copybooks.CopybookServiceImpl;
4139
import org.eclipse.lsp.cobol.service.delegates.validations.CobolLanguageEngineFacade;
4240
import org.eclipse.lsp.cobol.test.UseCaseInitializer;
@@ -80,7 +78,6 @@ protected void configure() {
8078
bind(TextPreprocessor.class).to(TextPreprocessorImpl.class);
8179
bind(CleanerPreprocessor.class).to(TextPreprocessorImpl.class);
8280
bind(WatcherService.class).to(WatcherServiceImpl.class);
83-
bind(CopybookReferenceRepo.class).toInstance(new CopybookReferenceRepoImpl());
8481
bind(DialectDiscoveryService.class).to(ExplicitDialectDiscoveryService.class);
8582
}
8683
});

server/dialect-idms/src/test/java/org/eclipse/lsp/cobol/dialects/idms/utils/UseCaseInitializerService.java

-3
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636
import org.eclipse.lsp.cobol.service.SubroutineServiceImpl;
3737
import org.eclipse.lsp.cobol.service.WatcherService;
3838
import org.eclipse.lsp.cobol.service.WatcherServiceImpl;
39-
import org.eclipse.lsp.cobol.service.copybooks.CopybookReferenceRepo;
40-
import org.eclipse.lsp.cobol.service.copybooks.CopybookReferenceRepoImpl;
4139
import org.eclipse.lsp.cobol.service.copybooks.CopybookServiceImpl;
4240
import org.eclipse.lsp.cobol.service.delegates.actions.CodeActions;
4341
import org.eclipse.lsp.cobol.service.delegates.actions.FindCopybookCommand;
@@ -85,7 +83,6 @@ protected void configure() {
8583
bind(TextPreprocessor.class).to(TextPreprocessorImpl.class);
8684
bind(CleanerPreprocessor.class).to(TextPreprocessorImpl.class);
8785
bind(WatcherService.class).to(WatcherServiceImpl.class);
88-
bind(CopybookReferenceRepo.class).toInstance(new CopybookReferenceRepoImpl());
8986
bind(DialectDiscoveryService.class).to(ExplicitDialectDiscoveryService.class);
9087
bind(CodeActions.class);
9188
Multibinder<CodeActionProvider> codeActionBinding =

server/engine/src/main/java/org/eclipse/lsp/cobol/core/engine/symbols/SymbolsRepository.java

-13
Original file line numberDiff line numberDiff line change
@@ -108,19 +108,6 @@ public static Optional<Context> findElementByPosition(String uri, AnalysisResult
108108
.map(SymbolsRepository::constructElementsExcludingImplicits);
109109
}
110110

111-
// /**
112-
// * Remove program related symbols
113-
// *
114-
// * @param documentUri the program uri
115-
// */
116-
// public void reset(String documentUri) {
117-
// programSymbols.keySet().stream()
118-
// .filter(k -> k.endsWith("%" + documentUri))
119-
// .collect(Collectors.toList())
120-
// .forEach(programSymbols::remove);
121-
// programSymbols.remove(documentUri);
122-
// }
123-
124111
private static Context constructElementsExcludingImplicits(Context ctx) {
125112
List<Location> definitions =
126113
ctx.getDefinitions().stream().filter(uriNotImplicit()).collect(Collectors.toList());

server/engine/src/main/java/org/eclipse/lsp/cobol/domain/modules/ServiceModule.java

-3
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@
3838
import org.eclipse.lsp.cobol.service.copybooks.CopybookIdentificationCombinedStrategy;
3939
import org.eclipse.lsp.cobol.service.copybooks.CopybookIdentificationService;
4040
import org.eclipse.lsp.cobol.service.copybooks.CopybookIdentificationServiceBasedOnContent;
41-
import org.eclipse.lsp.cobol.service.copybooks.CopybookReferenceRepo;
42-
import org.eclipse.lsp.cobol.service.copybooks.CopybookReferenceRepoImpl;
4341
import org.eclipse.lsp.cobol.common.copybook.CopybookService;
4442
import org.eclipse.lsp.cobol.service.copybooks.CopybookServiceImpl;
4543
import org.eclipse.lsp.cobol.common.action.CodeActionProvider;
@@ -89,7 +87,6 @@ protected void configure() {
8987
bind(Occurrences.class).to(ElementOccurrences.class);
9088
bind(HoverProvider.class).to(VariableHover.class);
9189
bind(CFASTBuilder.class).to(CFASTBuilderImpl.class);
92-
bind(CopybookReferenceRepo.class).to(CopybookReferenceRepoImpl.class);
9390
bind(CopybookIdentificationService.class)
9491
.annotatedWith(Names.named("contentStrategy"))
9592
.to(CopybookIdentificationServiceBasedOnContent.class);

server/engine/src/main/java/org/eclipse/lsp/cobol/service/AnalysisService.java

+9-26
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,12 @@
2323
import org.eclipse.lsp.cobol.common.AnalysisConfig;
2424
import org.eclipse.lsp.cobol.common.AnalysisResult;
2525
import org.eclipse.lsp.cobol.common.LanguageEngineFacade;
26-
import org.eclipse.lsp.cobol.common.copybook.CopybookModel;
2726
import org.eclipse.lsp.cobol.common.copybook.CopybookProcessingMode;
28-
import org.eclipse.lsp.cobol.common.copybook.CopybookService;
2927
import org.eclipse.lsp.cobol.common.model.tree.Node;
3028
import org.eclipse.lsp.cobol.common.utils.ThreadInterruptionUtil;
3129
import org.eclipse.lsp.cobol.domain.databus.api.DataBusBroker;
3230
import org.eclipse.lsp.cobol.domain.databus.model.AnalysisFinishedEvent;
3331
import org.eclipse.lsp.cobol.service.copybooks.CopybookIdentificationService;
34-
import org.eclipse.lsp.cobol.service.copybooks.CopybookReferenceRepo;
3532
import org.eclipse.lsp.cobol.service.delegates.communications.Communications;
3633
import org.eclipse.lsp.cobol.service.delegates.completions.Completions;
3734
import org.eclipse.lsp.cobol.service.delegates.formations.Formations;
@@ -45,6 +42,7 @@
4542
import java.time.format.DateTimeFormatter;
4643
import java.util.Collections;
4744
import java.util.List;
45+
import java.util.Set;
4846
import java.util.concurrent.CountDownLatch;
4947

5048
import static java.lang.String.format;
@@ -65,8 +63,6 @@ class AnalysisService {
6563
private final ConfigurationService configurationService;
6664
private final SyncProvider syncProvider;
6765
private final CopybookIdentificationService copybookIdentificationService;
68-
private final CopybookReferenceRepo copybookReferenceRepo;
69-
private final CopybookService copybookService;
7066
private final CountDownLatch waitConfig = new CountDownLatch(1);
7167
private List<String> copybookExtensions;
7268
private final Completions completions;
@@ -85,8 +81,6 @@ class AnalysisService {
8581
ConfigurationService configurationService,
8682
SyncProvider syncProvider,
8783
@Named("combinedStrategy") CopybookIdentificationService copybookIdentificationService,
88-
CopybookReferenceRepo copybookReferenceRepo,
89-
CopybookService copybookService,
9084
Completions completions,
9185
Occurrences occurrences,
9286
Formations formations,
@@ -99,8 +93,6 @@ class AnalysisService {
9993
this.configurationService = configurationService;
10094
this.syncProvider = syncProvider;
10195
this.copybookIdentificationService = copybookIdentificationService;
102-
this.copybookReferenceRepo = copybookReferenceRepo;
103-
this.copybookService = copybookService;
10496
this.completions = completions;
10597
this.occurrences = occurrences;
10698
this.formations = formations;
@@ -191,8 +183,8 @@ public void reanalyzeDocument(String uri, String text) {
191183

192184
if (isCopybook(uri, text)) {
193185
communications.logGeneralMessage(MessageType.Log, now() + "[reanalyzeDocument] Document " + uri + " treated as a copy");
194-
updateCopybook(uri, text);
195-
reanalyseOpenedPrograms();
186+
Set<String> affectedOpenedPrograms = documentService.findAffectedDocumentsForCopybook(uri, (d) -> !isCopybook(d.getUri(), d.getText()));
187+
reanalysePrograms(affectedOpenedPrograms);
196188
} else {
197189
communications.logGeneralMessage(MessageType.Log, now() + "[reanalyzeDocument] Document " + uri + " treated as a program");
198190
analyzeDocumentWithCopybooks(uri, text);
@@ -300,27 +292,18 @@ private void doAnalysis(String uri, String text) {
300292
}
301293
}
302294

303-
private void updateCopybook(String uri, String text) {
304-
copybookReferenceRepo
305-
.getCopybookUsageReference(uri)
306-
.forEach(
307-
val -> {
308-
CopybookModel copybookModel =
309-
new CopybookModel(
310-
val.getCopybookId(),
311-
val.getCopybookName(),
312-
uri,
313-
text);
314-
this.copybookService.store(copybookModel, true);
315-
});
316-
}
317-
318295
public void reanalyseOpenedPrograms() {
319296
documentService.getAllOpened()
320297
.stream().filter(d -> !isCopybook(d.getUri(), d.getText()))
321298
.forEach(doc -> analyzeDocumentWithCopybooks(doc.getUri(), doc.getText()));
322299
}
323300

301+
private void reanalysePrograms(Set<String> programs) {
302+
documentService.getAll(programs)
303+
.stream().filter(d -> !isCopybook(d.getUri(), d.getText()))
304+
.forEach(doc -> analyzeDocumentWithCopybooks(doc.getUri(), doc.getText()));
305+
}
306+
324307
private String createDescriptiveErrorMessage(String action, String uri) {
325308
return format("An exception thrown while applying %s for %s:", action, uri);
326309
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright (c) 2022 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 org.eclipse.lsp.cobol.service;
16+
17+
import com.google.inject.Singleton;
18+
19+
import java.io.File;
20+
import java.util.*;
21+
22+
/**
23+
* Provides API to search for COBOL programs that refers a copybooks file.
24+
*/
25+
@Singleton
26+
class CopybookReferenceRepo {
27+
28+
private final Map<String, Set<String>> copybookRef = new HashMap<>();
29+
30+
/**
31+
* Gives all the usage references of a copybook URI.
32+
*
33+
* @param copybookUri is a URI of a copybook
34+
* @return a set of all reference of passed copybook URI
35+
*/
36+
public Set<String> getCopybookUsageReference(String copybookUri) {
37+
Set<String> result = new HashSet<>();
38+
getReferences(copybookUri, result);
39+
return result;
40+
}
41+
42+
/** Clears all copybook references. */
43+
public void clearReferences() {
44+
this.copybookRef.clear();
45+
}
46+
47+
/**
48+
* Stores the references of cobol programs which refers a copybook.
49+
*
50+
* @param documentUri Cobol document (program or copybook) that refers the copybook
51+
* @param copybookUri copybook uri
52+
*/
53+
public void storeCopybookUsageReference(String documentUri, String copybookUri) {
54+
Set<String> copybookUsageRef =
55+
copybookRef.computeIfAbsent(copybookUri, k -> new HashSet<>());
56+
copybookUsageRef.add(documentUri);
57+
copybookRef.put(copybookUri, copybookUsageRef);
58+
}
59+
60+
private void getReferences(String copybookUri, Set<String> result) {
61+
copybookRef.entrySet().stream()
62+
.filter(entry -> Objects.nonNull(entry.getKey()))
63+
.filter(entry -> new File(entry.getKey()).equals(new File(copybookUri)))
64+
.map(Map.Entry::getValue)
65+
.flatMap(Collection::stream)
66+
.filter(d -> !result.contains(d))
67+
.forEach(d -> {
68+
result.add(d);
69+
getReferences(d, result);
70+
});
71+
}
72+
}

server/engine/src/main/java/org/eclipse/lsp/cobol/service/DocumentModelService.java

+65-32
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@
1515
package org.eclipse.lsp.cobol.service;
1616

1717
import com.google.common.collect.ImmutableList;
18+
import com.google.inject.Inject;
1819
import com.google.inject.Singleton;
1920
import lombok.Synchronized;
2021
import org.eclipse.lsp.cobol.common.AnalysisResult;
22+
import org.eclipse.lsp.cobol.common.model.NodeType;
23+
import org.eclipse.lsp.cobol.common.model.tree.CopyNode;
2124
import org.eclipse.lsp.cobol.service.utils.BuildOutlineTreeFromSyntaxTree;
2225
import org.eclipse.lsp4j.Diagnostic;
2326

24-
import java.util.List;
25-
import java.util.Map;
26-
import java.util.Optional;
27+
import java.util.*;
2728
import java.util.concurrent.ConcurrentHashMap;
29+
import java.util.function.Predicate;
2830
import java.util.stream.Collectors;
2931

3032
/**
@@ -34,6 +36,12 @@
3436
class DocumentModelService {
3537
private final Map<String, CobolDocumentModel> docs = new ConcurrentHashMap<>();
3638
private final DiagnosticRepo diagnosticRepo = new DiagnosticRepo();
39+
private final CopybookReferenceRepo copybookReferenceRepo;
40+
41+
@Inject
42+
DocumentModelService(CopybookReferenceRepo copybookReferenceRepo) {
43+
this.copybookReferenceRepo = copybookReferenceRepo;
44+
}
3745

3846
/**
3947
* Mark the document as opened and stores document text
@@ -47,16 +55,6 @@ public void openDocument(String uri, String text) {
4755
documentModel.setOpened(true);
4856
}
4957

50-
/**
51-
* Returns available diagnostic for the document
52-
* @param uri - document uri
53-
* @return list of diagnostic
54-
*/
55-
@Synchronized
56-
public List<Diagnostic> getDiagnostics(String uri) {
57-
return diagnosticRepo.get(uri);
58-
}
59-
6058
/**
6159
* Returns document model object
6260
* @param uri - document uri
@@ -78,6 +76,11 @@ public void processAnalysisResult(String uri, AnalysisResult analysisResult) {
7876
d.setAnalysisResult(analysisResult);
7977
diagnosticRepo.put(analysisResult.getDiagnostics());
8078
d.setOutlineResult(BuildOutlineTreeFromSyntaxTree.convert(analysisResult.getRootNode(), uri));
79+
analysisResult.getRootNode().getDepthFirstStream()
80+
.filter(n -> n.getNodeType() == NodeType.COPY)
81+
.filter(n -> n instanceof CopyNode)
82+
.map(CopyNode.class::cast)
83+
.forEach(n -> copybookReferenceRepo.storeCopybookUsageReference(n.getNameLocation().getUri(), n.getUri()));
8184
});
8285
}
8386

@@ -133,26 +136,17 @@ public boolean isDocumentSynced(String uri) {
133136
*/
134137
@Synchronized
135138
public Map<String, List<Diagnostic>> getOpenedDiagnostic() {
136-
return docs.values().stream()
137-
.collect(Collectors.toMap(CobolDocumentModel::getUri, d -> {
138-
List<Diagnostic> diagnostics = diagnosticRepo.get(d.getUri());
139-
if (!d.isOpened() || diagnostics == null) {
140-
return ImmutableList.of();
141-
}
142-
return diagnostics;
143-
}));
144-
}
139+
Map<String, List<Diagnostic>> result = new HashMap<>();
140+
docs.forEach((key, value) -> {
141+
List<Diagnostic> diagnostics = diagnosticRepo.get(value.getUri());
142+
if (diagnostics != null && value.isOpened()) {
143+
result.put(key, diagnostics);
144+
} else {
145+
result.put(key, ImmutableList.of());
146+
}
147+
});
145148

146-
@Synchronized
147-
public Map<String, List<Diagnostic>> getAllDiagnostic() {
148-
return docs.values().stream()
149-
.collect(Collectors.toMap(CobolDocumentModel::getUri, d -> {
150-
List<Diagnostic> diagnostics = diagnosticRepo.get(d.getUri());
151-
if (!d.isOpened() || diagnostics == null) {
152-
return ImmutableList.of();
153-
}
154-
return diagnostics;
155-
}));
149+
return result;
156150
}
157151

158152
/**
@@ -171,4 +165,43 @@ public void updateDocument(String uri, String text) {
171165
});
172166
}
173167

168+
/**
169+
* Collects all documents with given uri list
170+
* @param programs - the uri list
171+
* @return a list of documents
172+
*/
173+
@Synchronized
174+
public List<CobolDocumentModel> getAll(Set<String> programs) {
175+
return programs.stream().map(docs::get)
176+
.filter(Objects::nonNull)
177+
.collect(Collectors.toList());
178+
}
179+
180+
/**
181+
* Updates copybook and returns all affected opened programs filtered by predicate
182+
* @param uri - copybook uri
183+
* @param predicate - filtering predicate for programs
184+
* @return set of affected opened programs
185+
*/
186+
@Synchronized
187+
public Set<String> findAffectedDocumentsForCopybook(String uri, Predicate<CobolDocumentModel> predicate) {
188+
Set<String> affectedPrograms = new HashSet<>();
189+
copybookReferenceRepo
190+
.getCopybookUsageReference(uri)
191+
.forEach(
192+
curi -> {
193+
if (Optional.ofNullable(get(curi)).map(CobolDocumentModel::isOpened).orElse(false)) {
194+
affectedPrograms.add(curi);
195+
}
196+
});
197+
198+
// Add all not synced programs
199+
affectedPrograms.addAll(docs.values().stream()
200+
.filter(d -> !d.isDocumentSynced())
201+
.filter(predicate)
202+
.map(CobolDocumentModel::getUri)
203+
.collect(Collectors.toList()));
204+
205+
return affectedPrograms;
206+
}
174207
}

0 commit comments

Comments
 (0)