mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
findAllReferences: Share code between populateSearchSymbolSet and getRelatedSymbol (#23028)
This commit is contained in:
@@ -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<void>(symbol, location, checker,
|
||||
(sym, root, base) => { result.push(base || root || sym); },
|
||||
parameterProperties => { result.push(...parameterProperties); },
|
||||
/*allowBaseTypes*/ () => !implementations,
|
||||
/*includeShorthandDestructuring*/ false);
|
||||
return result;
|
||||
}
|
||||
|
||||
function forEachRelatedSymbol<T>(
|
||||
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<T>(symbol: Symbol, propertyName: string, checker: TypeChecker, cb: (symbol: Symbol) => T | undefined): T | undefined {
|
||||
const seen = createMap<true>();
|
||||
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<boolean>, 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. */
|
||||
|
||||
@@ -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] },
|
||||
]);
|
||||
|
||||
@@ -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] },
|
||||
]);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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] }
|
||||
]);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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] },
|
||||
]);
|
||||
|
||||
@@ -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] }]);
|
||||
|
||||
@@ -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] }]);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
//// 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] }
|
||||
]);
|
||||
@@ -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");
|
||||
|
||||
@@ -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 },
|
||||
]);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user