1
1
/* @internal */
2
2
namespace ts . Completions . PathCompletions {
3
- export interface PathCompletion {
3
+ export interface NameAndKind {
4
4
readonly name : string ;
5
5
readonly kind : ScriptElementKind . scriptElement | ScriptElementKind . directory | ScriptElementKind . externalModuleName ;
6
+ }
7
+ export interface PathCompletion extends NameAndKind {
6
8
readonly span : TextSpan ;
7
9
}
8
10
function createPathCompletion ( name : string , kind : PathCompletion [ "kind" ] , span : TextSpan ) : PathCompletion {
@@ -158,10 +160,10 @@ namespace ts.Completions.PathCompletions {
158
160
for ( const path in paths ) {
159
161
const patterns = paths [ path ] ;
160
162
if ( paths . hasOwnProperty ( path ) && patterns ) {
161
- for ( const pathCompletion of getCompletionsForPathMapping ( path , patterns , fragment , baseUrl , fileExtensions , host ) ) {
163
+ for ( const { name , kind } of getCompletionsForPathMapping ( path , patterns , fragment , baseUrl , fileExtensions , host ) ) {
162
164
// Path mappings may provide a duplicate way to get to something we've already added, so don't add again.
163
- if ( ! result . some ( entry => entry . name === pathCompletion ) ) {
164
- result . push ( createPathCompletion ( pathCompletion , ScriptElementKind . externalModuleName , span ) ) ;
165
+ if ( ! result . some ( entry => entry . name === name ) ) {
166
+ result . push ( createPathCompletion ( name , kind , span ) ) ;
165
167
}
166
168
}
167
169
}
@@ -188,22 +190,22 @@ namespace ts.Completions.PathCompletions {
188
190
189
191
function getCompletionsForPathMapping (
190
192
path : string , patterns : ReadonlyArray < string > , fragment : string , baseUrl : string , fileExtensions : ReadonlyArray < string > , host : LanguageServiceHost ,
191
- ) : ReadonlyArray < string > {
193
+ ) : ReadonlyArray < NameAndKind > {
192
194
if ( ! endsWith ( path , "*" ) ) {
193
195
// For a path mapping "foo": ["/x/y/z.ts"], add "foo" itself as a completion.
194
- return ! stringContains ( path , "*" ) && startsWith ( path , fragment ) ? [ path ] : emptyArray ;
196
+ return ! stringContains ( path , "*" ) && startsWith ( path , fragment ) ? [ { name : path , kind : ScriptElementKind . directory } ] : emptyArray ;
195
197
}
196
198
197
199
const pathPrefix = path . slice ( 0 , path . length - 1 ) ;
198
200
if ( ! startsWith ( fragment , pathPrefix ) ) {
199
- return [ pathPrefix ] ;
201
+ return [ { name : pathPrefix , kind : ScriptElementKind . directory } ] ;
200
202
}
201
203
202
204
const remainingFragment = fragment . slice ( pathPrefix . length ) ;
203
205
return flatMap ( patterns , pattern => getModulesForPathsPattern ( remainingFragment , baseUrl , pattern , fileExtensions , host ) ) ;
204
206
}
205
207
206
- function getModulesForPathsPattern ( fragment : string , baseUrl : string , pattern : string , fileExtensions : ReadonlyArray < string > , host : LanguageServiceHost ) : string [ ] | undefined {
208
+ function getModulesForPathsPattern ( fragment : string , baseUrl : string , pattern : string , fileExtensions : ReadonlyArray < string > , host : LanguageServiceHost ) : ReadonlyArray < NameAndKind > | undefined {
207
209
if ( ! host . readDirectory ) {
208
210
return undefined ;
209
211
}
@@ -234,14 +236,14 @@ namespace ts.Completions.PathCompletions {
234
236
// doesn't support. For now, this is safer but slower
235
237
const includeGlob = normalizedSuffix ? "**/*" : "./*" ;
236
238
237
- const matches = tryReadDirectory ( host , baseDirectory , fileExtensions , /*exclude*/ undefined , [ includeGlob ] ) ;
238
- const directories = tryGetDirectories ( host , baseDirectory ) . map ( d => combinePaths ( baseDirectory , d ) ) ;
239
+ const matches = tryReadDirectory ( host , baseDirectory , fileExtensions , /*exclude*/ undefined , [ includeGlob ] ) . map < NameAndKind > ( name => ( { name , kind : ScriptElementKind . scriptElement } ) ) ;
240
+ const directories = tryGetDirectories ( host , baseDirectory ) . map ( d => combinePaths ( baseDirectory , d ) ) . map < NameAndKind > ( name => ( { name , kind : ScriptElementKind . directory } ) ) ;
239
241
240
242
// Trim away prefix and suffix
241
- return mapDefined ( concatenate ( matches , directories ) , match => {
242
- const normalizedMatch = normalizePath ( match ) ;
243
+ return mapDefined < NameAndKind , NameAndKind > ( concatenate ( matches , directories ) , ( { name , kind } ) => {
244
+ const normalizedMatch = normalizePath ( name ) ;
243
245
const inner = withoutStartAndEnd ( normalizedMatch , completePrefix , normalizedSuffix ) ;
244
- return inner !== undefined ? removeLeadingDirectorySeparator ( removeFileExtension ( inner ) ) : undefined ;
246
+ return inner !== undefined ? { name : removeLeadingDirectorySeparator ( removeFileExtension ( inner ) ) , kind } : undefined ;
245
247
} ) ;
246
248
}
247
249
@@ -488,8 +490,8 @@ namespace ts.Completions.PathCompletions {
488
490
return tryIOAndConsumeErrors ( host , host . getDirectories , directoryName ) || [ ] ;
489
491
}
490
492
491
- function tryReadDirectory ( host : LanguageServiceHost , path : string , extensions ?: ReadonlyArray < string > , exclude ?: ReadonlyArray < string > , include ?: ReadonlyArray < string > ) : string [ ] | undefined | undefined {
492
- return tryIOAndConsumeErrors ( host , host . readDirectory , path , extensions , exclude , include ) ;
493
+ function tryReadDirectory ( host : LanguageServiceHost , path : string , extensions ?: ReadonlyArray < string > , exclude ?: ReadonlyArray < string > , include ?: ReadonlyArray < string > ) : ReadonlyArray < string > {
494
+ return tryIOAndConsumeErrors ( host , host . readDirectory , path , extensions , exclude , include ) || emptyArray ;
493
495
}
494
496
495
497
function tryReadFile ( host : LanguageServiceHost , path : string ) : string | undefined {
0 commit comments