@@ -1506,15 +1506,6 @@ namespace ts.Completions {
15061506 return GlobalsSearch . Success ;
15071507 }
15081508
1509- // Set SortText to OptionalMember if it is an optinoal member
1510- function setSortTextToOptionalMember ( ) {
1511- symbols . forEach ( m => {
1512- if ( SymbolDisplay . getSymbolModifiers ( m ) === "optional" ) {
1513- symbolToSortTextMap [ getSymbolId ( m ) ] = symbolToSortTextMap [ getSymbolId ( m ) ] || SortText . OptionalMember ;
1514- }
1515- } ) ;
1516- }
1517-
15181509 /**
15191510 * Aggregates relevant symbols for completion in import clauses and export clauses
15201511 * whose declarations have a module specifier; for instance, symbols will be aggregated for
@@ -1884,7 +1875,7 @@ namespace ts.Completions {
18841875 return contextualMemberSymbols ;
18851876 }
18861877
1887- const membersDeclaredBySpreadAssignment : Symbol [ ] = [ ] ;
1878+ const membersDeclaredBySpreadAssignment = createMap < boolean > ( ) ;
18881879 const existingMemberNames = createUnderscoreEscapedMap < boolean > ( ) ;
18891880 for ( const m of existingMembers ) {
18901881 // Ignore omitted expressions for missing members
@@ -1911,7 +1902,9 @@ namespace ts.Completions {
19111902 const type = symbol && typeChecker . getTypeOfSymbolAtLocation ( symbol , expression ) ;
19121903 const properties = type && ( < ObjectType > type ) . properties ;
19131904 if ( properties ) {
1914- membersDeclaredBySpreadAssignment . push ( ...properties ) ;
1905+ properties . forEach ( property => {
1906+ membersDeclaredBySpreadAssignment . set ( property . name , true ) ;
1907+ } ) ;
19151908 }
19161909 }
19171910 else if ( isBindingElement ( m ) && m . propertyName ) {
@@ -1932,18 +1925,28 @@ namespace ts.Completions {
19321925 }
19331926
19341927 const filteredSymbols = contextualMemberSymbols . filter ( m => ! existingMemberNames . get ( m . escapedName ) ) ;
1935- setSortTextToMemberDeclaredBySpreadAssignment ( membersDeclaredBySpreadAssignment , contextualMemberSymbols ) ;
1928+ setSortTextToMemberDeclaredBySpreadAssignment ( membersDeclaredBySpreadAssignment , filteredSymbols ) ;
19361929
19371930 return filteredSymbols ;
19381931 }
19391932
1933+ // Set SortText to OptionalMember if it is an optinoal member
1934+ function setSortTextToOptionalMember ( ) {
1935+ symbols . forEach ( m => {
1936+ if ( m . flags & SymbolFlags . Optional ) {
1937+ symbolToSortTextMap [ getSymbolId ( m ) ] = symbolToSortTextMap [ getSymbolId ( m ) ] || SortText . OptionalMember ;
1938+ }
1939+ } ) ;
1940+ }
1941+
19401942 // Set SortText to MemberDeclaredBySpreadAssignment if it is fulfilled by spread assignment
1941- function setSortTextToMemberDeclaredBySpreadAssignment ( membersDeclaredBySpreadAssignment : Symbol [ ] , contextualMemberSymbols : Symbol [ ] ) : void {
1942- for ( const fulfilledSymbol of membersDeclaredBySpreadAssignment ) {
1943- for ( const contextualMemberSymbol of contextualMemberSymbols ) {
1944- if ( contextualMemberSymbol . name === fulfilledSymbol . name ) {
1945- symbolToSortTextMap [ getSymbolId ( contextualMemberSymbol ) ] = SortText . MemberDeclaredBySpreadAssignment ;
1946- }
1943+ function setSortTextToMemberDeclaredBySpreadAssignment ( membersDeclaredBySpreadAssignment : Map < boolean > , contextualMemberSymbols : Symbol [ ] ) : void {
1944+ if ( membersDeclaredBySpreadAssignment . size === 0 ) {
1945+ return ;
1946+ }
1947+ for ( const contextualMemberSymbol of contextualMemberSymbols ) {
1948+ if ( membersDeclaredBySpreadAssignment . has ( contextualMemberSymbol . name ) ) {
1949+ symbolToSortTextMap [ getSymbolId ( contextualMemberSymbol ) ] = SortText . MemberDeclaredBySpreadAssignment ;
19471950 }
19481951 }
19491952 }
@@ -1999,7 +2002,7 @@ namespace ts.Completions {
19992002 */
20002003 function filterJsxAttributes ( symbols : Symbol [ ] , attributes : NodeArray < JsxAttribute | JsxSpreadAttribute > ) : Symbol [ ] {
20012004 const seenNames = createUnderscoreEscapedMap < boolean > ( ) ;
2002- const membersDeclaredBySpreadAssignment : Symbol [ ] = [ ] ;
2005+ const membersDeclaredBySpreadAssignment = createMap < boolean > ( ) ;
20032006 for ( const attr of attributes ) {
20042007 // If this is the current item we are editing right now, do not filter it out
20052008 if ( isCurrentlyEditingNode ( attr ) ) {
@@ -2015,7 +2018,9 @@ namespace ts.Completions {
20152018 const type = symbol && typeChecker . getTypeOfSymbolAtLocation ( symbol , expression ) ;
20162019 const properties = type && ( < ObjectType > type ) . properties ;
20172020 if ( properties ) {
2018- membersDeclaredBySpreadAssignment . push ( ...properties ) ;
2021+ properties . forEach ( property => {
2022+ membersDeclaredBySpreadAssignment . set ( property . name , true ) ;
2023+ } ) ;
20192024 }
20202025 }
20212026 }
0 commit comments