mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-09 02:30:15 -06:00
Add the members of interfaces that need to be implemented to class element completion
This commit is contained in:
parent
588c4eca42
commit
99ea9c730f
@ -937,7 +937,8 @@ namespace ts.Completions {
|
||||
hasFilteredClassMemberKeywords = true;
|
||||
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(classLikeDeclaration);
|
||||
if (baseTypeNode) {
|
||||
const implementsTypeNodes = getClassImplementsHeritageClauseElements(classLikeDeclaration);
|
||||
if (baseTypeNode || implementsTypeNodes) {
|
||||
const classElement = contextToken.parent;
|
||||
let classElementModifierFlags = isClassElement(classElement) && getModifierFlags(classElement);
|
||||
// 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 {
|
||||
|
||||
// No member list for private methods
|
||||
if (!(classElementModifierFlags & ModifierFlags.Private)) {
|
||||
const baseType = typeChecker.getTypeAtLocation(baseTypeNode);
|
||||
const typeToGetPropertiesFrom = (classElementModifierFlags & ModifierFlags.Static) ?
|
||||
typeChecker.getTypeOfSymbolAtLocation(baseType.symbol, classLikeDeclaration) :
|
||||
baseType;
|
||||
let baseClassTypeToGetPropertiesFrom: Type;
|
||||
if (baseTypeNode) {
|
||||
baseClassTypeToGetPropertiesFrom = typeChecker.getTypeAtLocation(baseTypeNode);
|
||||
if (classElementModifierFlags & ModifierFlags.Static) {
|
||||
// Use static class to get property symbols from
|
||||
baseClassTypeToGetPropertiesFrom = typeChecker.getTypeOfSymbolAtLocation(
|
||||
baseClassTypeToGetPropertiesFrom.symbol, classLikeDeclaration);
|
||||
}
|
||||
}
|
||||
const implementedInterfaceTypePropertySymbols = (classElementModifierFlags & ModifierFlags.Static) ?
|
||||
undefined :
|
||||
flatMap(implementsTypeNodes, typeNode => typeChecker.getPropertiesOfType(typeChecker.getTypeAtLocation(typeNode)));
|
||||
|
||||
// List of property symbols of base type that are not private and already implemented
|
||||
symbols = filterClassMembersList(typeChecker.getPropertiesOfType(typeToGetPropertiesFrom), classLikeDeclaration.members, classElementModifierFlags);
|
||||
symbols = filterClassMembersList(
|
||||
baseClassTypeToGetPropertiesFrom ?
|
||||
typeChecker.getPropertiesOfType(baseClassTypeToGetPropertiesFrom) :
|
||||
undefined,
|
||||
implementedInterfaceTypePropertySymbols,
|
||||
classLikeDeclaration.members,
|
||||
classElementModifierFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1334,7 +1349,7 @@ namespace ts.Completions {
|
||||
*
|
||||
* @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[] {
|
||||
function filterClassMembersList(baseSymbols: Symbol[], implementingTypeSymbols: Symbol[], existingMembers: ClassElement[], currentClassElementModifierFlags: ModifierFlags): Symbol[] {
|
||||
const existingMemberNames = createMap<boolean>();
|
||||
for (const m of existingMembers) {
|
||||
// Ignore omitted expressions for missing members
|
||||
@ -1358,7 +1373,7 @@ namespace ts.Completions {
|
||||
// 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) ||
|
||||
if ((mIsStatic && !currentElementIsStatic) ||
|
||||
(!mIsStatic && currentElementIsStatic)) {
|
||||
continue;
|
||||
}
|
||||
@ -1369,10 +1384,16 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
return filter(baseSymbols, baseProperty =>
|
||||
!existingMemberNames.get(baseProperty.name) &&
|
||||
baseProperty.getDeclarations() &&
|
||||
!(getDeclarationModifierFlagsFromSymbol(baseProperty) & ModifierFlags.Private));
|
||||
return concatenate(
|
||||
filter(baseSymbols, baseProperty => isValidProperty(baseProperty, ModifierFlags.Private)),
|
||||
filter(implementingTypeSymbols, implementingProperty => isValidProperty(implementingProperty, ModifierFlags.NonPublicAccessibilityModifier))
|
||||
);
|
||||
|
||||
function isValidProperty(propertySymbol: Symbol, inValidModifierFlags: ModifierFlags) {
|
||||
return !existingMemberNames.get(propertySymbol.name) &&
|
||||
propertySymbol.getDeclarations() &&
|
||||
!(getDeclarationModifierFlagsFromSymbol(propertySymbol) & inValidModifierFlags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -30,6 +30,18 @@
|
||||
//// }
|
||||
//// /*classThatHasDifferentMethodThanBaseAfterProtectedMethod*/
|
||||
////}
|
||||
////class D3 extends D1 {
|
||||
//// /*classThatExtendsClassExtendingAnotherClass*/
|
||||
////}
|
||||
////class D4 extends D1 {
|
||||
//// static /*classThatExtendsClassExtendingAnotherClassAndTypesStatic*/
|
||||
////}
|
||||
////class D5 extends D2 {
|
||||
//// /*classThatExtendsClassExtendingAnotherClassWithOverridingMember*/
|
||||
////}
|
||||
////class D6 extends D2 {
|
||||
//// static /*classThatExtendsClassExtendingAnotherClassWithOverridingMemberAndTypesStatic*/
|
||||
////}
|
||||
////class E {
|
||||
//// /*classThatDoesNotExtendAnotherClass*/
|
||||
////}
|
||||
@ -127,6 +139,12 @@ const allMembersOfBase: CompletionInfo[] = [
|
||||
["privateMethod", "(method) B.privateMethod(): void"],
|
||||
["staticMethod", "(method) B.staticMethod(): void"]
|
||||
];
|
||||
const publicCompletionInfoOfD1: CompletionInfo[] = [
|
||||
["getValue1", "(method) D1.getValue1(): number"]
|
||||
];
|
||||
const publicCompletionInfoOfD2: CompletionInfo[] = [
|
||||
["protectedMethod", "(method) D2.protectedMethod(): void"]
|
||||
];
|
||||
function filterCompletionInfo(fn: (a: CompletionInfo) => boolean): CompletionInfoVerifier {
|
||||
const validMembers: CompletionInfo[] = [];
|
||||
const invalidMembers: CompletionInfo[] = [];
|
||||
@ -147,6 +165,19 @@ const staticMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "st
|
||||
const instanceWithoutProtectedMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "getValue");
|
||||
const instanceWithoutPublicMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "protectedMethod");
|
||||
|
||||
const instanceMemberInfoD1: CompletionInfoVerifier = {
|
||||
validMembers: instanceMemberInfo.validMembers.concat(publicCompletionInfoOfD1),
|
||||
invalidMembers: instanceMemberInfo.invalidMembers
|
||||
};
|
||||
const instanceMemberInfoD2: CompletionInfoVerifier = {
|
||||
validMembers: instanceWithoutProtectedMemberInfo.validMembers.concat(publicCompletionInfoOfD2),
|
||||
invalidMembers: instanceWithoutProtectedMemberInfo.invalidMembers
|
||||
};
|
||||
const staticMemberInfoDn: CompletionInfoVerifier = {
|
||||
validMembers: staticMemberInfo.validMembers,
|
||||
invalidMembers: staticMemberInfo.invalidMembers.concat(publicCompletionInfoOfD1, publicCompletionInfoOfD2)
|
||||
};
|
||||
|
||||
// Not a class element declaration location
|
||||
const nonClassElementMarkers = [
|
||||
"InsideMethod"
|
||||
@ -210,4 +241,16 @@ const classInstanceElementWithoutProtectedMethodLocations = [
|
||||
"classThatHasAlreadyImplementedAnotherClassProtectedMethod",
|
||||
"classThatHasDifferentMethodThanBaseAfterProtectedMethod",
|
||||
];
|
||||
verifyClassElementLocations(instanceWithoutProtectedMemberInfo, classInstanceElementWithoutProtectedMethodLocations);
|
||||
verifyClassElementLocations(instanceWithoutProtectedMemberInfo, classInstanceElementWithoutProtectedMethodLocations);
|
||||
|
||||
// instance memebers in D1 and base class are shown
|
||||
verifyClassElementLocations(instanceMemberInfoD1, ["classThatExtendsClassExtendingAnotherClass"]);
|
||||
|
||||
// instance memebers in D2 and base class are shown
|
||||
verifyClassElementLocations(instanceMemberInfoD2, ["classThatExtendsClassExtendingAnotherClassWithOverridingMember"]);
|
||||
|
||||
// static base members and class member keywords allowed
|
||||
verifyClassElementLocations(staticMemberInfoDn, [
|
||||
"classThatExtendsClassExtendingAnotherClassAndTypesStatic",
|
||||
"classThatExtendsClassExtendingAnotherClassWithOverridingMemberAndTypesStatic"
|
||||
]);
|
||||
456
tests/cases/fourslash/completionEntryForClassMembers2.ts
Normal file
456
tests/cases/fourslash/completionEntryForClassMembers2.ts
Normal file
@ -0,0 +1,456 @@
|
||||
///<reference path="fourslash.ts" />
|
||||
|
||||
////interface I {
|
||||
//// methodOfInterface(): number;
|
||||
////}
|
||||
////interface I2 {
|
||||
//// methodOfInterface2(): number;
|
||||
////}
|
||||
////interface I3 {
|
||||
//// getValue(): string;
|
||||
//// method(): string;
|
||||
////}
|
||||
////interface I4 {
|
||||
//// staticMethod(): void;
|
||||
//// method(): string;
|
||||
////}
|
||||
////class B0 {
|
||||
//// private privateMethod() { }
|
||||
//// protected protectedMethod() { }
|
||||
//// static staticMethod() { }
|
||||
//// getValue(): string | boolean { return "hello"; }
|
||||
//// private privateMethod1() { }
|
||||
//// protected protectedMethod1() { }
|
||||
//// static staticMethod1() { }
|
||||
//// getValue1(): string | boolean { return "hello"; }
|
||||
////}
|
||||
////interface I5 extends B0 {
|
||||
//// methodOfInterface5(): number;
|
||||
////}
|
||||
////interface I6 extends B0 {
|
||||
//// methodOfInterface6(): number;
|
||||
//// staticMethod(): void;
|
||||
////}
|
||||
////interface I7 extends I {
|
||||
//// methodOfInterface7(): number;
|
||||
////}
|
||||
////class B {
|
||||
//// private privateMethod() { }
|
||||
//// protected protectedMethod() { }
|
||||
//// static staticMethod() { }
|
||||
//// getValue(): string | boolean { return "hello"; }
|
||||
////}
|
||||
////class C0 implements I, I2 {
|
||||
//// /*implementsIAndI2*/
|
||||
////}
|
||||
////class C00 implements I, I2 {
|
||||
//// static /*implementsIAndI2AndWritingStatic*/
|
||||
////}
|
||||
////class C001 implements I, I2 {
|
||||
//// methodOfInterface/*implementsIAndI2AndWritingMethodNameOfI*/
|
||||
////}
|
||||
////class C extends B implements I, I2 {
|
||||
//// /*extendsBAndImplementsIAndI2*/
|
||||
////}
|
||||
////class C1 extends B implements I, I2 {
|
||||
//// static /*extendsBAndImplementsIAndI2AndWritingStatic*/
|
||||
////}
|
||||
////class D extends B implements I, I2 {
|
||||
//// /*extendsBAndImplementsIAndI2WithMethodFromB*/
|
||||
//// protected protectedMethod() {
|
||||
//// return "protected";
|
||||
//// }
|
||||
////}
|
||||
////class E extends B implements I, I2 {
|
||||
//// /*extendsBAndImplementsIAndI2WithMethodFromI*/
|
||||
//// methodOfInterface() {
|
||||
//// return 1;
|
||||
//// }
|
||||
////}
|
||||
////class F extends B implements I, I2 {
|
||||
//// /*extendsBAndImplementsIAndI2WithMethodFromBAndI*/
|
||||
//// protected protectedMethod() {
|
||||
//// return "protected"
|
||||
//// }
|
||||
//// methodOfInterface() {
|
||||
//// return 1;
|
||||
//// }
|
||||
////}
|
||||
////class F2 extends B implements I, I2 {
|
||||
//// protected protectedMethod() {
|
||||
//// return "protected"
|
||||
//// }
|
||||
//// methodOfInterface() {
|
||||
//// return 1;
|
||||
//// }
|
||||
//// static /*extendsBAndImplementsIAndI2WithMethodFromBAndIAndTypesStatic*/
|
||||
////}
|
||||
////class G extends B implements I3 {
|
||||
//// /*extendsBAndImplementsI3WithSameNameMembers*/
|
||||
////}
|
||||
////class H extends B implements I3 {
|
||||
//// /*extendsBAndImplementsI3WithSameNameMembersAndHasImplementedTheMember*/
|
||||
//// getValue() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
////}
|
||||
////class J extends B0 implements I4 {
|
||||
//// /*extendsB0ThatExtendsAndImplementsI4WithStaticMethod*/
|
||||
////}
|
||||
////class L extends B0 implements I4 {
|
||||
//// /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedAnotherMethod*/
|
||||
//// staticMethod2() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
////}
|
||||
////class K extends B0 implements I4 {
|
||||
//// /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethod*/
|
||||
//// staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
////}
|
||||
////class M extends B0 implements I4 {
|
||||
//// /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsStatic*/
|
||||
//// static staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
////}
|
||||
////class N extends B0 implements I4 {
|
||||
//// /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsBoth*/
|
||||
//// staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
////}
|
||||
////class J1 extends B0 implements I4 {
|
||||
//// static /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodWritingStatic*/
|
||||
////}
|
||||
////class L1 extends B0 implements I4 {
|
||||
//// staticMethod2() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedAnotherMethodWritingStatic*/
|
||||
////}
|
||||
////class K1 extends B0 implements I4 {
|
||||
//// staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodWritingStatic*/
|
||||
////}
|
||||
////class M1 extends B0 implements I4 {
|
||||
//// static staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsStaticWritingStatic*/
|
||||
////}
|
||||
////class N1 extends B0 implements I4 {
|
||||
//// staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsBothWritingStatic*/
|
||||
////}
|
||||
////class O implements I7 {
|
||||
//// /*implementsI7whichExtendsI*/
|
||||
////}
|
||||
////class P implements I7, I {
|
||||
//// /*implementsI7whichExtendsIAndAlsoImplementsI*/
|
||||
////}
|
||||
////class Q implements I, I7 {
|
||||
//// /*implementsIAndAlsoImplementsI7whichExtendsI*/
|
||||
////}
|
||||
////class R implements I5 {
|
||||
//// /*implementsI5ThatExtendsB0*/
|
||||
////}
|
||||
////class S implements I6 {
|
||||
//// /*implementsI6ThatExtendsB0AndHasStaticMethodOfB0*/
|
||||
////}
|
||||
////class T extends B0 implements I5 {
|
||||
//// /*extendsB0AndImplementsI5ThatExtendsB0*/
|
||||
////}
|
||||
////class U extends B0 implements I6 {
|
||||
//// /*extendsB0AndImplementsI6ThatExtendsB0AndHasStaticMethodOfB0*/
|
||||
////}
|
||||
////class R1 implements I5 {
|
||||
//// static /*implementsI5ThatExtendsB0TypesStatic*/
|
||||
////}
|
||||
////class S1 implements I6 {
|
||||
//// static /*implementsI6ThatExtendsB0AndHasStaticMethodOfB0TypesStatic*/
|
||||
////}
|
||||
////class T1 extends B0 implements I5 {
|
||||
//// static /*extendsB0AndImplementsI5ThatExtendsB0TypesStatic*/
|
||||
////}
|
||||
////class U1 extends B0 implements I6 {
|
||||
//// static /*extendsB0AndImplementsI6ThatExtendsB0AndHasStaticMethodOfB0TypesStatic*/
|
||||
////}
|
||||
|
||||
const allowedKeywordCount = verify.allowedClassElementKeywords.length;
|
||||
type CompletionInfo = [string, string];
|
||||
type CompletionInfoVerifier = { validMembers: CompletionInfo[], invalidMembers: CompletionInfo[] };
|
||||
|
||||
function verifyClassElementLocations({ validMembers, invalidMembers }: CompletionInfoVerifier, classElementCompletionLocations: string[]) {
|
||||
for (const marker of classElementCompletionLocations) {
|
||||
goTo.marker(marker);
|
||||
verifyCompletionInfo(validMembers, verify);
|
||||
verifyCompletionInfo(invalidMembers, verify.not);
|
||||
verify.completionListContainsClassElementKeywords();
|
||||
verify.completionListCount(allowedKeywordCount + validMembers.length);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyCompletionInfo(memberInfo: CompletionInfo[], verify: FourSlashInterface.verifyNegatable) {
|
||||
for (const [symbol, text] of memberInfo) {
|
||||
verify.completionListContains(symbol, text, /*documentation*/ undefined, "method");
|
||||
}
|
||||
}
|
||||
|
||||
const validInstanceMembersOfBaseClassB: CompletionInfo[] = [
|
||||
["getValue", "(method) B.getValue(): string | boolean"],
|
||||
["protectedMethod", "(method) B.protectedMethod(): void"],
|
||||
];
|
||||
const validStaticMembersOfBaseClassB: CompletionInfo[] = [
|
||||
["staticMethod", "(method) B.staticMethod(): void"]
|
||||
];
|
||||
const privateMembersOfBaseClassB: CompletionInfo[] = [
|
||||
["privateMethod", "(method) B.privateMethod(): void"],
|
||||
];
|
||||
const protectedPropertiesOfBaseClassB0: CompletionInfo[] = [
|
||||
["protectedMethod", "(method) B0.protectedMethod(): void"],
|
||||
["protectedMethod1", "(method) B0.protectedMethod1(): void"],
|
||||
];
|
||||
const publicPropertiesOfBaseClassB0: CompletionInfo[] = [
|
||||
["getValue", "(method) B0.getValue(): string | boolean"],
|
||||
["getValue1", "(method) B0.getValue1(): string | boolean"],
|
||||
];
|
||||
const validInstanceMembersOfBaseClassB0: CompletionInfo[] = protectedPropertiesOfBaseClassB0.concat(publicPropertiesOfBaseClassB0);
|
||||
const validStaticMembersOfBaseClassB0: CompletionInfo[] = [
|
||||
["staticMethod", "(method) B0.staticMethod(): void"],
|
||||
["staticMethod1", "(method) B0.staticMethod1(): void"]
|
||||
];
|
||||
const privateMembersOfBaseClassB0: CompletionInfo[] = [
|
||||
["privateMethod", "(method) B0.privateMethod(): void"],
|
||||
["privateMethod1", "(method) B0.privateMethod1(): void"],
|
||||
];
|
||||
const membersOfI: CompletionInfo[] = [
|
||||
["methodOfInterface", "(method) I.methodOfInterface(): number"],
|
||||
];
|
||||
const membersOfI2: CompletionInfo[] = [
|
||||
["methodOfInterface2", "(method) I2.methodOfInterface2(): number"],
|
||||
];
|
||||
const membersOfI3: CompletionInfo[] = [
|
||||
["getValue", "(method) I3.getValue(): string"],
|
||||
["method", "(method) I3.method(): string"],
|
||||
];
|
||||
const membersOfI4: CompletionInfo[] = [
|
||||
["staticMethod", "(method) I4.staticMethod(): void"],
|
||||
["method", "(method) I4.method(): string"],
|
||||
];
|
||||
const membersOfI5: CompletionInfo[] = publicPropertiesOfBaseClassB0.concat([
|
||||
["methodOfInterface5", "(method) I5.methodOfInterface5(): number"]
|
||||
]);
|
||||
const membersOfI6: CompletionInfo[] = publicPropertiesOfBaseClassB0.concat([
|
||||
["staticMethod", "(method) I6.staticMethod(): void"],
|
||||
["methodOfInterface6", "(method) I6.methodOfInterface6(): number"]
|
||||
]);
|
||||
const membersOfI7: CompletionInfo[] = membersOfI.concat([
|
||||
["methodOfInterface7", "(method) I7.methodOfInterface7(): number"]
|
||||
]);
|
||||
|
||||
function getCompletionInfoVerifier(
|
||||
validMembers: CompletionInfo[],
|
||||
invalidMembers: CompletionInfo[],
|
||||
arrayToDistribute: CompletionInfo[],
|
||||
isValidDistributionCriteria: (v: CompletionInfo) => boolean): CompletionInfoVerifier {
|
||||
if (arrayToDistribute) {
|
||||
validMembers = validMembers.concat(arrayToDistribute.filter(isValidDistributionCriteria));
|
||||
invalidMembers = invalidMembers.concat(arrayToDistribute.filter(v => !isValidDistributionCriteria(v)));
|
||||
}
|
||||
return {
|
||||
validMembers,
|
||||
invalidMembers
|
||||
}
|
||||
}
|
||||
|
||||
const noMembers: CompletionInfo[] = [];
|
||||
const membersOfIAndI2 = membersOfI.concat(membersOfI2);
|
||||
const invalidMembersOfBAtInstanceLocation = privateMembersOfBaseClassB.concat(validStaticMembersOfBaseClassB);
|
||||
|
||||
// members of I and I2
|
||||
verifyClassElementLocations({ validMembers: membersOfIAndI2, invalidMembers: noMembers }, [
|
||||
"implementsIAndI2",
|
||||
"implementsIAndI2AndWritingMethodNameOfI"
|
||||
]);
|
||||
|
||||
// Static location so no members of I and I2
|
||||
verifyClassElementLocations({ validMembers: noMembers, invalidMembers: membersOfIAndI2 },
|
||||
["implementsIAndI2AndWritingStatic"]);
|
||||
|
||||
const allInstanceBAndIAndI2 = membersOfIAndI2.concat(validInstanceMembersOfBaseClassB);
|
||||
// members of instance B, I and I2
|
||||
verifyClassElementLocations({
|
||||
validMembers: allInstanceBAndIAndI2,
|
||||
invalidMembers: invalidMembersOfBAtInstanceLocation
|
||||
}, ["extendsBAndImplementsIAndI2"]);
|
||||
|
||||
// static location so only static members of B and no members of instance B, I and I2
|
||||
verifyClassElementLocations({
|
||||
validMembers: validStaticMembersOfBaseClassB,
|
||||
invalidMembers: privateMembersOfBaseClassB.concat(allInstanceBAndIAndI2)
|
||||
}, [
|
||||
"extendsBAndImplementsIAndI2AndWritingStatic",
|
||||
"extendsBAndImplementsIAndI2WithMethodFromBAndIAndTypesStatic"
|
||||
]);
|
||||
|
||||
// instance members of B without protectedMethod, I and I2
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ membersOfIAndI2,
|
||||
/*invalidMembers*/ invalidMembersOfBAtInstanceLocation,
|
||||
/*arrayToDistribute*/ validInstanceMembersOfBaseClassB,
|
||||
value => value[0] !== "protectedMethod"),
|
||||
["extendsBAndImplementsIAndI2WithMethodFromB"]);
|
||||
|
||||
// instance members of B, members of T without methodOfInterface and I2
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ membersOfI2.concat(validInstanceMembersOfBaseClassB),
|
||||
/*invalidMembers*/ invalidMembersOfBAtInstanceLocation,
|
||||
/*arrayToDistribute*/ membersOfI,
|
||||
value => value[0] !== "methodOfInterface"),
|
||||
["extendsBAndImplementsIAndI2WithMethodFromI"]);
|
||||
|
||||
// instance members of B without protectedMethod, members of T without methodOfInterface and I2
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ membersOfI2,
|
||||
/*invalidMembers*/ invalidMembersOfBAtInstanceLocation,
|
||||
/*arrayToDistribute*/ membersOfI.concat(validInstanceMembersOfBaseClassB),
|
||||
value => value[0] !== "methodOfInterface" && value[0] !== "protectedMethod"),
|
||||
["extendsBAndImplementsIAndI2WithMethodFromBAndI"]);
|
||||
|
||||
// members of B and members of I3 that are not same as name of method in B
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ validInstanceMembersOfBaseClassB,
|
||||
/*invalidMembers*/ invalidMembersOfBAtInstanceLocation,
|
||||
/*arrayToDistribute*/ membersOfI3,
|
||||
value => value[0] !== "getValue"),
|
||||
["extendsBAndImplementsI3WithSameNameMembers"]);
|
||||
|
||||
// members of B (without getValue since its implemented) and members of I3 that are not same as name of method in B
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ noMembers,
|
||||
/*invalidMembers*/ invalidMembersOfBAtInstanceLocation,
|
||||
/*arrayToDistribute*/ membersOfI3.concat(validInstanceMembersOfBaseClassB),
|
||||
value => value[0] !== "getValue"),
|
||||
["extendsBAndImplementsI3WithSameNameMembersAndHasImplementedTheMember"]);
|
||||
|
||||
const invalidMembersOfB0AtInstanceSide = privateMembersOfBaseClassB0.concat(validStaticMembersOfBaseClassB0);
|
||||
const invalidMembersOfB0AtStaticSide = privateMembersOfBaseClassB0.concat(validInstanceMembersOfBaseClassB0);
|
||||
// members of B0 and members of I4
|
||||
verifyClassElementLocations({
|
||||
validMembers: validInstanceMembersOfBaseClassB0.concat(membersOfI4),
|
||||
invalidMembers: invalidMembersOfB0AtInstanceSide
|
||||
}, [
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethod",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedAnotherMethod",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsStatic"
|
||||
]);
|
||||
|
||||
// members of B0 and members of I4 that are not staticMethod
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ validInstanceMembersOfBaseClassB0,
|
||||
/*invalidMembers*/ invalidMembersOfB0AtInstanceSide,
|
||||
/*arrayToDistribute*/ membersOfI4,
|
||||
value => value[0] !== "staticMethod"
|
||||
), [
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethod",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsBoth"
|
||||
]);
|
||||
|
||||
// static members of B0
|
||||
verifyClassElementLocations({
|
||||
validMembers: validStaticMembersOfBaseClassB0,
|
||||
invalidMembers: invalidMembersOfB0AtStaticSide.concat(membersOfI4)
|
||||
}, [
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodWritingStatic",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedAnotherMethodWritingStatic",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodWritingStatic"
|
||||
]);
|
||||
|
||||
// static members of B0 without staticMethod
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ noMembers,
|
||||
/*invalidMembers*/ invalidMembersOfB0AtStaticSide.concat(membersOfI4),
|
||||
/*arrayToDistribute*/ validStaticMembersOfBaseClassB0,
|
||||
value => value[0] !== "staticMethod"
|
||||
), [
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsStaticWritingStatic",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsBothWritingStatic"
|
||||
]);
|
||||
|
||||
// members of I7 extends I
|
||||
verifyClassElementLocations({ validMembers: membersOfI7, invalidMembers: noMembers }, [
|
||||
"implementsI7whichExtendsI",
|
||||
"implementsI7whichExtendsIAndAlsoImplementsI",
|
||||
"implementsIAndAlsoImplementsI7whichExtendsI"
|
||||
]);
|
||||
|
||||
const invalidMembersOfB0AtInstanceSideFromInterfaceExtendingB0 = invalidMembersOfB0AtInstanceSide
|
||||
.concat(protectedPropertiesOfBaseClassB0);
|
||||
// members of I5 extends B0
|
||||
verifyClassElementLocations({
|
||||
validMembers: membersOfI5,
|
||||
invalidMembers: invalidMembersOfB0AtInstanceSideFromInterfaceExtendingB0
|
||||
}, [
|
||||
"implementsI5ThatExtendsB0",
|
||||
]);
|
||||
|
||||
// members of I6 extends B0
|
||||
verifyClassElementLocations({
|
||||
validMembers: membersOfI6,
|
||||
invalidMembers: invalidMembersOfB0AtInstanceSideFromInterfaceExtendingB0
|
||||
}, [
|
||||
"implementsI6ThatExtendsB0AndHasStaticMethodOfB0",
|
||||
]);
|
||||
|
||||
// members of B0 and I5 that extends B0
|
||||
verifyClassElementLocations({
|
||||
validMembers: membersOfI5.concat(protectedPropertiesOfBaseClassB0),
|
||||
invalidMembers: invalidMembersOfB0AtInstanceSide
|
||||
}, [
|
||||
"extendsB0AndImplementsI5ThatExtendsB0"
|
||||
]);
|
||||
|
||||
// members of B0 and I6 that extends B0
|
||||
verifyClassElementLocations({
|
||||
validMembers: membersOfI6.concat(protectedPropertiesOfBaseClassB0),
|
||||
invalidMembers: invalidMembersOfB0AtInstanceSide
|
||||
}, [
|
||||
"extendsB0AndImplementsI6ThatExtendsB0AndHasStaticMethodOfB0"
|
||||
]);
|
||||
|
||||
// nothing on static side as these do not extend any other class
|
||||
verifyClassElementLocations({
|
||||
validMembers: [],
|
||||
invalidMembers: membersOfI5.concat(membersOfI6, invalidMembersOfB0AtStaticSide)
|
||||
}, [
|
||||
"implementsI5ThatExtendsB0TypesStatic",
|
||||
"implementsI6ThatExtendsB0AndHasStaticMethodOfB0TypesStatic"
|
||||
]);
|
||||
|
||||
// statics of base B but nothing from instance side
|
||||
verifyClassElementLocations({
|
||||
validMembers: validStaticMembersOfBaseClassB0,
|
||||
invalidMembers: membersOfI5.concat(membersOfI6, invalidMembersOfB0AtStaticSide)
|
||||
}, [
|
||||
"extendsB0AndImplementsI5ThatExtendsB0TypesStatic",
|
||||
"extendsB0AndImplementsI6ThatExtendsB0AndHasStaticMethodOfB0TypesStatic"
|
||||
]);
|
||||
Loading…
x
Reference in New Issue
Block a user