mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-11 09:24:19 -06:00
Fixes export destructured variables reference (#32007)
* Add basic test for current behavior * Fixes getting destructured variables references(#31922) * Add test case that renames destructured property * Fixes missing nested object destrucuturing variable references
This commit is contained in:
parent
c1e0db7953
commit
33a6509751
@ -577,10 +577,10 @@ namespace ts.FindAllReferences {
|
||||
// If a reference is a class expression, the exported node would be its parent.
|
||||
// If a reference is a variable declaration, the exported node would be the variable statement.
|
||||
function getExportNode(parent: Node, node: Node): Node | undefined {
|
||||
if (parent.kind === SyntaxKind.VariableDeclaration) {
|
||||
const p = parent as VariableDeclaration;
|
||||
return p.name !== node ? undefined :
|
||||
p.parent.kind === SyntaxKind.CatchClause ? undefined : p.parent.parent.kind === SyntaxKind.VariableStatement ? p.parent.parent : undefined;
|
||||
const declaration = isVariableDeclaration(parent) ? parent : isBindingElement(parent) ? walkUpBindingElementsAndPatterns(parent) : undefined;
|
||||
if (declaration) {
|
||||
return (parent as VariableDeclaration | BindingElement).name !== node ? undefined :
|
||||
isCatchClause(declaration.parent) ? undefined : isVariableStatement(declaration.parent.parent) ? declaration.parent.parent : undefined;
|
||||
}
|
||||
else {
|
||||
return parent;
|
||||
|
||||
@ -131,6 +131,7 @@
|
||||
"unittests/tsserver/formatSettings.ts",
|
||||
"unittests/tsserver/getApplicableRefactors.ts",
|
||||
"unittests/tsserver/getEditsForFileRename.ts",
|
||||
"unittests/tsserver/getExportReferences.ts",
|
||||
"unittests/tsserver/importHelpers.ts",
|
||||
"unittests/tsserver/inferredProjects.ts",
|
||||
"unittests/tsserver/languageService.ts",
|
||||
|
||||
@ -1,11 +1,4 @@
|
||||
namespace ts.projectSystem {
|
||||
interface DocumentSpanFromSubstring {
|
||||
file: File;
|
||||
text: string;
|
||||
options?: SpanFromSubstringOptions;
|
||||
contextText?: string;
|
||||
contextOptions?: SpanFromSubstringOptions;
|
||||
}
|
||||
function documentSpanFromSubstring({ file, text, contextText, options, contextOptions }: DocumentSpanFromSubstring): DocumentSpan {
|
||||
const contextSpan = contextText !== undefined ? documentSpanFromSubstring({ file, text: contextText, options: contextOptions }) : undefined;
|
||||
return {
|
||||
@ -19,19 +12,6 @@ namespace ts.projectSystem {
|
||||
return documentSpanFromSubstring(input);
|
||||
}
|
||||
|
||||
interface MakeReferenceItem extends DocumentSpanFromSubstring {
|
||||
isDefinition: boolean;
|
||||
lineText: string;
|
||||
}
|
||||
function makeReferenceItem({ isDefinition, lineText, ...rest }: MakeReferenceItem): protocol.ReferencesResponseItem {
|
||||
return {
|
||||
...protocolFileSpanWithContextFromSubstring(rest),
|
||||
isDefinition,
|
||||
isWriteAccess: isDefinition,
|
||||
lineText,
|
||||
};
|
||||
}
|
||||
|
||||
interface MakeReferenceEntry extends DocumentSpanFromSubstring {
|
||||
isDefinition: boolean;
|
||||
}
|
||||
|
||||
185
src/testRunner/unittests/tsserver/getExportReferences.ts
Normal file
185
src/testRunner/unittests/tsserver/getExportReferences.ts
Normal file
@ -0,0 +1,185 @@
|
||||
namespace ts.projectSystem {
|
||||
describe("unittests:: tsserver:: getExportReferences", () => {
|
||||
const exportVariable = "export const value = 0;";
|
||||
const exportArrayDestructured = "export const [valueA, valueB] = [0, 1];";
|
||||
const exportObjectDestructured = "export const { valueC, valueD: renamedD } = { valueC: 0, valueD: 1 };";
|
||||
const exportNestedObject = "export const { nest: [valueE, { valueF }] } = { nest: [0, { valueF: 1 }] };";
|
||||
|
||||
const mainTs: File = {
|
||||
path: "/main.ts",
|
||||
content: 'import { value, valueA, valueB, valueC, renamedD, valueE, valueF } from "./mod";',
|
||||
};
|
||||
const modTs: File = {
|
||||
path: "/mod.ts",
|
||||
content: `${exportVariable}
|
||||
${exportArrayDestructured}
|
||||
${exportObjectDestructured}
|
||||
${exportNestedObject}
|
||||
`,
|
||||
};
|
||||
const tsconfig: File = {
|
||||
path: "/tsconfig.json",
|
||||
content: "{}",
|
||||
};
|
||||
|
||||
function makeSampleSession() {
|
||||
const host = createServerHost([mainTs, modTs, tsconfig]);
|
||||
const session = createSession(host);
|
||||
openFilesForSession([mainTs, modTs], session);
|
||||
return session;
|
||||
}
|
||||
|
||||
const referenceMainTs = (mainTs: File, text: string): protocol.ReferencesResponseItem =>
|
||||
makeReferenceItem({
|
||||
file: mainTs,
|
||||
isDefinition: true,
|
||||
lineText: mainTs.content,
|
||||
contextText: mainTs.content,
|
||||
text,
|
||||
});
|
||||
|
||||
const referenceModTs = (
|
||||
texts: { text: string; lineText: string; contextText?: string },
|
||||
override: Partial<MakeReferenceItem> = {},
|
||||
): protocol.ReferencesResponseItem =>
|
||||
makeReferenceItem({
|
||||
file: modTs,
|
||||
isDefinition: true,
|
||||
...texts,
|
||||
...override,
|
||||
});
|
||||
|
||||
it("should get const variable declaration references", () => {
|
||||
const session = makeSampleSession();
|
||||
|
||||
const response = executeSessionRequest<protocol.ReferencesRequest, protocol.ReferencesResponse>(
|
||||
session,
|
||||
protocol.CommandTypes.References,
|
||||
protocolFileLocationFromSubstring(modTs, "value"),
|
||||
);
|
||||
|
||||
const expectResponse = {
|
||||
refs: [
|
||||
referenceModTs({ text: "value", lineText: exportVariable, contextText: exportVariable }),
|
||||
referenceMainTs(mainTs, "value"),
|
||||
],
|
||||
symbolDisplayString: "const value: 0",
|
||||
symbolName: "value",
|
||||
symbolStartOffset: protocolLocationFromSubstring(modTs.content, "value").offset,
|
||||
};
|
||||
|
||||
assert.deepEqual(response, expectResponse);
|
||||
});
|
||||
|
||||
it("should get array destructuring declaration references", () => {
|
||||
const session = makeSampleSession();
|
||||
const response = executeSessionRequest<protocol.ReferencesRequest, protocol.ReferencesResponse>(
|
||||
session,
|
||||
protocol.CommandTypes.References,
|
||||
protocolFileLocationFromSubstring(modTs, "valueA"),
|
||||
);
|
||||
|
||||
const expectResponse = {
|
||||
refs: [
|
||||
referenceModTs({
|
||||
text: "valueA",
|
||||
lineText: exportArrayDestructured,
|
||||
contextText: exportArrayDestructured,
|
||||
}),
|
||||
referenceMainTs(mainTs, "valueA"),
|
||||
],
|
||||
symbolDisplayString: "const valueA: number",
|
||||
symbolName: "valueA",
|
||||
symbolStartOffset: protocolLocationFromSubstring(modTs.content, "valueA").offset,
|
||||
};
|
||||
|
||||
assert.deepEqual(response, expectResponse);
|
||||
});
|
||||
|
||||
it("should get object destructuring declaration references", () => {
|
||||
const session = makeSampleSession();
|
||||
const response = executeSessionRequest<protocol.ReferencesRequest, protocol.ReferencesResponse>(
|
||||
session,
|
||||
protocol.CommandTypes.References,
|
||||
protocolFileLocationFromSubstring(modTs, "valueC"),
|
||||
);
|
||||
const expectResponse = {
|
||||
refs: [
|
||||
referenceModTs({
|
||||
text: "valueC",
|
||||
lineText: exportObjectDestructured,
|
||||
contextText: exportObjectDestructured,
|
||||
}),
|
||||
referenceMainTs(mainTs, "valueC"),
|
||||
referenceModTs(
|
||||
{ text: "valueC", lineText: exportObjectDestructured, contextText: "valueC: 0" },
|
||||
{ options: { index: 1 } },
|
||||
),
|
||||
],
|
||||
symbolDisplayString: "const valueC: number",
|
||||
symbolName: "valueC",
|
||||
symbolStartOffset: protocolLocationFromSubstring(modTs.content, "valueC").offset,
|
||||
};
|
||||
|
||||
assert.deepEqual(response, expectResponse);
|
||||
});
|
||||
|
||||
it("should get object declaration references that renames destructured property", () => {
|
||||
const session = makeSampleSession();
|
||||
const response = executeSessionRequest<protocol.ReferencesRequest, protocol.ReferencesResponse>(
|
||||
session,
|
||||
protocol.CommandTypes.References,
|
||||
protocolFileLocationFromSubstring(modTs, "renamedD"),
|
||||
);
|
||||
|
||||
const expectResponse = {
|
||||
refs: [
|
||||
referenceModTs({
|
||||
text: "renamedD",
|
||||
lineText: exportObjectDestructured,
|
||||
contextText: exportObjectDestructured,
|
||||
}),
|
||||
referenceMainTs(mainTs, "renamedD"),
|
||||
],
|
||||
symbolDisplayString: "const renamedD: number",
|
||||
symbolName: "renamedD",
|
||||
symbolStartOffset: protocolLocationFromSubstring(modTs.content, "renamedD").offset,
|
||||
};
|
||||
|
||||
assert.deepEqual(response, expectResponse);
|
||||
});
|
||||
|
||||
it("should get nested object declaration references", () => {
|
||||
const session = makeSampleSession();
|
||||
const response = executeSessionRequest<protocol.ReferencesRequest, protocol.ReferencesResponse>(
|
||||
session,
|
||||
protocol.CommandTypes.References,
|
||||
protocolFileLocationFromSubstring(modTs, "valueF"),
|
||||
);
|
||||
|
||||
const expectResponse = {
|
||||
refs: [
|
||||
referenceModTs({
|
||||
text: "valueF",
|
||||
lineText: exportNestedObject,
|
||||
contextText: exportNestedObject,
|
||||
}),
|
||||
referenceMainTs(mainTs, "valueF"),
|
||||
referenceModTs(
|
||||
{
|
||||
text: "valueF",
|
||||
lineText: exportNestedObject,
|
||||
contextText: "valueF: 1",
|
||||
},
|
||||
{ options: { index: 1 } },
|
||||
),
|
||||
],
|
||||
symbolDisplayString: "const valueF: number",
|
||||
symbolName: "valueF",
|
||||
symbolStartOffset: protocolLocationFromSubstring(modTs.content, "valueF").offset,
|
||||
};
|
||||
|
||||
assert.deepEqual(response, expectResponse);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -519,6 +519,8 @@ namespace ts.projectSystem {
|
||||
file: File;
|
||||
text: string;
|
||||
options?: SpanFromSubstringOptions;
|
||||
contextText?: string;
|
||||
contextOptions?: SpanFromSubstringOptions;
|
||||
}
|
||||
export function protocolFileSpanFromSubstring({ file, text, options }: DocumentSpanFromSubstring): protocol.FileSpan {
|
||||
return { file: file.path, ...protocolTextSpanFromSubstring(file.content, text, options) };
|
||||
@ -727,4 +729,18 @@ namespace ts.projectSystem {
|
||||
assert.strictEqual(outputs.length, index + 1, JSON.stringify(outputs));
|
||||
}
|
||||
}
|
||||
|
||||
export interface MakeReferenceItem extends DocumentSpanFromSubstring {
|
||||
isDefinition: boolean;
|
||||
lineText: string;
|
||||
}
|
||||
|
||||
export function makeReferenceItem({ isDefinition, lineText, ...rest }: MakeReferenceItem): protocol.ReferencesResponseItem {
|
||||
return {
|
||||
...protocolFileSpanWithContextFromSubstring(rest),
|
||||
isDefinition,
|
||||
isWriteAccess: isDefinition,
|
||||
lineText,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user