@@ -937,7 +937,8 @@ namespace ts.Completions {
937
937
hasFilteredClassMemberKeywords = true ;
938
938
939
939
const baseTypeNode = getClassExtendsHeritageClauseElement ( classLikeDeclaration ) ;
940
- if ( baseTypeNode ) {
940
+ const implementsTypeNodes = getClassImplementsHeritageClauseElements ( classLikeDeclaration ) ;
941
+ if ( baseTypeNode || implementsTypeNodes ) {
941
942
const classElement = contextToken . parent ;
942
943
let classElementModifierFlags = isClassElement ( classElement ) && getModifierFlags ( classElement ) ;
943
944
// If this is context token is not something we are editing now, consider if this would lead to be modifier
@@ -954,13 +955,27 @@ namespace ts.Completions {
954
955
955
956
// No member list for private methods
956
957
if ( ! ( classElementModifierFlags & ModifierFlags . Private ) ) {
957
- const baseType = typeChecker . getTypeAtLocation ( baseTypeNode ) ;
958
- const typeToGetPropertiesFrom = ( classElementModifierFlags & ModifierFlags . Static ) ?
959
- typeChecker . getTypeOfSymbolAtLocation ( baseType . symbol , classLikeDeclaration ) :
960
- baseType ;
958
+ let baseClassTypeToGetPropertiesFrom : Type ;
959
+ if ( baseTypeNode ) {
960
+ baseClassTypeToGetPropertiesFrom = typeChecker . getTypeAtLocation ( baseTypeNode ) ;
961
+ if ( classElementModifierFlags & ModifierFlags . Static ) {
962
+ // Use static class to get property symbols from
963
+ baseClassTypeToGetPropertiesFrom = typeChecker . getTypeOfSymbolAtLocation (
964
+ baseClassTypeToGetPropertiesFrom . symbol , classLikeDeclaration ) ;
965
+ }
966
+ }
967
+ const implementedInterfaceTypePropertySymbols = ( classElementModifierFlags & ModifierFlags . Static ) ?
968
+ undefined :
969
+ flatMap ( implementsTypeNodes , typeNode => typeChecker . getPropertiesOfType ( typeChecker . getTypeAtLocation ( typeNode ) ) ) ;
961
970
962
971
// List of property symbols of base type that are not private and already implemented
963
- symbols = filterClassMembersList ( typeChecker . getPropertiesOfType ( typeToGetPropertiesFrom ) , classLikeDeclaration . members , classElementModifierFlags ) ;
972
+ symbols = filterClassMembersList (
973
+ baseClassTypeToGetPropertiesFrom ?
974
+ typeChecker . getPropertiesOfType ( baseClassTypeToGetPropertiesFrom ) :
975
+ undefined ,
976
+ implementedInterfaceTypePropertySymbols ,
977
+ classLikeDeclaration . members ,
978
+ classElementModifierFlags ) ;
964
979
}
965
980
}
966
981
}
@@ -1334,7 +1349,7 @@ namespace ts.Completions {
1334
1349
*
1335
1350
* @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags
1336
1351
*/
1337
- function filterClassMembersList ( baseSymbols : Symbol [ ] , existingMembers : ClassElement [ ] , currentClassElementModifierFlags : ModifierFlags ) : Symbol [ ] {
1352
+ function filterClassMembersList ( baseSymbols : Symbol [ ] , implementingTypeSymbols : Symbol [ ] , existingMembers : ClassElement [ ] , currentClassElementModifierFlags : ModifierFlags ) : Symbol [ ] {
1338
1353
const existingMemberNames = createMap < boolean > ( ) ;
1339
1354
for ( const m of existingMembers ) {
1340
1355
// Ignore omitted expressions for missing members
@@ -1358,7 +1373,7 @@ namespace ts.Completions {
1358
1373
// do not filter it out if the static presence doesnt match
1359
1374
const mIsStatic = hasModifier ( m , ModifierFlags . Static ) ;
1360
1375
const currentElementIsStatic = ! ! ( currentClassElementModifierFlags & ModifierFlags . Static ) ;
1361
- if ( ( mIsStatic && currentElementIsStatic ) ||
1376
+ if ( ( mIsStatic && ! currentElementIsStatic ) ||
1362
1377
( ! mIsStatic && currentElementIsStatic ) ) {
1363
1378
continue ;
1364
1379
}
@@ -1369,10 +1384,16 @@ namespace ts.Completions {
1369
1384
}
1370
1385
}
1371
1386
1372
- return filter ( baseSymbols , baseProperty =>
1373
- ! existingMemberNames . get ( baseProperty . name ) &&
1374
- baseProperty . getDeclarations ( ) &&
1375
- ! ( getDeclarationModifierFlagsFromSymbol ( baseProperty ) & ModifierFlags . Private ) ) ;
1387
+ return concatenate (
1388
+ filter ( baseSymbols , baseProperty => isValidProperty ( baseProperty , ModifierFlags . Private ) ) ,
1389
+ filter ( implementingTypeSymbols , implementingProperty => isValidProperty ( implementingProperty , ModifierFlags . NonPublicAccessibilityModifier ) )
1390
+ ) ;
1391
+
1392
+ function isValidProperty ( propertySymbol : Symbol , inValidModifierFlags : ModifierFlags ) {
1393
+ return ! existingMemberNames . get ( propertySymbol . name ) &&
1394
+ propertySymbol . getDeclarations ( ) &&
1395
+ ! ( getDeclarationModifierFlagsFromSymbol ( propertySymbol ) & inValidModifierFlags ) ;
1396
+ }
1376
1397
}
1377
1398
1378
1399
/**
0 commit comments