@@ -149,10 +149,10 @@ namespace ts.Completions.PathCompletions {
149
149
for ( const path in paths ) {
150
150
const patterns = paths [ path ] ;
151
151
if ( paths . hasOwnProperty ( path ) && patterns ) {
152
- for ( const pathCompletion of getCompletionsForPathMapping ( path , patterns , fragment , baseUrl , fileExtensions , host ) ) {
152
+ for ( const { name , kind } of getCompletionsForPathMapping ( path , patterns , fragment , baseUrl , fileExtensions , host ) ) {
153
153
// Path mappings may provide a duplicate way to get to something we've already added, so don't add again.
154
- if ( ! result . some ( entry => entry . name === pathCompletion ) ) {
155
- result . push ( createCompletionEntryForModule ( pathCompletion , ScriptElementKind . externalModuleName , span ) ) ;
154
+ if ( ! result . some ( entry => entry . name === name ) ) {
155
+ result . push ( createCompletionEntryForModule ( name , kind , span ) ) ;
156
156
}
157
157
}
158
158
}
@@ -177,24 +177,29 @@ namespace ts.Completions.PathCompletions {
177
177
return result ;
178
178
}
179
179
180
+ interface NameAndKind {
181
+ readonly name : string ;
182
+ readonly kind : ScriptElementKind . scriptElement | ScriptElementKind . directory ;
183
+ }
184
+
180
185
function getCompletionsForPathMapping (
181
186
path : string , patterns : ReadonlyArray < string > , fragment : string , baseUrl : string , fileExtensions : ReadonlyArray < string > , host : LanguageServiceHost ,
182
- ) : ReadonlyArray < string > {
187
+ ) : ReadonlyArray < NameAndKind > {
183
188
if ( ! endsWith ( path , "*" ) ) {
184
189
// For a path mapping "foo": ["/x/y/z.ts"], add "foo" itself as a completion.
185
- return ! stringContains ( path , "*" ) && startsWith ( path , fragment ) ? [ path ] : emptyArray ;
190
+ return ! stringContains ( path , "*" ) && startsWith ( path , fragment ) ? [ { name : path , kind : ScriptElementKind . directory } ] : emptyArray ;
186
191
}
187
192
188
193
const pathPrefix = path . slice ( 0 , path . length - 1 ) ;
189
194
if ( ! startsWith ( fragment , pathPrefix ) ) {
190
- return [ pathPrefix ] ;
195
+ return [ { name : pathPrefix , kind : ScriptElementKind . directory } ] ;
191
196
}
192
197
193
198
const remainingFragment = fragment . slice ( pathPrefix . length ) ;
194
199
return flatMap ( patterns , pattern => getModulesForPathsPattern ( remainingFragment , baseUrl , pattern , fileExtensions , host ) ) ;
195
200
}
196
201
197
- function getModulesForPathsPattern ( fragment : string , baseUrl : string , pattern : string , fileExtensions : ReadonlyArray < string > , host : LanguageServiceHost ) : string [ ] | undefined {
202
+ function getModulesForPathsPattern ( fragment : string , baseUrl : string , pattern : string , fileExtensions : ReadonlyArray < string > , host : LanguageServiceHost ) : ReadonlyArray < NameAndKind > | undefined {
198
203
if ( ! host . readDirectory ) {
199
204
return undefined ;
200
205
}
@@ -225,14 +230,14 @@ namespace ts.Completions.PathCompletions {
225
230
// doesn't support. For now, this is safer but slower
226
231
const includeGlob = normalizedSuffix ? "**/*" : "./*" ;
227
232
228
- const matches = tryReadDirectory ( host , baseDirectory , fileExtensions , /*exclude*/ undefined , [ includeGlob ] ) ;
229
- const directories = tryGetDirectories ( host , baseDirectory ) . map ( d => combinePaths ( baseDirectory , d ) ) ;
233
+ const matches = tryReadDirectory ( host , baseDirectory , fileExtensions , /*exclude*/ undefined , [ includeGlob ] ) . map < NameAndKind > ( name => ( { name , kind : ScriptElementKind . scriptElement } ) ) ;
234
+ const directories = tryGetDirectories ( host , baseDirectory ) . map ( d => combinePaths ( baseDirectory , d ) ) . map < NameAndKind > ( name => ( { name , kind : ScriptElementKind . directory } ) ) ;
230
235
231
236
// Trim away prefix and suffix
232
- return mapDefined ( concatenate ( matches , directories ) , match => {
233
- const normalizedMatch = normalizePath ( match ) ;
237
+ return mapDefined < NameAndKind , NameAndKind > ( concatenate ( matches , directories ) , ( { name , kind } ) => {
238
+ const normalizedMatch = normalizePath ( name ) ;
234
239
const inner = withoutStartAndEnd ( normalizedMatch , completePrefix , normalizedSuffix ) ;
235
- return inner !== undefined ? removeLeadingDirectorySeparator ( removeFileExtension ( inner ) ) : undefined ;
240
+ return inner !== undefined ? { name : removeLeadingDirectorySeparator ( removeFileExtension ( inner ) ) , kind } : undefined ;
236
241
} ) ;
237
242
}
238
243
@@ -489,8 +494,8 @@ namespace ts.Completions.PathCompletions {
489
494
return tryIOAndConsumeErrors ( host , host . getDirectories , directoryName ) || [ ] ;
490
495
}
491
496
492
- function tryReadDirectory ( host : LanguageServiceHost , path : string , extensions ?: ReadonlyArray < string > , exclude ?: ReadonlyArray < string > , include ?: ReadonlyArray < string > ) : string [ ] | undefined | undefined {
493
- return tryIOAndConsumeErrors ( host , host . readDirectory , path , extensions , exclude , include ) ;
497
+ function tryReadDirectory ( host : LanguageServiceHost , path : string , extensions ?: ReadonlyArray < string > , exclude ?: ReadonlyArray < string > , include ?: ReadonlyArray < string > ) : ReadonlyArray < string > {
498
+ return tryIOAndConsumeErrors ( host , host . readDirectory , path , extensions , exclude , include ) || emptyArray ;
494
499
}
495
500
496
501
function tryReadFile ( host : LanguageServiceHost , path : string ) : string | undefined {
0 commit comments