21
21
import com .intellij .openapi .project .Project ;
22
22
import com .intellij .openapi .project .ProjectManager ;
23
23
import com .intellij .openapi .vfs .VirtualFile ;
24
+ import com .intellij .psi .PsiFile ;
24
25
import com .intellij .util .concurrency .AppExecutorUtil ;
25
26
import com .redhat .devtools .lsp4ij .client .features .LSPClientFeatures ;
26
27
import com .redhat .devtools .lsp4ij .internal .editor .EditorFeatureManager ;
@@ -153,11 +154,13 @@ void sendDidOpenAndRefreshEditorFeatureForOpenedFiles(@NotNull LanguageServerDef
153
154
@ NotNull Project project ) {
154
155
VirtualFile [] files = FileEditorManager .getInstance (project ).getOpenFiles ();
155
156
for (VirtualFile file : files ) {
156
- sendDidOpenAndRefreshEditorFeatureFor (file , serverDefinition );
157
+ // TODO : revisit that
158
+ PsiFile psiFile = LSPIJUtils .getPsiFile (file , project );
159
+ sendDidOpenAndRefreshEditorFeatureFor (psiFile , serverDefinition );
157
160
}
158
161
}
159
162
160
- private void sendDidOpenAndRefreshEditorFeatureFor (@ NotNull VirtualFile file ,
163
+ private void sendDidOpenAndRefreshEditorFeatureFor (@ NotNull PsiFile file ,
161
164
@ NotNull LanguageServerDefinition serverDefinition ) {
162
165
ReadAction .nonBlocking (() -> {
163
166
// Try to send a textDocument/didOpen notification if the file is associated to the language server definition
@@ -185,13 +188,13 @@ private void sendDidOpenAndRefreshEditorFeatureFor(@NotNull VirtualFile file,
185
188
* @param filter the filter.
186
189
* @return true if the given file matches one of started language server with the given filter and false otherwise.
187
190
*/
188
- public boolean hasAny (@ NotNull VirtualFile file ,
191
+ public boolean hasAny (@ NotNull PsiFile file ,
189
192
@ NotNull Predicate <LanguageServerWrapper > filter ) {
190
193
var startedServers = getStartedServers ();
191
194
if (startedServers .isEmpty ()) {
192
195
return false ;
193
196
}
194
- MatchedLanguageServerDefinitions mappings = getMatchedLanguageServerDefinitions (file , project , true );
197
+ MatchedLanguageServerDefinitions mappings = getMatchedLanguageServerDefinitions (file , true );
195
198
if (mappings == MatchedLanguageServerDefinitions .NO_MATCH ) {
196
199
return false ;
197
200
}
@@ -243,19 +246,19 @@ public boolean hasAny(@NotNull VirtualFile file,
243
246
}
244
247
245
248
@ NotNull
246
- public CompletableFuture <@ NotNull List <LanguageServerItem >> getLanguageServers (@ NotNull VirtualFile file ,
249
+ public CompletableFuture <@ NotNull List <LanguageServerItem >> getLanguageServers (@ NotNull PsiFile file ,
247
250
@ Nullable Predicate <LSPClientFeatures > beforeStartingServerFilter ,
248
251
@ Nullable Predicate <LSPClientFeatures > afterStartingServerFilter ) {
249
252
return getLanguageServers (file , beforeStartingServerFilter , afterStartingServerFilter , null );
250
253
}
251
254
252
255
@ NotNull
253
- CompletableFuture <@ NotNull List <LanguageServerItem >> getLanguageServers (@ NotNull VirtualFile file ,
256
+ CompletableFuture <@ NotNull List <LanguageServerItem >> getLanguageServers (@ NotNull PsiFile psiFile ,
254
257
@ Nullable Predicate <LSPClientFeatures > beforeStartingServerFilter ,
255
258
@ Nullable Predicate <LSPClientFeatures > afterStartingServerFilter ,
256
259
@ Nullable LanguageServerDefinition matchServerDefinition ) {
257
260
// Collect started (or not) language servers which matches the given file.
258
- CompletableFuture <Collection <LanguageServerWrapper >> matchedServers = getMatchedLanguageServersWrappers (file , matchServerDefinition , beforeStartingServerFilter );
261
+ CompletableFuture <Collection <LanguageServerWrapper >> matchedServers = getMatchedLanguageServersWrappers (psiFile , matchServerDefinition , beforeStartingServerFilter );
259
262
var matchedServersNow = matchedServers .getNow (Collections .emptyList ());
260
263
if (matchedServers .isDone () && matchedServersNow .isEmpty ()) {
261
264
// None language servers matches the given file
@@ -269,7 +272,8 @@ public boolean hasAny(@NotNull VirtualFile file,
269
272
// LSP document listener to manage didOpen, didChange, etc.
270
273
boolean writeAccessAllowed = ApplicationManager .getApplication ().isWriteAccessAllowed ();
271
274
boolean readAccessAllowed = ApplicationManager .getApplication ().isReadAccessAllowed ();
272
- Document document = readAccessAllowed || (!writeAccessAllowed ) ? LSPIJUtils .getDocument (file ) : null ;
275
+ Document document = readAccessAllowed || (!writeAccessAllowed ) ? LSPIJUtils .getDocument (psiFile ) : null ;
276
+ var file = psiFile .getVirtualFile ();
273
277
274
278
// Try to get document, languageId information (used by didOpen) for each matched language server wrapper
275
279
// since here we should be in Read Action allowed
@@ -356,10 +360,10 @@ public void projectClosing(Project project) {
356
360
357
361
@ NotNull
358
362
private CompletableFuture <Collection <LanguageServerWrapper >> getMatchedLanguageServersWrappers (
359
- @ NotNull VirtualFile file ,
363
+ @ NotNull PsiFile file ,
360
364
@ Nullable LanguageServerDefinition matchServerDefinition ,
361
365
@ Nullable Predicate <LSPClientFeatures > beforeStartingServerFilter ) {
362
- MatchedLanguageServerDefinitions mappings = getMatchedLanguageServerDefinitions (file , project , false );
366
+ MatchedLanguageServerDefinitions mappings = getMatchedLanguageServerDefinitions (file , false );
363
367
if (mappings == MatchedLanguageServerDefinitions .NO_MATCH ) {
364
368
// There are no mapping for the given file
365
369
return CompletableFuture .completedFuture (Collections .emptyList ());
@@ -393,22 +397,23 @@ private CompletableFuture<Collection<LanguageServerWrapper>> getMatchedLanguageS
393
397
/**
394
398
* Get or create a language server wrapper for the given server definitions and add then to the given matched servers.
395
399
*
396
- * @param file the file.
400
+ * @param psiFile the file.
397
401
* @param serverDefinitions the server definitions.
398
402
* @param matchedServers the list to update with get/created language server.
399
403
* @param beforeStartingServerFilter
400
404
*/
401
- private void collectLanguageServersFromDefinition (@ Nullable VirtualFile file ,
405
+ private void collectLanguageServersFromDefinition (@ Nullable PsiFile psiFile ,
402
406
@ NotNull Set <LanguageServerDefinition > serverDefinitions ,
403
407
@ NotNull Set <LanguageServerWrapper > matchedServers ,
404
408
@ Nullable Predicate <LSPClientFeatures > beforeStartingServerFilter ) {
409
+ var file = psiFile .getVirtualFile ();
405
410
synchronized (startedServers ) {
406
411
for (var serverDefinition : serverDefinitions ) {
407
412
boolean useExistingServer = false ;
408
413
// Loop for started language servers
409
414
for (var startedServer : startedServers ) {
410
415
if (startedServer .getServerDefinition ().equals (serverDefinition )
411
- && (file == null || startedServer .canOperate (file ))
416
+ && (psiFile == null || startedServer .canOperate (file ))
412
417
&& (beforeStartingServerFilter == null || beforeStartingServerFilter .test (startedServer .getClientFeatures ()))) {
413
418
// A started language server match the file, use it
414
419
matchedServers .add (startedServer );
@@ -466,26 +471,25 @@ public CompletableFuture<Set<LanguageServerDefinition>> getAsyncMatched() {
466
471
/**
467
472
* Returns the matched language server definitions for the given file.
468
473
*
469
- * @param file the file.
470
- * @param fileProject the file project.
474
+ * @param psiFile the file.
471
475
* @param ignoreMatch true if {@link DocumentMatcher} must be ignored when mapping matches the given file and false otherwise.
472
476
* @return the matched language server definitions for the given file.
473
477
*/
474
- private MatchedLanguageServerDefinitions getMatchedLanguageServerDefinitions (@ NotNull VirtualFile file ,
475
- @ NotNull Project fileProject ,
478
+ private MatchedLanguageServerDefinitions getMatchedLanguageServerDefinitions (@ NotNull PsiFile psiFile ,
476
479
boolean ignoreMatch ) {
477
480
481
+ var file = psiFile .getVirtualFile ();
478
482
Set <LanguageServerDefinition > syncMatchedDefinitions = null ;
479
483
Set <LanguageServerFileAssociation > asyncMatchedDefinitions = null ;
480
484
481
485
// look for running language servers via content-type
482
486
Queue <Object > languages = new LinkedList <>();
483
487
Set <Object > processedContentTypes = new HashSet <>();
484
- Language language = LSPIJUtils . getFileLanguage ( file , project );
488
+ Language language = psiFile . getLanguage ( );
485
489
if (language != null ) {
486
490
languages .add (language );
487
491
}
488
- FileType fileType = file .getFileType ();
492
+ FileType fileType = psiFile .getFileType ();
489
493
languages .add (fileType );
490
494
491
495
while (!languages .isEmpty ()) {
@@ -502,7 +506,7 @@ private MatchedLanguageServerDefinitions getMatchedLanguageServerDefinitions(@No
502
506
}
503
507
// Loop for server/language mapping
504
508
for (LanguageServerFileAssociation mapping : LanguageServersRegistry .getInstance ()
505
- .findLanguageServerDefinitionFor (currentLanguage , currentFileType , file )) {
509
+ .findLanguageServerDefinitionFor (currentLanguage , currentFileType , file . getName () )) {
506
510
if (mapping == null || !mapping .isEnabled (project ) || (syncMatchedDefinitions != null && syncMatchedDefinitions .contains (mapping .getServerDefinition ()))) {
507
511
// the mapping is disabled
508
512
// or the server definition has been already added
@@ -514,7 +518,7 @@ private MatchedLanguageServerDefinitions getMatchedLanguageServerDefinitions(@No
514
518
}
515
519
syncMatchedDefinitions .add (mapping .getServerDefinition ());
516
520
} else {
517
- if (mapping .shouldBeMatchedAsynchronously (fileProject )) {
521
+ if (mapping .shouldBeMatchedAsynchronously (project )) {
518
522
// Async mapping
519
523
// Mapping must be done asynchronously because the match of DocumentMatcher of the mapping need to be done asynchronously
520
524
// This usecase comes from for instance when custom match need to collect classes from the Java project and requires read only action.
@@ -524,7 +528,7 @@ private MatchedLanguageServerDefinitions getMatchedLanguageServerDefinitions(@No
524
528
asyncMatchedDefinitions .add (mapping );
525
529
} else {
526
530
// Sync mapping
527
- if (match (file , fileProject , mapping )) {
531
+ if (match (file , project , mapping )) {
528
532
if (syncMatchedDefinitions == null ) {
529
533
syncMatchedDefinitions = new HashSet <>();
530
534
}
@@ -543,7 +547,7 @@ private MatchedLanguageServerDefinitions getMatchedLanguageServerDefinitions(@No
543
547
async = CompletableFuture .allOf (asyncMatchedDefinitions
544
548
.stream ()
545
549
.map (mapping -> mapping
546
- .matchAsync (file , fileProject )
550
+ .matchAsync (file , project )
547
551
.thenApply (result -> {
548
552
if (result ) {
549
553
serverDefinitions .add (mapping .getServerDefinition ());
0 commit comments