diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 2d95cf978e3..412e29c3556 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1373,26 +1373,37 @@ namespace ts.FindAllReferences.Core { // For certain symbol kinds, we need to include other symbols in the search set. // This is not needed when searching for re-exports. function populateSearchSymbolSet(symbol: Symbol, location: Node, checker: TypeChecker, implementations: boolean): Symbol[] { - // The search set contains at least the current symbol const result: Symbol[] = []; + forEachRelatedSymbol(symbol, location, checker, + (sym, root, base) => { result.push(base || root || sym); }, + parameterProperties => { result.push(...parameterProperties); }, + /*allowBaseTypes*/ () => !implementations, + /*includeShorthandDestructuring*/ false); + return result; + } + function forEachRelatedSymbol( + symbol: Symbol, location: Node, checker: TypeChecker, + cbSymbol: (symbol: Symbol, rootSymbol?: Symbol, baseSymbol?: Symbol) => T | undefined, + cbParameterProperties: (s: Symbol[]) => T | undefined, + allowBaseTypes: (rootSymbol: Symbol) => boolean, + includeShorthandDestructuring: boolean, + ): T | undefined { const containingObjectLiteralElement = getContainingObjectLiteralElement(location); if (containingObjectLiteralElement) { - // If the location is name of property symbol from object literal destructuring pattern - // Search the property symbol - // for ( { property: p2 } of elems) { } - if (containingObjectLiteralElement.kind !== SyntaxKind.ShorthandPropertyAssignment) { - const propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker); - if (propertySymbol) { - result.push(propertySymbol); - } - } - // If the location is in a context sensitive location (i.e. in an object literal) try // to get a contextual type for it, and add the property symbol from the contextual // type to the search set - for (const contextualSymbol of getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker)) { - addRootSymbols(contextualSymbol); + const res = firstDefined(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), fromRoot); + if (res) return res; + + // If the location is name of property symbol from object literal destructuring pattern + // Search the property symbol + // for ( { property: p2 } of elems) { } + if (includeShorthandDestructuring || containingObjectLiteralElement.kind !== SyntaxKind.ShorthandPropertyAssignment) { + const propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker); + const res = propertySymbol && cbSymbol(propertySymbol); + if (res) return res; } /* Because in short-hand property assignment, location has two meaning : property name and as value of the property @@ -1407,49 +1418,44 @@ namespace ts.FindAllReferences.Core { * will be included correctly. */ const shorthandValueSymbol = checker.getShorthandAssignmentValueSymbol(location.parent); - if (shorthandValueSymbol) { - result.push(shorthandValueSymbol); - } + const res1 = shorthandValueSymbol && cbSymbol(shorthandValueSymbol); + if (res1) return res1; } + const res = fromRoot(symbol); + if (res) return res; + // If the symbol.valueDeclaration is a property parameter declaration, // we should include both parameter declaration symbol and property declaration symbol // Parameter Declaration symbol is only visible within function scope, so the symbol is stored in constructor.locals. // Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members - addRange(result, getParameterPropertySymbols(symbol, checker)); + if (symbol.valueDeclaration && isParameter(symbol.valueDeclaration) && isParameterPropertyDeclaration(symbol.valueDeclaration)) { + const paramProps = checker.getSymbolsOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name); + const res = paramProps && cbParameterProperties(paramProps); + if (res) return res; + } // If this is symbol of binding element without propertyName declaration in Object binding pattern // Include the property in the search const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker); - if (bindingElementPropertySymbol) { - result.push(bindingElementPropertySymbol); - addRootSymbols(bindingElementPropertySymbol); - } - - addRootSymbols(symbol); - - return result; - - function addRootSymbols(sym: Symbol): void { - // If this is a union property, add all the symbols from all its source symbols in all unioned types. - // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list - for (const rootSymbol of checker.getRootSymbols(sym)) { - result.push(rootSymbol); + return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol); + function fromRoot(sym: Symbol): T | undefined { + // If this is a union property: + // - In populateSearchSymbolsSet we will add all the symbols from all its source symbols in all unioned types. + // - In findRelatedSymbol, we will just use the union symbol if any source symbol is included in the search. + // If the symbol is an instantiation from a another symbol (e.g. widened symbol): + // - In populateSearchSymbolsSet, add the root the list + // - In findRelatedSymbol, return the source symbol if that is in the search. (Do not return the instantiation symbol.) + return firstDefined(checker.getRootSymbols(sym), rootSymbol => + cbSymbol(sym, rootSymbol) // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions - if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker, result); - } - } + || (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface) && allowBaseTypes(rootSymbol) + ? getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker, base => cbSymbol(sym, rootSymbol, base)) + : undefined)); } } - function getParameterPropertySymbols(symbol: Symbol, checker: TypeChecker): Symbol[] { - return symbol.valueDeclaration && isParameter(symbol.valueDeclaration) && isParameterPropertyDeclaration(symbol.valueDeclaration) - ? checker.getSymbolsOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name) - : undefined; - } - /** * Find symbol of the given property-name and add the symbol to the given result array * @param symbol a symbol to start searching for the given propertyName @@ -1458,100 +1464,39 @@ namespace ts.FindAllReferences.Core { * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol. * The value of previousIterationSymbol is undefined when the function is first called. */ - function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, checker: TypeChecker, result: Symbol[] = []): Symbol[] { + function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, checker: TypeChecker, cb: (symbol: Symbol) => T | undefined): T | undefined { const seen = createMap(); - recur(symbol); - return result; + return recur(symbol); - function recur(symbol: Symbol): void { + function recur(symbol: Symbol): T | undefined { // Use `addToSeen` to ensure we don't infinitely recurse in this situation: // interface C extends C { // /*findRef*/propName: string; // } if (!(symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) || !addToSeen(seen, getSymbolId(symbol))) return; - for (const declaration of symbol.declarations) { - for (const typeReference of getAllSuperTypeNodes(declaration)) { - const type = checker.getTypeAtLocation(typeReference); - if (!(type && type.symbol)) continue; - - const propertySymbol = checker.getPropertyOfType(type, propertyName); - if (propertySymbol) { - result.push(...checker.getRootSymbols(propertySymbol)); - } - - // Visit the typeReference as well to see if it directly or indirectly use that property - recur(type.symbol); - } - } + return firstDefined(symbol.declarations, declaration => firstDefined(getAllSuperTypeNodes(declaration), typeReference => { + const type = checker.getTypeAtLocation(typeReference); + const propertySymbol = type && type.symbol && checker.getPropertyOfType(type, propertyName); + // Visit the typeReference as well to see if it directly or indirectly uses that property + return propertySymbol && (firstDefined(checker.getRootSymbols(propertySymbol), cb) || recur(type.symbol)); + })); } } function getRelatedSymbol(search: Search, referenceSymbol: Symbol, referenceLocation: Node, state: State): Symbol | undefined { const { checker } = state; - if (search.includes(referenceSymbol)) { - return referenceSymbol; - } - - if (referenceSymbol.flags & SymbolFlags.FunctionScopedVariable) { - Debug.assert(!(referenceSymbol.flags & SymbolFlags.Property)); - const paramProps = getParameterPropertySymbols(referenceSymbol, checker); - if (paramProps) { - return getRelatedSymbol(search, find(paramProps, x => !!(x.flags & SymbolFlags.Property))!, referenceLocation, state); - } - } - - // If the reference location is in an object literal, try to get the contextual type for the - // object literal, lookup the property symbol in the contextual type, and use this symbol to - // compare to our searchSymbol - const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation); - if (containingObjectLiteralElement) { - const contextualSymbol = firstDefined(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), findRootSymbol); - if (contextualSymbol) { - return contextualSymbol; - } - - // If the reference location is the name of property from object literal destructuring pattern - // Get the property symbol from the object literal's type and look if thats the search symbol - // In below eg. get 'property' from type of elems iterating type - // for ( { property: p2 } of elems) { } - const propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation, checker); - if (propertySymbol && search.includes(propertySymbol)) { - return propertySymbol; - } - } - - // If the reference location is the binding element and doesn't have property name - // then include the binding element in the related symbols - // let { a } : { a }; - const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol, checker); - if (bindingElementPropertySymbol) { - const fromBindingElement = findRootSymbol(bindingElementPropertySymbol); - if (fromBindingElement) return fromBindingElement; - } - - return findRootSymbol(referenceSymbol); - - function findRootSymbol(sym: Symbol): Symbol | undefined { - // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening) - // Or a union property, use its underlying unioned symbols - return firstDefined(checker.getRootSymbols(sym), rootSymbol => - isMatchingRootSymbol(search, rootSymbol, state.inheritsFromCache, checker) - // For a root symbol that is a component of a union or intersection, use the original (union/intersection) symbol. - // That we when a symbol references the whole union we avoid claiming it references some particular member of the union. - // For a transient symbol we want to use the root symbol instead. - ? getCheckFlags(sym) & CheckFlags.Synthetic ? sym : rootSymbol - : undefined); - } - } - - function isMatchingRootSymbol(search: Search, rootSymbol: Symbol, inheritsFromCache: Map, checker: TypeChecker): boolean { - return search.includes(rootSymbol) - || rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface) - // If we were passed a parent symbol (if 'implementations' set), only include types that are subtypes of the parent symbol. - && !(search.parents && !search.parents.some(parent => explicitlyInheritsFrom(rootSymbol.parent, parent, inheritsFromCache, checker))) - // Try all properties with the same name in any type the containing type extended or implemented. - && getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker).some(search.includes); + return forEachRelatedSymbol(referenceSymbol, referenceLocation, checker, + (sym, rootSymbol, baseSymbol) => search.includes(baseSymbol || rootSymbol || sym) + // For a base type, use the symbol for the derived type. For a synthetic (e.g. union) property, use the union symbol. + ? rootSymbol && !(getCheckFlags(sym) & CheckFlags.Synthetic) ? rootSymbol : sym + : undefined, + paramProps => referenceSymbol.flags & SymbolFlags.FunctionScopedVariable + ? getRelatedSymbol(search, find(paramProps, x => !!(x.flags & SymbolFlags.Property))!, referenceLocation, state) + : undefined, + /*allowBaseTypes*/ rootSymbol => + !(search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker))), + /*includeShorthandDestructuring*/ true); } /** Gets all symbols for one property. Does not get symbols for every property. */ diff --git a/tests/cases/fourslash/findAllRefsForComputedProperties.ts b/tests/cases/fourslash/findAllRefsForComputedProperties.ts index 5e11ec6f357..7dac0432e94 100644 --- a/tests/cases/fourslash/findAllRefsForComputedProperties.ts +++ b/tests/cases/fourslash/findAllRefsForComputedProperties.ts @@ -12,13 +12,9 @@ //// ["[|{| "isDefinition": true |}prop1|]"]: function () { }, ////} -const [r0, r1, r2] = test.ranges(); -verify.referenceGroups([r0, r1], [ +const ranges = test.ranges(); +const [r0, r1, r2] = ranges; +verify.referenceGroups(ranges, [ { definition: { text: '(property) I["prop1"]: () => void', range: r0 }, ranges: [r0, r2] }, { definition: { text: '(property) C["prop1"]: any', range: r1 }, ranges: [r1] }, ]); -verify.referenceGroups(r2, [ - { definition: { text: '(property) I["prop1"]: () => void', range: r0 }, ranges: [r0] }, - { definition: { text: '(property) C["prop1"]: any', range: r1 }, ranges: [r1] }, - { definition: { text: '(property) ["prop1"]: () => void', range: r2 }, ranges: [r2] }, -]); diff --git a/tests/cases/fourslash/findAllRefsForComputedProperties2.ts b/tests/cases/fourslash/findAllRefsForComputedProperties2.ts index 1461dc304a5..81abd714d32 100644 --- a/tests/cases/fourslash/findAllRefsForComputedProperties2.ts +++ b/tests/cases/fourslash/findAllRefsForComputedProperties2.ts @@ -12,13 +12,9 @@ //// ["[|{| "isDefinition": true |}42|]"]: function () { } ////} -const [r0, r1, r2] = test.ranges(); -verify.referenceGroups([r0, r1], [ +const ranges = test.ranges(); +const [r0, r1, r2] = ranges; +verify.referenceGroups(ranges, [ { definition: { text: '(method) I[42](): void', range: r0 }, ranges: [r0, r2] }, { definition: { text: '(property) C[42]: any', range: r1 }, ranges: [r1] }, ]); -verify.referenceGroups(r2, [ - { definition: { text: '(method) I[42](): void', range: r0 }, ranges: [r0] }, - { definition: { text: '(property) C[42]: any', range: r1 }, ranges: [r1] }, - { definition: { text: '(property) ["42"]: () => void', range: r2 }, ranges: [r2] }, -]); diff --git a/tests/cases/fourslash/findAllRefsForMappedType.ts b/tests/cases/fourslash/findAllRefsForMappedType.ts index 2247b4cbf08..904dc8c42c7 100644 --- a/tests/cases/fourslash/findAllRefsForMappedType.ts +++ b/tests/cases/fourslash/findAllRefsForMappedType.ts @@ -6,14 +6,4 @@ ////const u: U = { [|{| "isWriteAccess": true, "isDefinition": true |}a|]: "" } ////const v: V = { [|{| "isWriteAccess": true, "isDefinition": true |}a|]: true } -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) T.a: number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(property) T.a: number", ranges: [r0, r2] }, - { definition: "(property) a: string", ranges: [r1] } -]); -verify.referenceGroups(r2, [ - { definition: "(property) T.a: number", ranges: [r0, r1] }, - { definition: "(property) a: true", ranges: [r2] } -]); +verify.singleReferenceGroup("(property) T.a: number"); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts index ac6efaecf5e..a8dd5bda227 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts @@ -18,12 +18,8 @@ const ranges = test.ranges(); const [r0, r1, r2, r3, r4] = ranges; -verify.referenceGroups([r0, r1, r3], [{ definition: "(property) I.property1: number", ranges }]); +verify.referenceGroups([r0, r1, r3, r4], [{ definition: "(property) I.property1: number", ranges }]); verify.referenceGroups(r2, [ { definition: "(property) I.property1: number", ranges: [r0, r1, r3, r4] }, { definition: "let property1: number", ranges: [r2] } ]); -verify.referenceGroups(r4, [ - { definition: "(property) I.property1: number", ranges: [r0, r1, r2, r3] }, - { definition: "(property) property1: any", ranges: [r4] } -]); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts index f9415ab6a81..69d1f6ac2ff 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts @@ -4,10 +4,4 @@ //// ////p, [{ [|{| "isWriteAccess": true, "isDefinition": true |}a|]: p, b }] = [{ [|{| "isWriteAccess": true, "isDefinition": true |}a|]: 10, b: true }]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) a: any", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(property) a: any", ranges: [r0] }, - { definition: "(property) a: number", ranges: [r1] } -]); +verify.singleReferenceGroup("(property) a: any"); diff --git a/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts b/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts index dec6575ebc4..e4e9b830510 100644 --- a/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts +++ b/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts @@ -17,14 +17,4 @@ //// [|{| "isWriteAccess": true, "isDefinition": true |}a|]: "ss" ////}; -const ranges = test.ranges(); -const [r0, r1, r2, r3] = ranges; -verify.referenceGroups([r0, r2], [{ definition: "(property) IFoo.a: string", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(property) IFoo.a: string", ranges: [r0, r2, r3] }, - { definition: "(property) a: string", ranges: [r1] } -]); -verify.referenceGroups(r3, [ - { definition: "(property) IFoo.a: string", ranges: [r0, r1, r2] }, - { definition: "(property) a: string", ranges: [r3] } -]); +verify.singleReferenceGroup("(property) IFoo.a: string"); diff --git a/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts b/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts index 11f83c39ae8..1964ebf2c2c 100644 --- a/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts +++ b/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts @@ -11,18 +11,9 @@ ////const a: A = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 }; ////const b: B = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 }; -const [r0, r1, r2, r3] = test.ranges(); -verify.referenceGroups([r0, r1], [ +const ranges = test.ranges(); +const [r0, r1, r2, r3] = ranges; +verify.referenceGroups(ranges, [ { definition: "(property) A.x: string | number", ranges: [r0, r2] }, { definition: "(property) B.x: number", ranges: [r1, r3] }, ]); -verify.referenceGroups(r2, [ - { definition: "(property) A.x: string | number", ranges: [r0] }, - { definition: "(property) B.x: number", ranges: [r1, r3] }, - { definition: "(property) x: number", ranges: [r2] }, -]); -verify.referenceGroups(r3, [ - { definition: "(property) A.x: string | number", ranges: [r0, r2] }, - { definition: "(property) B.x: number", ranges: [r1] }, - { definition: "(property) x: number", ranges: [r3] }, -]); diff --git a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts index 897bf9f562a..b25c08cd692 100644 --- a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts +++ b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts @@ -7,10 +7,10 @@ //// obj.[|name|]; const [r0, r1, r2, r3, r4] = test.ranges(); -verify.referenceGroups(r0, [{ definition: "var name: string", ranges: [r0, r1, r3] }]); //r3 +verify.referenceGroups([r0, r3], [{ definition: "var name: string", ranges: [r0, r1, r3] }]); verify.referenceGroups(r1, [ - { definition: "var name: string", ranges: [r0, r3] }, - { definition: "(property) name: string", ranges: [r1, r4] } + { definition: "var name: string", ranges: [r0, r1, r3] }, + { definition: "(property) name: string", ranges: [r4] } ]); verify.singleReferenceGroup("(property) name: string", [r2]); verify.referenceGroups(r4, [{ definition: "(property) name: string", ranges: [r1, r4] }]); diff --git a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts index 0f9b95c75ed..6dbbf9e613b 100644 --- a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts +++ b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts @@ -13,7 +13,7 @@ const [r0, r1, r2, r3] = test.ranges(); verify.singleReferenceGroup("var dx: string", [r0]); verify.referenceGroups(r1, [{ definition: "var M.dx: any", ranges: [r1, r2] }]); verify.referenceGroups(r2, [ - { definition: "var M.dx: any", ranges: [r1] }, - { definition: "(property) dx: any", ranges: [r2, r3] } + { definition: "var M.dx: any", ranges: [r1, r2] }, + { definition: "(property) dx: any", ranges: [r3] } ]); verify.referenceGroups(r3, [{ definition: "(property) dx: any", ranges: [r2, r3] }]); diff --git a/tests/cases/fourslash/referencesBloomFilters.ts b/tests/cases/fourslash/referencesBloomFilters.ts index 2f3fd02a827..1b96ef6f1c9 100644 --- a/tests/cases/fourslash/referencesBloomFilters.ts +++ b/tests/cases/fourslash/referencesBloomFilters.ts @@ -14,11 +14,4 @@ // @Filename: redeclaration.ts ////container = { "[|{| "isWriteAccess": true, "isDefinition": true |}searchProp|]" : 18 }; -const ranges = test.ranges(); -const [r0, r1, r2, r3] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) searchProp: number", ranges }]); -verify.referenceGroups([r1, r2], [{ definition: "(property) searchProp: number", ranges }]); -verify.referenceGroups(r3, [ - { definition: "(property) searchProp: number", ranges: [r0, r1, r2] }, - { definition: '(property) "searchProp": number', ranges: [r3] } -]); +verify.singleReferenceGroup("(property) searchProp: number"); diff --git a/tests/cases/fourslash/referencesBloomFilters2.ts b/tests/cases/fourslash/referencesBloomFilters2.ts index 3dea66b593d..6f1dfa16e80 100644 --- a/tests/cases/fourslash/referencesBloomFilters2.ts +++ b/tests/cases/fourslash/referencesBloomFilters2.ts @@ -14,10 +14,4 @@ // @Filename: redeclaration.ts ////container = { "[|{| "isWriteAccess": true, "isDefinition": true |}42|]" : 18 }; -const ranges = test.ranges(); -const [r0, r1, r2, r3] = ranges; -verify.referenceGroups([r0, r1, r2], [{ definition: "(property) 42: number", ranges }]); -verify.referenceGroups(r3, [ - { definition: "(property) 42: number", ranges: [r0, r1, r2] }, - { definition: '(property) "42": number', ranges: [r3] } -]); +verify.singleReferenceGroup("(property) 42: number"); diff --git a/tests/cases/fourslash/referencesFoo.ts b/tests/cases/fourslash/referencesFoo.ts new file mode 100644 index 00000000000..baba29b2185 --- /dev/null +++ b/tests/cases/fourslash/referencesFoo.ts @@ -0,0 +1,15 @@ +/// + +//// class Foo { +//// constructor(private [|{| "isWriteAccess": true, "isDefinition": true |}privateParam|]: number) { +//// let localPrivate = [|privateParam|]; +//// this.[|{| "isWriteAccess": true |}privateParam|] += 10; +//// } +//// } + +const ranges = test.ranges(); +const [r0, r1, r2] = ranges; +verify.referenceGroups(ranges, [ + { definition: "(property) Foo.privateParam: number", ranges: [r0, r2] }, + { definition: "(parameter) privateParam: number", ranges: [r1] } +]); diff --git a/tests/cases/fourslash/referencesForContextuallyTypedObjectLiteralProperties.ts b/tests/cases/fourslash/referencesForContextuallyTypedObjectLiteralProperties.ts index 7d6bc05cf30..f4e0daaab00 100644 --- a/tests/cases/fourslash/referencesForContextuallyTypedObjectLiteralProperties.ts +++ b/tests/cases/fourslash/referencesForContextuallyTypedObjectLiteralProperties.ts @@ -25,12 +25,4 @@ ////// Untped -- should not be included ////var u = { xy: 0 }; -const ranges = test.ranges(); -verify.referenceGroups(ranges[0], [{ definition: "(property) IFoo.xy: number", ranges }]); -for (const range of ranges.slice(1)) { - const type = range.marker.data.type || "number"; - verify.referenceGroups(range, [ - { definition: "(property) IFoo.xy: number", ranges: ranges.filter(r => r !== range) }, - { definition: `(property) xy: ${type}`, ranges: [range] } - ]); -} +verify.singleReferenceGroup("(property) IFoo.xy: number"); diff --git a/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties.ts b/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties.ts index d9f57f2de57..d955ac0b572 100644 --- a/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties.ts +++ b/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties.ts @@ -44,21 +44,8 @@ verify.referenceGroups(bCommon, [ { definition: "(property) B.common: number", ranges: [bCommon] }, { definition: "(property) common: string | number", ranges: unionRefs }, ]); - -unionRefs.forEach((unionRef, idx) => { - const type = unionRef.marker.data.type; - const last2 = [ - { definition: `(property) common: string | number`, ranges: unionRefs.filter(u => u != unionRef) }, - { definition: `(property) common: ${type}`, ranges: [unionRef] }, - ]; - if (idx === 0) { - const tmp = last2[0]; - last2[0] = last2[1]; - last2[1] = tmp; - } - verify.referenceGroups(unionRef, [ - { definition: "(property) A.common: string", ranges: [aCommon] }, - { definition: "(property) B.common: number", ranges: [bCommon] }, - ...last2, - ]); -}); +verify.referenceGroups(unionRefs, [ + { definition: "(property) A.common: string", ranges: [aCommon] }, + { definition: "(property) B.common: number", ranges: [bCommon] }, + { definition: `(property) common: string | number`, ranges: unionRefs }, +]); diff --git a/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties2.ts b/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties2.ts index 2c48e353b03..3ea7cd9b275 100644 --- a/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties2.ts +++ b/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties2.ts @@ -34,12 +34,4 @@ ////var u1 = { a: 0, b: 0, common: "" }; ////var u2 = { b: 0, common: 0 }; -const ranges = test.ranges(); -verify.referenceGroups(ranges[0], [{ definition: "(property) B.b: number", ranges }]); -for (const reference of ranges.slice(1)) { - const type = reference.marker.data.type; - verify.referenceGroups(reference, [ - { definition: "(property) B.b: number", ranges: ranges.filter(r => r !== reference) }, - { definition: `(property) b: ${type}`, ranges: [reference] } - ]); -} +verify.singleReferenceGroup("(property) B.b: number"); diff --git a/tests/cases/fourslash/referencesForNumericLiteralPropertyNames.ts b/tests/cases/fourslash/referencesForNumericLiteralPropertyNames.ts index a869ba8bcc1..79dc04ecaee 100644 --- a/tests/cases/fourslash/referencesForNumericLiteralPropertyNames.ts +++ b/tests/cases/fourslash/referencesForNumericLiteralPropertyNames.ts @@ -9,15 +9,4 @@ ////x = { "[|{| "isWriteAccess": true, "isDefinition": true |}12|]": 0 }; ////x = { [|{| "isWriteAccess": true, "isDefinition": true |}12|]: 0 }; -//verify.singleReferenceGroup("(property) Foo[12]: any"); -const ranges = test.ranges(); -const [r0, r1, r2, r3] = ranges; -verify.referenceGroups([r0, r1], [{ definition: "(property) Foo[12]: any", ranges }]); -verify.referenceGroups(r2, [ - { definition: "(property) Foo[12]: any", ranges: [r0, r1, r3] }, - { definition: "(property) \"12\": number", ranges: [r2] } -]); -verify.referenceGroups(r3, [ - { definition: "(property) Foo[12]: any", ranges: [r0, r1, r2] }, - { definition: "(property) 12: number", ranges: [r3] } -]); +verify.singleReferenceGroup("(property) Foo[12]: any"); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts index c5ae2f0c586..5c98eddadce 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts @@ -10,14 +10,4 @@ ////x = { "[|{| "isWriteAccess": true, "isDefinition": true |}ss|]": 0 }; ////x = { [|{| "isWriteAccess": true, "isDefinition": true |}ss|]: 0 }; -const ranges = test.ranges(); -const [r0, r1, r2, r3, r4] = ranges; -verify.referenceGroups([r0, r1, r2], [{ definition: '(property) Foo["ss"]: any', ranges }]); -verify.referenceGroups(r3, [ - { definition: '(property) Foo["ss"]: any', ranges: [r0, r1, r2, r4] }, - { definition: '(property) "ss": number', ranges: [r3] } -]); -verify.referenceGroups(r4, [ - { definition: '(property) Foo["ss"]: any', ranges: [r0, r1, r2, r3] }, - { definition: '(property) ss: number', ranges: [r4] } -]); +verify.singleReferenceGroup('(property) Foo["ss"]: any');