mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-12 04:17:34 -06:00
Filter out existing members of the class from the completion list
This commit is contained in:
parent
a8ad40f131
commit
588c4eca42
@ -927,8 +927,6 @@ namespace ts.Completions {
|
||||
/**
|
||||
* Aggregates relevant symbols for completion in class declaration
|
||||
* Relevant symbols are stored in the captured 'symbols' variable.
|
||||
*
|
||||
* @returns true if 'symbols' was successfully populated; false otherwise.
|
||||
*/
|
||||
function getGetClassLikeCompletionSymbols(classLikeDeclaration: ClassLikeDeclaration) {
|
||||
// We're looking up possible property names from parent type.
|
||||
@ -961,9 +959,8 @@ namespace ts.Completions {
|
||||
typeChecker.getTypeOfSymbolAtLocation(baseType.symbol, classLikeDeclaration) :
|
||||
baseType;
|
||||
|
||||
// List of property symbols of base type that are not private
|
||||
symbols = filter(typeChecker.getPropertiesOfType(typeToGetPropertiesFrom),
|
||||
baseProperty => baseProperty.getDeclarations() && !(getDeclarationModifierFlagsFromSymbol(baseProperty) & ModifierFlags.Private));
|
||||
// List of property symbols of base type that are not private and already implemented
|
||||
symbols = filterClassMembersList(typeChecker.getPropertiesOfType(typeToGetPropertiesFrom), classLikeDeclaration.members, classElementModifierFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1332,6 +1329,52 @@ namespace ts.Completions {
|
||||
return filter(contextualMemberSymbols, m => !existingMemberNames.get(m.name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out completion suggestions for class elements.
|
||||
*
|
||||
* @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags
|
||||
*/
|
||||
function filterClassMembersList(baseSymbols: Symbol[], existingMembers: ClassElement[], currentClassElementModifierFlags: ModifierFlags): Symbol[] {
|
||||
const existingMemberNames = createMap<boolean>();
|
||||
for (const m of existingMembers) {
|
||||
// Ignore omitted expressions for missing members
|
||||
if (m.kind !== SyntaxKind.PropertyDeclaration &&
|
||||
m.kind !== SyntaxKind.MethodDeclaration &&
|
||||
m.kind !== SyntaxKind.GetAccessor &&
|
||||
m.kind !== SyntaxKind.SetAccessor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is the current item we are editing right now, do not filter it out
|
||||
if (isCurrentlyEditingNode(m)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Dont filter member even if the name matches if it is declared private in the list
|
||||
if (hasModifier(m, ModifierFlags.Private)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// do not filter it out if the static presence doesnt match
|
||||
const mIsStatic = hasModifier(m, ModifierFlags.Static);
|
||||
const currentElementIsStatic = !!(currentClassElementModifierFlags & ModifierFlags.Static);
|
||||
if ((mIsStatic && currentElementIsStatic) ||
|
||||
(!mIsStatic && currentElementIsStatic)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const existingName = getPropertyNameForPropertyNameNode(m.name);
|
||||
if (existingName) {
|
||||
existingMemberNames.set(existingName, true);
|
||||
}
|
||||
}
|
||||
|
||||
return filter(baseSymbols, baseProperty =>
|
||||
!existingMemberNames.get(baseProperty.name) &&
|
||||
baseProperty.getDeclarations() &&
|
||||
!(getDeclarationModifierFlagsFromSymbol(baseProperty) & ModifierFlags.Private));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out completion suggestions from 'symbols' according to existing JSX attributes.
|
||||
*
|
||||
|
||||
@ -17,6 +17,19 @@
|
||||
//// }
|
||||
//// /*classThatHasAlreadyImplementedAnotherClassMethodAfterMethod*/
|
||||
////}
|
||||
////class D1 extends B {
|
||||
//// /*classThatHasDifferentMethodThanBase*/
|
||||
//// getValue1() {
|
||||
//// return 10;
|
||||
//// }
|
||||
//// /*classThatHasDifferentMethodThanBaseAfterMethod*/
|
||||
////}
|
||||
////class D2 extends B {
|
||||
//// /*classThatHasAlreadyImplementedAnotherClassProtectedMethod*/
|
||||
//// protectedMethod() {
|
||||
//// }
|
||||
//// /*classThatHasDifferentMethodThanBaseAfterProtectedMethod*/
|
||||
////}
|
||||
////class E {
|
||||
//// /*classThatDoesNotExtendAnotherClass*/
|
||||
////}
|
||||
@ -131,6 +144,8 @@ function filterCompletionInfo(fn: (a: CompletionInfo) => boolean): CompletionInf
|
||||
|
||||
const instanceMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "getValue" || a === "protectedMethod");
|
||||
const staticMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "staticMethod");
|
||||
const instanceWithoutProtectedMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "getValue");
|
||||
const instanceWithoutPublicMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "protectedMethod");
|
||||
|
||||
// Not a class element declaration location
|
||||
const nonClassElementMarkers = [
|
||||
@ -156,8 +171,8 @@ verifyClassElementLocations({ validMembers: [], invalidMembers: allMembersOfBase
|
||||
// Instance base members and class member keywords allowed
|
||||
const classInstanceElementLocations = [
|
||||
"classThatIsEmptyAndExtendingAnotherClass",
|
||||
"classThatHasAlreadyImplementedAnotherClassMethod",
|
||||
"classThatHasAlreadyImplementedAnotherClassMethodAfterMethod",
|
||||
"classThatHasDifferentMethodThanBase",
|
||||
"classThatHasDifferentMethodThanBaseAfterMethod",
|
||||
"classThatHasWrittenPublicKeyword",
|
||||
"classThatStartedWritingIdentifier",
|
||||
"propDeclarationWithoutSemicolon",
|
||||
@ -183,4 +198,16 @@ const staticClassLocations = [
|
||||
"classElementContainingStatic",
|
||||
"classThatStartedWritingIdentifierAfterStaticModifier"
|
||||
];
|
||||
verifyClassElementLocations(staticMemberInfo, staticClassLocations);
|
||||
verifyClassElementLocations(staticMemberInfo, staticClassLocations);
|
||||
|
||||
const classInstanceElementWithoutPublicMethodLocations = [
|
||||
"classThatHasAlreadyImplementedAnotherClassMethod",
|
||||
"classThatHasAlreadyImplementedAnotherClassMethodAfterMethod",
|
||||
];
|
||||
verifyClassElementLocations(instanceWithoutPublicMemberInfo, classInstanceElementWithoutPublicMethodLocations);
|
||||
|
||||
const classInstanceElementWithoutProtectedMethodLocations = [
|
||||
"classThatHasAlreadyImplementedAnotherClassProtectedMethod",
|
||||
"classThatHasDifferentMethodThanBaseAfterProtectedMethod",
|
||||
];
|
||||
verifyClassElementLocations(instanceWithoutProtectedMemberInfo, classInstanceElementWithoutProtectedMethodLocations);
|
||||
Loading…
x
Reference in New Issue
Block a user