25
25
import org .eclipse .lsp .cobol .service .delegates .communications .Communications ;
26
26
27
27
import java .util .*;
28
- import java .util .concurrent .CompletableFuture ;
29
- import java .util .concurrent .Executor ;
30
- import java .util .concurrent .Executors ;
28
+ import java .util .concurrent .*;
31
29
32
30
/**
33
31
* Asynchronous analysis
@@ -42,9 +40,10 @@ public class AsyncAnalysisService {
42
40
private final Communications communications ;
43
41
44
42
private final Map <String , CompletableFuture <CobolDocumentModel >> analysisResults = Collections .synchronizedMap (new HashMap <>());
45
- private final Map <String , Long > analysisResultsRevisions = Collections .synchronizedMap (new HashMap <>());
43
+ private final Map <String , Integer > analysisResultsRevisions = Collections .synchronizedMap (new HashMap <>());
44
+ private final Map <String , CompletableFuture <CobolDocumentModel >> lastResults = new ConcurrentHashMap <>();
46
45
47
- private final Executor analysisExecutor = Executors .newSingleThreadExecutor ();
46
+ private final Executor analysisExecutor = Executors .newCachedThreadPool ();
48
47
49
48
@ Inject
50
49
public AsyncAnalysisService (DocumentModelService documentModelService ,
@@ -61,30 +60,47 @@ public AsyncAnalysisService(DocumentModelService documentModelService,
61
60
/**
62
61
* Fetch last analysis result or wait for it if analysis is in progress.
63
62
*
64
- * @param uri URI of the source
63
+ * @param documentUri URI of the source
65
64
* @return DocumentModel with analysis result or Option.empty() if analysis was not
66
65
* triggered at the time of method call.
67
66
*/
68
- public Optional <CompletableFuture <CobolDocumentModel >> fetchLastResultOrAnalyzeDocument (String uri ) {
69
- CobolDocumentModel documentModel = documentModelService .get (uri );
70
- if (documentModel == null || documentModel .getLastAnalysisResult () == null ) {
71
- return Optional .ofNullable (analysisResults .get (makeId (uri , analysisResultsRevisions .get (uri ))));
72
- }
73
- return Optional .of (CompletableFuture .completedFuture (documentModel ));
67
+ public Optional <CompletableFuture <CobolDocumentModel >> fetchLastResultOrAnalyzeDocument (String documentUri ) {
68
+ return Optional .ofNullable (lastResults .computeIfAbsent (documentUri , uri -> {
69
+ CobolDocumentModel documentModel = documentModelService .get (uri );
70
+ return documentModel == null || documentModel .getLastAnalysisResult () == null
71
+ ? analysisResults .get (makeId (uri , analysisResultsRevisions .get (uri )))
72
+ : CompletableFuture .completedFuture (documentModel );
73
+ }));
74
74
}
75
75
76
76
/**
77
- * Schedule an analysis
77
+ * Schedule an analysis last known revision of the file will be assumed or 0 if none
78
78
*
79
79
* @param uri source URI
80
80
* @param text content
81
81
* @param open Is document just opened, or it's reanalyse request
82
82
* @return document model with analysis result
83
83
*/
84
84
public synchronized CompletableFuture <CobolDocumentModel > scheduleAnalysis (String uri , String text , boolean open ) {
85
- Long currentRevision = analysisResultsRevisions .compute (uri , (k , v ) -> (v == null ? 0 : v ) + 1 );
85
+ return scheduleAnalysis (uri , text , analysisResultsRevisions .getOrDefault (uri , 0 ), open );
86
+ }
87
+
88
+ /**
89
+ * Schedule an analysis
90
+ *
91
+ * @param uri source URI
92
+ * @param text content
93
+ * @param currentRevision the document currentRevision
94
+ * @param open Is document just opened, or it's reanalyse request
95
+ * @return document model with analysis result
96
+ */
97
+ public synchronized CompletableFuture <CobolDocumentModel > scheduleAnalysis (String uri , String text , Integer currentRevision , boolean open ) {
86
98
String id = makeId (uri , currentRevision );
99
+ analysisResultsRevisions .put (uri , currentRevision );
87
100
return analysisResults .computeIfAbsent (id , u -> CompletableFuture .supplyAsync (() -> {
101
+ if (currentRevision < analysisResultsRevisions .get (uri )) {
102
+ return null ;
103
+ }
88
104
LOG .debug ("[analyzeDocumentWithCopybooks] Start analysis: " + uri );
89
105
90
106
try {
@@ -101,7 +117,7 @@ public synchronized CompletableFuture<CobolDocumentModel> scheduleAnalysis(Strin
101
117
}, analysisExecutor ));
102
118
}
103
119
104
- private static String makeId (String uri , Long revision ) {
120
+ private static String makeId (String uri , Integer revision ) {
105
121
return revision + "#" + uri ;
106
122
}
107
123
@@ -114,7 +130,7 @@ public void reanalyseOpenedPrograms() {
114
130
LOG .info ("Cache invalidated" );
115
131
documentModelService .getAllOpened ()
116
132
.stream ().filter (d -> !analysisService .isCopybook (d .getUri (), d .getText ()))
117
- .forEach (doc -> scheduleAnalysis (doc .getUri (), doc .getText (), false ));
133
+ .forEach (doc -> scheduleAnalysis (doc .getUri (), doc .getText (), analysisResultsRevisions . get ( doc . getUri ()), false ));
118
134
}
119
135
120
136
/**
@@ -124,8 +140,27 @@ public void reanalyseOpenedPrograms() {
124
140
*/
125
141
public void cancelAnalysis (String uri ) {
126
142
analysisService .stopAnalysis (uri );
127
- communications .notifyProgressEnd (uri );
128
143
LOG .debug ("[stopAnalysis] Document " + uri + " publish diagnostic: " + documentModelService .getOpenedDiagnostic ());
129
144
communications .publishDiagnostics (documentModelService .getOpenedDiagnostic ());
130
145
}
146
+
147
+ /**
148
+ * Creates LSP Event dependency
149
+ *
150
+ * @param uri url of document to wait
151
+ * @return LspEventDependency object
152
+ */
153
+ public LspEventDependency createDependencyOn (String uri ) {
154
+ return () -> {
155
+ CobolDocumentModel doc = documentModelService .get (uri );
156
+ if (doc == null ) {
157
+ return false ;
158
+ }
159
+ if (analysisService .isCopybook (uri , doc .getText ())) {
160
+ return true ;
161
+ }
162
+ return doc .getLastAnalysisResult () != null ;
163
+ };
164
+ }
165
+
131
166
}
0 commit comments