mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Clean up FAR aggregation (#48619)
* Clean up FAR and RenameLocations This change had two goals: 1. Make the code easier to understand, primarily by simplifying the callback structure and minimizing side-effects 2. Improve performance by reducing repeated work, both FAR searches of individual projects and default tsconfig searches This implementation attempts to preserve the merging order found in the original code (someone less relevant in the present state of using syntactic isDefinition). * Stop enforcing search and aggregation order ...in preparation for implementing isDefinition explicitly. Also restore convention of referring to `DocumentPosition`s as "locations". * Introduce LanguageService.updateIsDefinitionOfReferencedSymbols ...to allow use of the checker when computing isDefinition across projects. * Update baselines * Tidy diff * De-dup simplified results * Baseline cross-project isDefinition results * Move de-duping upstream to fix Full output * Add server baseline test to confirm searches are not repeated * Manually merge #48758 * Update baseline for newer fix to #48963
This commit is contained in:
@@ -400,7 +400,7 @@ namespace ts.projectSystem {
|
||||
|
||||
const response = executeSessionRequest<protocol.ReferencesRequest, protocol.ReferencesResponse>(session, protocol.CommandTypes.References, protocolFileLocationFromSubstring(userTs, "fnA()"));
|
||||
assert.deepEqual<protocol.ReferencesResponseBody | undefined>(response, {
|
||||
refs: [...referencesUserTs(userTs, /*isDefinition*/ undefined), referenceATs(aTs, /*isDefinition*/ true)], // Presently inconsistent across projects
|
||||
refs: [...referencesUserTs(userTs, /*isDefinition*/ undefined), referenceATs(aTs, /*isDefinition*/ undefined)],
|
||||
symbolName: "fnA",
|
||||
symbolStartOffset: protocolLocationFromSubstring(userTs.content, "fnA()").offset,
|
||||
symbolDisplayString: "function fnA(): void",
|
||||
@@ -455,7 +455,7 @@ namespace ts.projectSystem {
|
||||
},
|
||||
references: [
|
||||
makeReferencedSymbolEntry({ file: userTs, text: "fnA" }),
|
||||
makeReferencedSymbolEntry({ file: aTs, text: "fnA", isDefinition: true, isWriteAccess: true, contextText: "export function fnA() {}" }),
|
||||
makeReferencedSymbolEntry({ file: aTs, text: "fnA", isWriteAccess: true, contextText: "export function fnA() {}" }),
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -581,6 +581,126 @@ testCompositeFunction('why hello there', 42);`
|
||||
baselineTsserverLogs("projectReferences", `finding local reference doesnt load ancestor/sibling projects`, session);
|
||||
});
|
||||
|
||||
it("when finding references in overlapping projects", () => {
|
||||
const solutionLocation = "/user/username/projects/solution";
|
||||
const solutionConfig: File = {
|
||||
path: `${solutionLocation}/tsconfig.json`,
|
||||
content: JSON.stringify({
|
||||
files: [],
|
||||
include: [],
|
||||
references: [
|
||||
{ path: "./a" },
|
||||
{ path: "./b" },
|
||||
{ path: "./c" },
|
||||
{ path: "./d" },
|
||||
]
|
||||
})
|
||||
};
|
||||
const aConfig: File = {
|
||||
path: `${solutionLocation}/a/tsconfig.json`,
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
module: "none"
|
||||
},
|
||||
files: ["./index.ts"]
|
||||
})
|
||||
};
|
||||
const aFile: File = {
|
||||
path: `${solutionLocation}/a/index.ts`,
|
||||
content: `
|
||||
export interface I {
|
||||
M(): void;
|
||||
}`
|
||||
};
|
||||
|
||||
const bConfig: File = {
|
||||
path: `${solutionLocation}/b/tsconfig.json`,
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {
|
||||
composite: true
|
||||
},
|
||||
files: ["./index.ts"],
|
||||
references: [
|
||||
{ path: "../a" }
|
||||
]
|
||||
})
|
||||
};
|
||||
const bFile: File = {
|
||||
path: `${solutionLocation}/b/index.ts`,
|
||||
content: `
|
||||
import { I } from "../a";
|
||||
|
||||
export class B implements I {
|
||||
M() {}
|
||||
}`
|
||||
};
|
||||
|
||||
const cConfig: File = {
|
||||
path: `${solutionLocation}/c/tsconfig.json`,
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {
|
||||
composite: true
|
||||
},
|
||||
files: ["./index.ts"],
|
||||
references: [
|
||||
{ path: "../b" }
|
||||
]
|
||||
})
|
||||
};
|
||||
const cFile: File = {
|
||||
path: `${solutionLocation}/c/index.ts`,
|
||||
content: `
|
||||
import { I } from "../a";
|
||||
import { B } from "../b";
|
||||
|
||||
export const C: I = new B();
|
||||
`
|
||||
};
|
||||
|
||||
const dConfig: File = {
|
||||
path: `${solutionLocation}/d/tsconfig.json`,
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {
|
||||
composite: true
|
||||
},
|
||||
files: ["./index.ts"],
|
||||
references: [
|
||||
{ path: "../c" }
|
||||
]
|
||||
})
|
||||
};
|
||||
const dFile: File = {
|
||||
path: `${solutionLocation}/d/index.ts`,
|
||||
content: `
|
||||
import { I } from "../a";
|
||||
import { C } from "../c";
|
||||
|
||||
export const D: I = C;
|
||||
`
|
||||
};
|
||||
|
||||
const files = [libFile, solutionConfig, aConfig, aFile, bConfig, bFile, cConfig, cFile, dConfig, dFile, libFile];
|
||||
const host = createServerHost(files);
|
||||
const session = createSession(host, { logger: createLoggerWithInMemoryLogs() });
|
||||
openFilesForSession([bFile], session);
|
||||
|
||||
// The first search will trigger project loads
|
||||
session.executeCommandSeq<protocol.ReferencesRequest>({
|
||||
command: protocol.CommandTypes.References,
|
||||
arguments: protocolFileLocationFromSubstring(bFile, "I", { index: 1 })
|
||||
});
|
||||
|
||||
// The second search starts with the projects already loaded
|
||||
// Formerly, this would search some projects multiple times
|
||||
session.executeCommandSeq<protocol.ReferencesRequest>({
|
||||
command: protocol.CommandTypes.References,
|
||||
arguments: protocolFileLocationFromSubstring(bFile, "I", { index: 1 })
|
||||
});
|
||||
|
||||
baselineTsserverLogs("projectReferences", `finding references in overlapping projects`, session);
|
||||
});
|
||||
|
||||
describe("special handling of localness of the definitions for findAllRefs", () => {
|
||||
function verify(scenario: string, definition: string, usage: string, referenceTerm: string) {
|
||||
it(scenario, () => {
|
||||
|
||||
Reference in New Issue
Block a user