11/* @internal */
22namespace ts . Completions . PathCompletions {
3- export interface PathCompletion {
3+ export interface NameAndKind {
44 readonly name : string ;
55 readonly kind : ScriptElementKind . scriptElement | ScriptElementKind . directory | ScriptElementKind . externalModuleName ;
6+ }
7+ export interface PathCompletion extends NameAndKind {
68 readonly span : TextSpan ;
79 }
810 function createPathCompletion ( name : string , kind : PathCompletion [ "kind" ] , span : TextSpan ) : PathCompletion {
@@ -158,10 +160,10 @@ namespace ts.Completions.PathCompletions {
158160 for ( const path in paths ) {
159161 const patterns = paths [ path ] ;
160162 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 ) ) {
162164 // 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 ) ) ;
165167 }
166168 }
167169 }
@@ -188,22 +190,22 @@ namespace ts.Completions.PathCompletions {
188190
189191 function getCompletionsForPathMapping (
190192 path : string , patterns : ReadonlyArray < string > , fragment : string , baseUrl : string , fileExtensions : ReadonlyArray < string > , host : LanguageServiceHost ,
191- ) : ReadonlyArray < string > {
193+ ) : ReadonlyArray < NameAndKind > {
192194 if ( ! endsWith ( path , "*" ) ) {
193195 // 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 ;
195197 }
196198
197199 const pathPrefix = path . slice ( 0 , path . length - 1 ) ;
198200 if ( ! startsWith ( fragment , pathPrefix ) ) {
199- return [ pathPrefix ] ;
201+ return [ { name : pathPrefix , kind : ScriptElementKind . directory } ] ;
200202 }
201203
202204 const remainingFragment = fragment . slice ( pathPrefix . length ) ;
203205 return flatMap ( patterns , pattern => getModulesForPathsPattern ( remainingFragment , baseUrl , pattern , fileExtensions , host ) ) ;
204206 }
205207
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 {
207209 if ( ! host . readDirectory ) {
208210 return undefined ;
209211 }
@@ -234,14 +236,14 @@ namespace ts.Completions.PathCompletions {
234236 // doesn't support. For now, this is safer but slower
235237 const includeGlob = normalizedSuffix ? "**/*" : "./*" ;
236238
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 } ) ) ;
239241
240242 // 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 ) ;
243245 const inner = withoutStartAndEnd ( normalizedMatch , completePrefix , normalizedSuffix ) ;
244- return inner !== undefined ? removeLeadingDirectorySeparator ( removeFileExtension ( inner ) ) : undefined ;
246+ return inner !== undefined ? { name : removeLeadingDirectorySeparator ( removeFileExtension ( inner ) ) , kind } : undefined ;
245247 } ) ;
246248 }
247249
@@ -488,8 +490,8 @@ namespace ts.Completions.PathCompletions {
488490 return tryIOAndConsumeErrors ( host , host . getDirectories , directoryName ) || [ ] ;
489491 }
490492
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 ;
493495 }
494496
495497 function tryReadFile ( host : LanguageServiceHost , path : string ) : string | undefined {
0 commit comments