@@ -1555,32 +1555,22 @@ namespace ts.Completions {
1555
1555
* @returns true if 'symbols' was successfully populated; false otherwise.
1556
1556
*/
1557
1557
function tryGetImportOrExportClauseCompletionSymbols ( ) : GlobalsSearch {
1558
- const namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion ( contextToken ) ;
1559
- if ( ! namedImportsOrExports ) return undefined ;
1558
+ // `import { |` or `import { a as 0, | }`
1559
+ const namedImportsOrExports = contextToken && ( contextToken . kind === SyntaxKind . OpenBraceToken || contextToken . kind === SyntaxKind . CommaToken )
1560
+ ? tryCast ( contextToken . parent , isNamedImportsOrExports ) : undefined ;
1561
+ if ( ! namedImportsOrExports ) return GlobalsSearch . Continue ;
1560
1562
1561
1563
// cursor is in an import clause
1562
1564
// try to show exported member for imported module
1563
- const declarationKind = namedImportsOrExports . kind === SyntaxKind . NamedImports ?
1564
- SyntaxKind . ImportDeclaration :
1565
- SyntaxKind . ExportDeclaration ;
1566
- const importOrExportDeclaration = < ImportDeclaration | ExportDeclaration > getAncestor ( namedImportsOrExports , declarationKind ) ;
1567
- const moduleSpecifier = importOrExportDeclaration . moduleSpecifier ;
1568
-
1569
- if ( ! moduleSpecifier ) {
1570
- return GlobalsSearch . Fail ;
1571
- }
1565
+ const { moduleSpecifier } = namedImportsOrExports . kind === SyntaxKind . NamedImports ? namedImportsOrExports . parent . parent : namedImportsOrExports . parent ;
1566
+ const moduleSpecifierSymbol = typeChecker . getSymbolAtLocation ( moduleSpecifier ) ;
1567
+ if ( ! moduleSpecifierSymbol ) return GlobalsSearch . Fail ;
1572
1568
1573
1569
completionKind = CompletionKind . MemberLike ;
1574
1570
isNewIdentifierLocation = false ;
1575
-
1576
- const moduleSpecifierSymbol = typeChecker . getSymbolAtLocation ( moduleSpecifier ) ;
1577
- if ( ! moduleSpecifierSymbol ) {
1578
- symbols = emptyArray ;
1579
- return GlobalsSearch . Fail ;
1580
- }
1581
-
1582
1571
const exports = typeChecker . getExportsAndPropertiesOfModule ( moduleSpecifierSymbol ) ;
1583
- symbols = filterNamedImportOrExportCompletionItems ( exports , namedImportsOrExports . elements ) ;
1572
+ const existing = arrayToSet < ImportOrExportSpecifier > ( namedImportsOrExports . elements , n => isCurrentlyEditingNode ( n ) ? undefined : ( n . propertyName || n . name ) . escapedText ) ;
1573
+ symbols = exports . filter ( e => e . escapedName !== InternalSymbolName . Default && ! existing . get ( e . escapedName ) ) ;
1584
1574
return GlobalsSearch . Success ;
1585
1575
}
1586
1576
@@ -1648,26 +1638,6 @@ namespace ts.Completions {
1648
1638
return undefined ;
1649
1639
}
1650
1640
1651
- /**
1652
- * Returns the containing list of named imports or exports of a context token,
1653
- * on the condition that one exists and that the context implies completion should be given.
1654
- */
1655
- function tryGetNamedImportsOrExportsForCompletion ( contextToken : Node ) : NamedImportsOrExports {
1656
- if ( contextToken ) {
1657
- switch ( contextToken . kind ) {
1658
- case SyntaxKind . OpenBraceToken : // import { |
1659
- case SyntaxKind . CommaToken : // import { a as 0, |
1660
- switch ( contextToken . parent . kind ) {
1661
- case SyntaxKind . NamedImports :
1662
- case SyntaxKind . NamedExports :
1663
- return < NamedImportsOrExports > contextToken . parent ;
1664
- }
1665
- }
1666
- }
1667
-
1668
- return undefined ;
1669
- }
1670
-
1671
1641
function isConstructorParameterCompletion ( node : Node ) : boolean {
1672
1642
return ! ! node . parent && isParameter ( node . parent ) && isConstructorDeclaration ( node . parent . parent )
1673
1643
&& ( isParameterPropertyModifier ( node . kind ) || isDeclarationName ( node ) ) ;
@@ -1911,31 +1881,6 @@ namespace ts.Completions {
1911
1881
return false ;
1912
1882
}
1913
1883
1914
- /**
1915
- * Filters out completion suggestions for named imports or exports.
1916
- *
1917
- * @param exportsOfModule The list of symbols which a module exposes.
1918
- * @param namedImportsOrExports The list of existing import/export specifiers in the import/export clause.
1919
- *
1920
- * @returns Symbols to be suggested at an import/export clause, barring those whose named imports/exports
1921
- * do not occur at the current position and have not otherwise been typed.
1922
- */
1923
- function filterNamedImportOrExportCompletionItems ( exportsOfModule : Symbol [ ] , namedImportsOrExports : ReadonlyArray < ImportOrExportSpecifier > ) : Symbol [ ] {
1924
- const existingImportsOrExports = createUnderscoreEscapedMap < boolean > ( ) ;
1925
-
1926
- for ( const element of namedImportsOrExports ) {
1927
- // If this is the current item we are editing right now, do not filter it out
1928
- if ( isCurrentlyEditingNode ( element ) ) {
1929
- continue ;
1930
- }
1931
-
1932
- const name = element . propertyName || element . name ;
1933
- existingImportsOrExports . set ( name . escapedText , true ) ;
1934
- }
1935
-
1936
- return exportsOfModule . filter ( e => e . escapedName !== InternalSymbolName . Default && ! existingImportsOrExports . get ( e . escapedName ) ) ;
1937
- }
1938
-
1939
1884
/**
1940
1885
* Filters out completion suggestions for named imports or exports.
1941
1886
*
0 commit comments