@@ -831,7 +831,8 @@ namespace ts.Completions {
831
831
// * |c|
832
832
// */
833
833
const lineStart = getLineStartPositionForPosition ( position , sourceFile ) ;
834
- const m = / ^ (?: [ * \s ] + | \s * \/ \* \* \s + ) ( @ ) ? $ / . exec (
834
+ // jsdoc tag will be listed if there is more than one whitespace after "*"
835
+ const m = / ^ (?: \s * (?: [ * \s ] + (? = \s ) ) ? \s + | \s * \/ \* \* \s + ) ( @ ) ? $ / . exec (
835
836
sourceFile . text . substring ( lineStart , position )
836
837
) ;
837
838
if ( m ) {
@@ -1271,6 +1272,7 @@ namespace ts.Completions {
1271
1272
function tryGetGlobalSymbols ( ) : boolean {
1272
1273
const result : GlobalsSearch = tryGetObjectLikeCompletionSymbols ( )
1273
1274
|| tryGetImportOrExportClauseCompletionSymbols ( )
1275
+ || tryGetLocalNamedExportCompletionSymbols ( )
1274
1276
|| tryGetConstructorCompletion ( )
1275
1277
|| tryGetClassLikeCompletionSymbols ( )
1276
1278
|| tryGetJsxCompletionSymbols ( )
@@ -1881,19 +1883,17 @@ namespace ts.Completions {
1881
1883
* export { | };
1882
1884
*
1883
1885
* Relevant symbols are stored in the captured 'symbols' variable.
1884
- *
1885
- * @returns true if 'symbols' was successfully populated; false otherwise.
1886
1886
*/
1887
1887
function tryGetImportOrExportClauseCompletionSymbols ( ) : GlobalsSearch {
1888
1888
// `import { |` or `import { a as 0, | }`
1889
1889
const namedImportsOrExports = contextToken && ( contextToken . kind === SyntaxKind . OpenBraceToken || contextToken . kind === SyntaxKind . CommaToken )
1890
1890
? tryCast ( contextToken . parent , isNamedImportsOrExports ) : undefined ;
1891
1891
if ( ! namedImportsOrExports ) return GlobalsSearch . Continue ;
1892
1892
1893
- // cursor is in an import clause
1894
- // try to show exported member for imported module
1893
+ // try to show exported member for imported/re-exported module
1895
1894
const { moduleSpecifier } = namedImportsOrExports . kind === SyntaxKind . NamedImports ? namedImportsOrExports . parent . parent : namedImportsOrExports . parent ;
1896
- const moduleSpecifierSymbol = typeChecker . getSymbolAtLocation ( moduleSpecifier ! ) ; // TODO: GH#18217
1895
+ if ( ! moduleSpecifier ) return namedImportsOrExports . kind === SyntaxKind . NamedImports ? GlobalsSearch . Fail : GlobalsSearch . Continue ;
1896
+ const moduleSpecifierSymbol = typeChecker . getSymbolAtLocation ( moduleSpecifier ) ; // TODO: GH#18217
1897
1897
if ( ! moduleSpecifierSymbol ) return GlobalsSearch . Fail ;
1898
1898
1899
1899
completionKind = CompletionKind . MemberLike ;
@@ -1904,6 +1904,36 @@ namespace ts.Completions {
1904
1904
return GlobalsSearch . Success ;
1905
1905
}
1906
1906
1907
+ /**
1908
+ * Adds local declarations for completions in named exports:
1909
+ *
1910
+ * export { | };
1911
+ *
1912
+ * Does not check for the absence of a module specifier (`export {} from "./other"`)
1913
+ * because `tryGetImportOrExportClauseCompletionSymbols` runs first and handles that,
1914
+ * preventing this function from running.
1915
+ */
1916
+ function tryGetLocalNamedExportCompletionSymbols ( ) : GlobalsSearch {
1917
+ const namedExports = contextToken && ( contextToken . kind === SyntaxKind . OpenBraceToken || contextToken . kind === SyntaxKind . CommaToken )
1918
+ ? tryCast ( contextToken . parent , isNamedExports )
1919
+ : undefined ;
1920
+
1921
+ if ( ! namedExports ) {
1922
+ return GlobalsSearch . Continue ;
1923
+ }
1924
+
1925
+ const localsContainer = findAncestor ( namedExports , or ( isSourceFile , isModuleDeclaration ) ) ! ;
1926
+ completionKind = CompletionKind . None ;
1927
+ isNewIdentifierLocation = false ;
1928
+ localsContainer . locals ?. forEach ( ( symbol , name ) => {
1929
+ symbols . push ( symbol ) ;
1930
+ if ( localsContainer . symbol ?. exports ?. has ( name ) ) {
1931
+ symbolToSortTextMap [ getSymbolId ( symbol ) ] = SortText . OptionalMember ;
1932
+ }
1933
+ } ) ;
1934
+ return GlobalsSearch . Success ;
1935
+ }
1936
+
1907
1937
/**
1908
1938
* Aggregates relevant symbols for completion in class declaration
1909
1939
* Relevant symbols are stored in the captured 'symbols' variable.
@@ -2299,7 +2329,7 @@ namespace ts.Completions {
2299
2329
}
2300
2330
}
2301
2331
2302
- // Set SortText to OptionalMember if it is an optinoal member
2332
+ // Set SortText to OptionalMember if it is an optional member
2303
2333
function setSortTextToOptionalMember ( ) {
2304
2334
symbols . forEach ( m => {
2305
2335
if ( m . flags & SymbolFlags . Optional ) {
0 commit comments