@@ -2,6 +2,7 @@ import { combineLatest, from, Observable } from 'rxjs'
2
2
import { map , switchMap } from 'rxjs/operators'
3
3
import { Location } from 'vscode-languageserver-types'
4
4
import { ReferenceParams , TextDocumentPositionParams , TextDocumentRegistrationOptions } from '../../protocol'
5
+ import { compact , flatten } from '../../util'
5
6
import { FeatureProviderRegistry } from './registry'
6
7
import { flattenAndCompact } from './util'
7
8
@@ -22,6 +23,24 @@ export class TextDocumentLocationProviderRegistry<
22
23
public getLocation ( params : P ) : Observable < L | L [ ] | null > {
23
24
return getLocation < P , L > ( this . providers , params )
24
25
}
26
+
27
+ public getLocationsWithExtensionID ( params : P ) : Observable < { extensionID : string ; location : L } [ ] | null > {
28
+ return getLocationsWithExtensionID < P , L > ( this . providersWithID , params )
29
+ }
30
+
31
+ /**
32
+ * List of providers with their associated extension ID
33
+ */
34
+ public readonly providersWithID : Observable <
35
+ { extensionID : string ; provider : ProvideTextDocumentLocationSignature < P , L > } [ ]
36
+ > = this . entries . pipe (
37
+ map ( providers =>
38
+ providers . map ( ( { provider, registrationOptions } ) => ( {
39
+ extensionID : registrationOptions . extensionID ,
40
+ provider,
41
+ } ) )
42
+ )
43
+ )
25
44
}
26
45
27
46
/**
@@ -62,6 +81,29 @@ export function getLocations<
62
81
)
63
82
}
64
83
84
+ /**
85
+ * Like getLocations, but includes the ID of the extension that provided each location result
86
+ */
87
+ export function getLocationsWithExtensionID <
88
+ P extends TextDocumentPositionParams = TextDocumentPositionParams ,
89
+ L extends Location = Location
90
+ > (
91
+ providersWithID : Observable < { extensionID : string ; provider : ProvideTextDocumentLocationSignature < P , L > } [ ] > ,
92
+ params : P
93
+ ) : Observable < { extensionID : string ; location : L } [ ] > {
94
+ return providersWithID . pipe (
95
+ switchMap ( providersWithID =>
96
+ combineLatest (
97
+ providersWithID . map ( ( { provider, extensionID } ) =>
98
+ provider ( params ) . pipe (
99
+ map ( r => flattenAndCompactNonNull ( [ r ] ) . map ( l => ( { extensionID, location : l } ) ) )
100
+ )
101
+ )
102
+ ) . pipe ( map ( flattenAndCompactNonNull ) )
103
+ )
104
+ )
105
+ }
106
+
65
107
/**
66
108
* Provides reference results from all extensions.
67
109
*
@@ -76,3 +118,8 @@ export class TextDocumentReferencesProviderRegistry extends TextDocumentLocation
76
118
return getLocations ( this . providers , params )
77
119
}
78
120
}
121
+
122
+ /** Flattens and compacts the argument. If it is null or if the result is empty, it returns null. */
123
+ function flattenAndCompactNonNull < T > ( value : ( T | T [ ] | null ) [ ] | null ) : T [ ] {
124
+ return value ? flatten ( compact ( value ) ) : [ ]
125
+ }
0 commit comments