@@ -149,10 +149,10 @@ namespace ts.Completions.PathCompletions {
149149 for ( const path in paths ) {
150150 const patterns = paths [ path ] ;
151151 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 ) ) {
153153 // 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 ) ) ;
156156 }
157157 }
158158 }
@@ -177,24 +177,29 @@ namespace ts.Completions.PathCompletions {
177177 return result ;
178178 }
179179
180+ interface NameAndKind {
181+ readonly name : string ;
182+ readonly kind : ScriptElementKind . scriptElement | ScriptElementKind . directory ;
183+ }
184+
180185 function getCompletionsForPathMapping (
181186 path : string , patterns : ReadonlyArray < string > , fragment : string , baseUrl : string , fileExtensions : ReadonlyArray < string > , host : LanguageServiceHost ,
182- ) : ReadonlyArray < string > {
187+ ) : ReadonlyArray < NameAndKind > {
183188 if ( ! endsWith ( path , "*" ) ) {
184189 // 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 ;
186191 }
187192
188193 const pathPrefix = path . slice ( 0 , path . length - 1 ) ;
189194 if ( ! startsWith ( fragment , pathPrefix ) ) {
190- return [ pathPrefix ] ;
195+ return [ { name : pathPrefix , kind : ScriptElementKind . directory } ] ;
191196 }
192197
193198 const remainingFragment = fragment . slice ( pathPrefix . length ) ;
194199 return flatMap ( patterns , pattern => getModulesForPathsPattern ( remainingFragment , baseUrl , pattern , fileExtensions , host ) ) ;
195200 }
196201
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 {
198203 if ( ! host . readDirectory ) {
199204 return undefined ;
200205 }
@@ -225,14 +230,14 @@ namespace ts.Completions.PathCompletions {
225230 // doesn't support. For now, this is safer but slower
226231 const includeGlob = normalizedSuffix ? "**/*" : "./*" ;
227232
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 } ) ) ;
230235
231236 // 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 ) ;
234239 const inner = withoutStartAndEnd ( normalizedMatch , completePrefix , normalizedSuffix ) ;
235- return inner !== undefined ? removeLeadingDirectorySeparator ( removeFileExtension ( inner ) ) : undefined ;
240+ return inner !== undefined ? { name : removeLeadingDirectorySeparator ( removeFileExtension ( inner ) ) , kind } : undefined ;
236241 } ) ;
237242 }
238243
@@ -489,8 +494,8 @@ namespace ts.Completions.PathCompletions {
489494 return tryIOAndConsumeErrors ( host , host . getDirectories , directoryName ) || [ ] ;
490495 }
491496
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 ;
494499 }
495500
496501 function tryReadFile ( host : LanguageServiceHost , path : string ) : string | undefined {
0 commit comments