From 99fa17e9a29a26bfbd8105f60de10044fa81812b Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 10 Feb 2022 18:33:47 -0800 Subject: [PATCH 01/11] 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). --- src/server/session.ts | 410 +++++++++++++++++++++++++++--------------- 1 file changed, 267 insertions(+), 143 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index ecd5b76ac46f0..fdbba85d68eff 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -303,97 +303,124 @@ namespace ts.server { return createSet(({textSpan}) => textSpan.start + 100003 * textSpan.length, documentSpansEqual); } - function combineProjectOutputForRenameLocations( + function getRenameLocationsWorker( projects: Projects, defaultProject: Project, - initialLocation: DocumentPosition, + initialPosition: DocumentPosition, findInStrings: boolean, findInComments: boolean, { providePrefixAndSuffixTextForRename }: UserPreferences ): readonly RenameLocation[] { - const outputs: RenameLocation[] = []; - const seen = createDocumentSpanSet(); - combineProjectOutputWorker( + const perProjectResults = getPerProjectReferences( projects, defaultProject, - initialLocation, - /*isForRename*/ true, - (project, location, tryAddToTodo) => { - const projectOutputs = project.getLanguageService().findRenameLocations(location.fileName, location.pos, findInStrings, findInComments, providePrefixAndSuffixTextForRename); - if (projectOutputs) { - for (const output of projectOutputs) { - if (!seen.has(output) && !tryAddToTodo(project, documentSpanLocation(output))) { - seen.add(output); - outputs.push(output); - } - } - } - }, + initialPosition, + (project, position) => project.getLanguageService().findRenameLocations(position.fileName, position.pos, findInStrings, findInComments, providePrefixAndSuffixTextForRename), + (renameLocation, cb) => cb(documentSpanLocation(renameLocation)), ); - return outputs; + + // No filtering or dedup'ing is required if there's exactly one project + if (isArray(perProjectResults)) { + return perProjectResults; + } + + const results: RenameLocation[] = []; + const seen = createDocumentSpanSet(); + + for (const project of perProjectResults.projects) { + const projectResults = perProjectResults.resultsMap.get(project); + if (!projectResults) continue; + + for (const result of projectResults) { + // If there's a mapped location, it'll appear in the results for another project + if (!seen.has(result) && !getMappedLocation(documentSpanLocation(result), project)) { + results.push(result); + seen.add(result); + } + } + } + + return results; } - function getDefinitionLocation(defaultProject: Project, initialLocation: DocumentPosition, isForRename: boolean): DocumentPosition | undefined { - const infos = defaultProject.getLanguageService().getDefinitionAtPosition(initialLocation.fileName, initialLocation.pos, /*searchOtherFilesOnly*/ false, isForRename); + function getDefinitionLocation(defaultProject: Project, initialLocation: DocumentPosition): DocumentPosition | undefined { + const infos = defaultProject.getLanguageService().getDefinitionAtPosition(initialLocation.fileName, initialLocation.pos); const info = infos && firstOrUndefined(infos); return info && !info.isLocal ? { fileName: info.fileName, pos: info.textSpan.start } : undefined; } - function combineProjectOutputForReferences( + function getReferencesWorker( projects: Projects, defaultProject: Project, - initialLocation: DocumentPosition, + initialPosition: DocumentPosition, logger: Logger, ): readonly ReferencedSymbol[] { - const outputs: ReferencedSymbol[] = []; - - combineProjectOutputWorker( + const perProjectResults = getPerProjectReferences( projects, defaultProject, - initialLocation, - /*isForRename*/ false, - (project, location, getMappedLocation) => { - logger.info(`Finding references to ${location.fileName} position ${location.pos} in project ${project.getProjectName()}`); - const projectOutputs = project.getLanguageService().findReferences(location.fileName, location.pos); - if (projectOutputs) { - const clearIsDefinition = projectOutputs[0]?.references[0]?.isDefinition === undefined; - for (const referencedSymbol of projectOutputs) { - const mappedDefinitionFile = getMappedLocation(project, documentSpanLocation(referencedSymbol.definition)); - const definition: ReferencedSymbolDefinitionInfo = mappedDefinitionFile === undefined ? - referencedSymbol.definition : - { - ...referencedSymbol.definition, - textSpan: createTextSpan(mappedDefinitionFile.pos, referencedSymbol.definition.textSpan.length), - fileName: mappedDefinitionFile.fileName, - contextSpan: getMappedContextSpan(referencedSymbol.definition, project) - }; - - let symbolToAddTo = find(outputs, o => documentSpansEqual(o.definition, definition)); - if (!symbolToAddTo) { - symbolToAddTo = { definition, references: [] }; - outputs.push(symbolToAddTo); - } + initialPosition, + (project, position) => { + logger.info(`Finding references to ${position.fileName} position ${position.pos} in project ${project.getProjectName()}`); + return project.getLanguageService().findReferences(position.fileName, position.pos); + }, + (referencedSymbol, cb) => { + cb(documentSpanLocation(referencedSymbol.definition)); + for (const ref of referencedSymbol.references) { + cb(documentSpanLocation(ref)); + } + }, + ); - for (const ref of referencedSymbol.references) { - // If it's in a mapped file, that is added to the todo list by `getMappedLocation`. - if (!contains(symbolToAddTo.references, ref, documentSpansEqual) && !getMappedLocation(project, documentSpanLocation(ref))) { - if (clearIsDefinition) { - delete ref.isDefinition; - } - symbolToAddTo.references.push(ref); - } + // No re-mapping is required if there's exactly one project + if (isArray(perProjectResults)) { + return perProjectResults; + } + + // We need to de-duplicate and aggregate the results by choosing an authoritative version + // of each definition and merging references from all the projects where they appear. + + const results: ReferencedSymbol[] = []; + + for (const project of perProjectResults.projects) { + const projectResults = perProjectResults.resultsMap.get(project); + if (!projectResults) continue; + + const clearIsDefinition = projectOutputs[0].references[0].isDefinition === undefined; + + for (const referencedSymbol of projectResults) { + const mappedDefinitionFile = getMappedLocation(documentSpanLocation(referencedSymbol.definition), project); + const definition: ReferencedSymbolDefinitionInfo = mappedDefinitionFile === undefined ? + referencedSymbol.definition : + { + ...referencedSymbol.definition, + textSpan: createTextSpan(mappedDefinitionFile.pos, referencedSymbol.definition.textSpan.length), // Why would the length be the same in the original? + fileName: mappedDefinitionFile.fileName, + contextSpan: getMappedContextSpan(referencedSymbol.definition, project) + }; + + let symbolToAddTo = find(results, o => documentSpansEqual(o.definition, definition)); + if (!symbolToAddTo) { + symbolToAddTo = { definition, references: [] }; + results.push(symbolToAddTo); + } + + for (const ref of referencedSymbol.references) { + if (!contains(symbolToAddTo.references, ref, documentSpansEqual) && !getMappedLocation(documentSpanLocation(ref), project)) { + if (clearIsDefinition) { + delete ref.isDefinition; } + symbolToAddTo.references.push(ref); } } - }, - ); + } + } - return outputs.filter(o => o.references.length !== 0); + return results.filter(o => o.references.length !== 0); } - interface ProjectAndLocation { + interface ProjectAndPosition { readonly project: Project; - readonly location: TLocation; + readonly position: DocumentPosition; } function forEachProjectInProjects(projects: Projects, path: string | undefined, cb: (project: Project, path: string | undefined) => void): void { @@ -409,53 +436,192 @@ namespace ts.server { } } - type CombineProjectOutputCallback = ( - project: Project, - location: TLocation, - getMappedLocation: (project: Project, location: DocumentPosition) => DocumentPosition | undefined, - ) => void; + interface PerProjectResults { + // The projects that were searched in the order in which they were searched. + // (The order may be slightly fudged to prioritize "authoritative" projects.) + projects: readonly Project[]; + // The results for each project. + // May not have an entry for every member of `projects`. + resultsMap: ESMap; + } - function combineProjectOutputWorker( + /** + * @param projects Projects initially known to contain {@link initialPosition} + * @param defaultProject The default project containing {@link initialPosition} + * @param initialPosition Where the search operation was triggered + * @param getResultsForPosition This is where you plug in `findReferences`, `renameLocation`, etc + * @param forPositionInResult Given an item returned by {@link getResultsForPosition} enumerate the positions referred to by that result + * @returns In the common case where there's only one project, returns an array of results from {@link getResultsForPosition}. + * If multiple projects were searched - even if they didn't return results - the result will be a {@link PerProjectResults}. + */ + function getPerProjectReferences( projects: Projects, defaultProject: Project, - initialLocation: TLocation, - isForRename: boolean, - cb: CombineProjectOutputCallback, - ): void { - const projectService = defaultProject.projectService; - let toDo: ProjectAndLocation[] | undefined; - const seenProjects = new Set(); - forEachProjectInProjects(projects, initialLocation && initialLocation.fileName, (project, path) => { - // TLocation should be either `DocumentPosition` or `undefined`. Since `initialLocation` is `TLocation` this cast should be valid. - const location = (initialLocation ? { fileName: path, pos: initialLocation.pos } : undefined) as TLocation; - toDo = callbackProjectAndLocation(project, location, projectService, toDo, seenProjects, cb); + initialPosition: DocumentPosition, + getResultsForPosition: (project: Project, position: DocumentPosition) => readonly TResult[] | undefined, + forPositionInResult: (result: TResult, cb: (position: DocumentPosition) => void) => void, + ): readonly TResult[] | PerProjectResults { + // If `getResultsForPosition` returns results for a project, they go in here + const resultsMap = new Map(); + + // The `isDefinition` property in a FAR result depends on where the search was started. + // This matters when a symbol is aliased (e.g. in an import or an export) because either + // the original declaration or the alias can be the one flagged `isDefinition`. + // As a result, searches starting from `initialPosition` are more authoritative than + // searches started from locations discovered during other searches. To ensure that + // these searches are prioritized, both during search (since we try to avoid searching a + // given project multiple times) and during aggregation (i.e. in the caller), we maintain + // separate work queues for the two types of searches. + + const initialPositionQueue: ProjectAndPosition[] = []; + forEachProjectInProjects(projects, initialPosition.fileName, (project, path) => { + const position = { fileName: path!, pos: initialPosition.pos }; + initialPositionQueue.push({ project, position }); }); - // After initial references are collected, go over every other project and see if it has a reference for the symbol definition. - if (initialLocation) { - const defaultDefinition = getDefinitionLocation(defaultProject, initialLocation, isForRename); + const otherPositionQueue: ProjectAndPosition[] = []; + + const projectService = defaultProject.projectService; + const cancellationToken = defaultProject.getCancellationToken(); + + const defaultDefinition = getDefinitionLocation(defaultProject, initialPosition); + + // Don't call these unless !!defaultDefinition + const getGeneratedDefinition = memoize(() => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition!.fileName) ? + defaultDefinition : + defaultProject.getLanguageService().getSourceMapper().tryGetGeneratedPosition(defaultDefinition!)); + const getSourceDefinition = memoize(() => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition!.fileName) ? + defaultDefinition : + defaultProject.getLanguageService().getSourceMapper().tryGetSourcePosition(defaultDefinition!)); + + // Track which projects we have already searched so that we don't repeat searches. + // We store the project key, rather than the project, because that's what `loadAncestorProjectTree` wants. + // (For that same reason, we don't use `resultsMap` for this check.) + const searchedProjects = new Set(); + // Caveat: We *can* re-search an already-searched project if the previous search was not initiated from `initialPosition`. + // Our search order should make this rare or impossible. + const initialPositionSearchedProjects = new Set(); + + // The caller needs to know the search order to aggregate properly, so we track it as we go. + // As with the sets and work queues, we need to track the two kinds of searches separately + // so that we can prioritize `initialPosition` searches over other position searches in the + // final result. + + const initialPositionProjects: Project[] = []; + const otherPositionProjects: Project[] = []; + + onCancellation: + while (initialPositionQueue.length || otherPositionQueue.length) { + // Drain the `initialPositionQueue` before doing anything else + while (initialPositionQueue.length) { + if (cancellationToken.isCancellationRequested()) break onCancellation; + + const { project, position } = initialPositionQueue.shift()!; + + if (isLocationProjectReferenceRedirect(project, position)) continue; + + if (!tryAddToSet(initialPositionSearchedProjects, getProjectKey(project))) continue; + searchedProjects.add(getProjectKey(project)); // Unconditional + initialPositionProjects.push(project); + + const projectResults = searchPosition(project, position); + if (projectResults) { + // There may already be an other-position search result in the map, + // in which case, clobbering it is desirable + resultsMap.set(project, projectResults); + } + } + + // At this point, we know about all projects passed in as arguments and any projects in which + // `getResultsForPosition` has returned results. We expand that set to include any projects + // downstream from any of these and then queue new initial-position searches for any new project + // containing `initialPosition`. if (defaultDefinition) { - const getGeneratedDefinition = memoize(() => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition.fileName) ? - defaultDefinition : - defaultProject.getLanguageService().getSourceMapper().tryGetGeneratedPosition(defaultDefinition)); - const getSourceDefinition = memoize(() => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition.fileName) ? - defaultDefinition : - defaultProject.getLanguageService().getSourceMapper().tryGetSourcePosition(defaultDefinition)); - projectService.loadAncestorProjectTree(seenProjects); + // This seems to mean "load all projects downstream from any member of `seenProjects`". + projectService.loadAncestorProjectTree(searchedProjects); projectService.forEachEnabledProject(project => { - if (!addToSeen(seenProjects, project)) return; - const definition = mapDefinitionInProject(defaultDefinition, project, getGeneratedDefinition, getSourceDefinition); - if (definition) { - toDo = callbackProjectAndLocation(project, definition as TLocation, projectService, toDo, seenProjects, cb); + if (cancellationToken.isCancellationRequested()) return; // There's no mechanism for skipping the remaining projects + if (initialPositionSearchedProjects.has(getProjectKey(project))) return; // Can loop forever without this (enqueue here, dequeue above, repeat) + const position = mapDefinitionInProject(defaultDefinition, project, getGeneratedDefinition, getSourceDefinition); + if (position) { + initialPositionQueue.push({ project, position }); } }); } + + // Ignore `otherPositionQueue` until `initialPositionQueue` is empty. + // If we didn't, we would still prioritize initial-position results, but we'd likely search more projects twice. + if (initialPositionQueue.length) continue; + + // Drain the `otherPositionQueue`. This can't add to `initialPositionQueue`, but it could cause more projects to + // be loaded, which might lead to more initial-position searches. + while (otherPositionQueue.length) { + if (cancellationToken.isCancellationRequested()) break onCancellation; + + const { project, position } = otherPositionQueue.shift()!; + + if (isLocationProjectReferenceRedirect(project, position)) continue; + + if (!tryAddToSet(searchedProjects, getProjectKey(project))) continue; + otherPositionProjects.push(project); + + const projectResults = searchPosition(project, position); + if (projectResults) { + Debug.assert(!resultsMap.has(project)); // Or we wouldn't have tried searching + resultsMap.set(project, projectResults); + } + } + } + + // It's not worth allocating a new array to hold the concatenation + const allProjects = initialPositionProjects; + for (const project of otherPositionProjects) { + if (!initialPositionSearchedProjects.has(getProjectKey(project))) { + allProjects.push(project); + } } - while (toDo && toDo.length) { - const next = toDo.pop(); - Debug.assertIsDefined(next); - toDo = callbackProjectAndLocation(next.project, next.location, projectService, toDo, seenProjects, cb); + // In the common case where there's only one project, return a simpler result to make + // it easier for the caller to skip post-processing. + if (allProjects.length === 1) { + return resultsMap.get(allProjects[0]) ?? []; + } + + return { projects: allProjects, resultsMap }; + + // May enqueue to otherPositionQueue + function searchPosition(project: Project, position: DocumentPosition): readonly TResult[] | undefined { + const projectResults = getResultsForPosition(project, position); + if (!projectResults) return undefined; + + for (const result of projectResults) { + forPositionInResult(result, position => { + // This may trigger a search for a tsconfig, but there are several layers of caching that make it inexpensive + const originalPosition = projectService.getOriginalLocationEnsuringConfiguredProject(project, position); + if (!originalPosition) return; + + const originalScriptInfo = projectService.getScriptInfo(originalPosition.fileName)!; + + for (const project of originalScriptInfo.containingProjects) { + if (!project.isOrphan()) { + otherPositionQueue.push({ project, position: originalPosition }); + } + } + + const symlinkedProjectsMap = projectService.getSymlinkedProjects(originalScriptInfo); + if (symlinkedProjectsMap) { + symlinkedProjectsMap.forEach((symlinkedProjects, symlinkedPath) => { + for (const symlinkedProject of symlinkedProjects) { + if (!symlinkedProject.isOrphan()) { + otherPositionQueue.push({ project: symlinkedProject, position: { fileName: symlinkedPath as string, pos: originalPosition.pos } }); + } + } + }); + } + }); + } + + return projectResults; } } @@ -492,49 +658,6 @@ namespace ts.server { sourceFile.resolvedPath !== project.toPath(location.fileName); } - function callbackProjectAndLocation( - project: Project, - location: TLocation, - projectService: ProjectService, - toDo: ProjectAndLocation[] | undefined, - seenProjects: Set, - cb: CombineProjectOutputCallback, - ): ProjectAndLocation[] | undefined { - if (project.getCancellationToken().isCancellationRequested()) return undefined; // Skip rest of toDo if cancelled - // If this is not the file we were actually looking, return rest of the toDo - if (isLocationProjectReferenceRedirect(project, location)) return toDo; - cb(project, location, (innerProject, location) => { - addToSeen(seenProjects, project); - const originalLocation = projectService.getOriginalLocationEnsuringConfiguredProject(innerProject, location); - if (!originalLocation) return undefined; - - const originalScriptInfo = projectService.getScriptInfo(originalLocation.fileName)!; - toDo = toDo || []; - - for (const project of originalScriptInfo.containingProjects) { - addToTodo(project, originalLocation as TLocation, toDo, seenProjects); - } - const symlinkedProjectsMap = projectService.getSymlinkedProjects(originalScriptInfo); - if (symlinkedProjectsMap) { - symlinkedProjectsMap.forEach((symlinkedProjects, symlinkedPath) => { - for (const symlinkedProject of symlinkedProjects) { - addToTodo(symlinkedProject, { fileName: symlinkedPath as string, pos: originalLocation.pos } as TLocation, toDo!, seenProjects); - } - }); - } - return originalLocation === location ? undefined : originalLocation; - }); - return toDo; - } - - function addToTodo(project: Project, location: TLocation, toDo: Push>, seenProjects: Set): void { - if (!project.isOrphan() && addToSeen(seenProjects, project)) toDo.push({ project, location }); - } - - function addToSeen(seenProjects: Set, project: Project) { - return tryAddToSet(seenProjects, getProjectKey(project)); - } - function getProjectKey(project: Project) { return isConfiguredProject(project) ? project.canonicalConfigFilePath : project.getProjectName(); } @@ -1665,7 +1788,7 @@ namespace ts.server { if (!renameInfo.canRename) return simplifiedResult ? { info: renameInfo, locs: [] } : []; - const locations = combineProjectOutputForRenameLocations( + const locations = getRenameLocationsWorker( projects, defaultProject, { fileName: args.file, pos: position }, @@ -1703,7 +1826,7 @@ namespace ts.server { const file = toNormalizedPath(args.file); const projects = this.getProjects(args); const position = this.getPositionInFile(args, file); - const references = combineProjectOutputForReferences( + const references = getReferencesWorker( projects, this.getDefaultProject(args), { fileName: args.file, pos: position }, @@ -2298,7 +2421,8 @@ namespace ts.server { const seenItems = new Map(); // name to items with that name if (!args.file && !projectFileName) { - // VS Code's `Go to symbol in workspaces` sends request like this + // VS Code's `Go to symbol in workspaces` sends request like this by default. + // There's a setting to have it send a file name (reverting to older behavior). // TODO (https://github.com/microsoft/TypeScript/issues/47839) // This appears to have been intended to search all projects but, in practice, it seems to only search From 205a6e1d3012d20f53c3a9fbbc7759df12867abb Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 30 Mar 2022 09:42:49 -0700 Subject: [PATCH 02/11] Stop enforcing search and aggregation order ...in preparation for implementing isDefinition explicitly. Also restore convention of referring to `DocumentPosition`s as "locations". --- src/server/session.ts | 173 ++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 118 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index fdbba85d68eff..06c2a7b871f81 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -306,7 +306,7 @@ namespace ts.server { function getRenameLocationsWorker( projects: Projects, defaultProject: Project, - initialPosition: DocumentPosition, + initialLocation: DocumentPosition, findInStrings: boolean, findInComments: boolean, { providePrefixAndSuffixTextForRename }: UserPreferences @@ -314,7 +314,7 @@ namespace ts.server { const perProjectResults = getPerProjectReferences( projects, defaultProject, - initialPosition, + initialLocation, (project, position) => project.getLanguageService().findRenameLocations(position.fileName, position.pos, findInStrings, findInComments, providePrefixAndSuffixTextForRename), (renameLocation, cb) => cb(documentSpanLocation(renameLocation)), ); @@ -327,10 +327,7 @@ namespace ts.server { const results: RenameLocation[] = []; const seen = createDocumentSpanSet(); - for (const project of perProjectResults.projects) { - const projectResults = perProjectResults.resultsMap.get(project); - if (!projectResults) continue; - + perProjectResults.forEach((projectResults, project) => { for (const result of projectResults) { // If there's a mapped location, it'll appear in the results for another project if (!seen.has(result) && !getMappedLocation(documentSpanLocation(result), project)) { @@ -338,7 +335,7 @@ namespace ts.server { seen.add(result); } } - } + }); return results; } @@ -352,13 +349,13 @@ namespace ts.server { function getReferencesWorker( projects: Projects, defaultProject: Project, - initialPosition: DocumentPosition, + initialLocation: DocumentPosition, logger: Logger, ): readonly ReferencedSymbol[] { const perProjectResults = getPerProjectReferences( projects, defaultProject, - initialPosition, + initialLocation, (project, position) => { logger.info(`Finding references to ${position.fileName} position ${position.pos} in project ${project.getProjectName()}`); return project.getLanguageService().findReferences(position.fileName, position.pos); @@ -381,12 +378,9 @@ namespace ts.server { const results: ReferencedSymbol[] = []; - for (const project of perProjectResults.projects) { - const projectResults = perProjectResults.resultsMap.get(project); - if (!projectResults) continue; - - const clearIsDefinition = projectOutputs[0].references[0].isDefinition === undefined; + const clearIsDefinition = perProjectResults.get(defaultProject)![0].references[0].isDefinition === undefined; + perProjectResults.forEach((projectResults, project) => { for (const referencedSymbol of projectResults) { const mappedDefinitionFile = getMappedLocation(documentSpanLocation(referencedSymbol.definition), project); const definition: ReferencedSymbolDefinitionInfo = mappedDefinitionFile === undefined ? @@ -413,14 +407,14 @@ namespace ts.server { } } } - } + }); return results.filter(o => o.references.length !== 0); } - interface ProjectAndPosition { + interface ProjectAndLocation { readonly project: Project; - readonly position: DocumentPosition; + readonly location: DocumentPosition; } function forEachProjectInProjects(projects: Projects, path: string | undefined, cb: (project: Project, path: string | undefined) => void): void { @@ -436,55 +430,43 @@ namespace ts.server { } } - interface PerProjectResults { - // The projects that were searched in the order in which they were searched. - // (The order may be slightly fudged to prioritize "authoritative" projects.) - projects: readonly Project[]; - // The results for each project. - // May not have an entry for every member of `projects`. - resultsMap: ESMap; - } - /** - * @param projects Projects initially known to contain {@link initialPosition} - * @param defaultProject The default project containing {@link initialPosition} - * @param initialPosition Where the search operation was triggered + * @param projects Projects initially known to contain {@link initialLocation} + * @param defaultProject The default project containing {@link initialLocation} + * @param initialLocation Where the search operation was triggered * @param getResultsForPosition This is where you plug in `findReferences`, `renameLocation`, etc * @param forPositionInResult Given an item returned by {@link getResultsForPosition} enumerate the positions referred to by that result * @returns In the common case where there's only one project, returns an array of results from {@link getResultsForPosition}. - * If multiple projects were searched - even if they didn't return results - the result will be a {@link PerProjectResults}. + * If multiple projects were searched - even if they didn't return results - the result will be a map from project to per-project results. */ function getPerProjectReferences( projects: Projects, defaultProject: Project, - initialPosition: DocumentPosition, - getResultsForPosition: (project: Project, position: DocumentPosition) => readonly TResult[] | undefined, - forPositionInResult: (result: TResult, cb: (position: DocumentPosition) => void) => void, - ): readonly TResult[] | PerProjectResults { + initialLocation: DocumentPosition, + getResultsForPosition: (project: Project, location: DocumentPosition) => readonly TResult[] | undefined, + forPositionInResult: (result: TResult, cb: (location: DocumentPosition) => void) => void, + ): readonly TResult[] | ESMap { // If `getResultsForPosition` returns results for a project, they go in here const resultsMap = new Map(); - // The `isDefinition` property in a FAR result depends on where the search was started. - // This matters when a symbol is aliased (e.g. in an import or an export) because either - // the original declaration or the alias can be the one flagged `isDefinition`. - // As a result, searches starting from `initialPosition` are more authoritative than - // searches started from locations discovered during other searches. To ensure that - // these searches are prioritized, both during search (since we try to avoid searching a - // given project multiple times) and during aggregation (i.e. in the caller), we maintain - // separate work queues for the two types of searches. - - const initialPositionQueue: ProjectAndPosition[] = []; - forEachProjectInProjects(projects, initialPosition.fileName, (project, path) => { - const position = { fileName: path!, pos: initialPosition.pos }; - initialPositionQueue.push({ project, position }); - }); + const queue: ProjectAndLocation[] = []; + + // In order to get accurate isDefinition values for `defaultProject`, + // we need to ensure that it is searched from `initialLocation`. + // The easiest way to do this is to search it first. + queue.push({ project: defaultProject, location: initialLocation }); - const otherPositionQueue: ProjectAndPosition[] = []; + // This will queue `defaultProject` a second time, but it will be dropped + // as a dup when it is dequeued. + forEachProjectInProjects(projects, initialLocation.fileName, (project, path) => { + const location = { fileName: path!, pos: initialLocation.pos }; + queue.push({ project, location }); + }); const projectService = defaultProject.projectService; const cancellationToken = defaultProject.getCancellationToken(); - const defaultDefinition = getDefinitionLocation(defaultProject, initialPosition); + const defaultDefinition = getDefinitionLocation(defaultProject, initialLocation); // Don't call these unless !!defaultDefinition const getGeneratedDefinition = memoize(() => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition!.fileName) ? @@ -498,36 +480,20 @@ namespace ts.server { // We store the project key, rather than the project, because that's what `loadAncestorProjectTree` wants. // (For that same reason, we don't use `resultsMap` for this check.) const searchedProjects = new Set(); - // Caveat: We *can* re-search an already-searched project if the previous search was not initiated from `initialPosition`. - // Our search order should make this rare or impossible. - const initialPositionSearchedProjects = new Set(); - - // The caller needs to know the search order to aggregate properly, so we track it as we go. - // As with the sets and work queues, we need to track the two kinds of searches separately - // so that we can prioritize `initialPosition` searches over other position searches in the - // final result. - - const initialPositionProjects: Project[] = []; - const otherPositionProjects: Project[] = []; onCancellation: - while (initialPositionQueue.length || otherPositionQueue.length) { - // Drain the `initialPositionQueue` before doing anything else - while (initialPositionQueue.length) { + while (queue.length) { + while (queue.length) { if (cancellationToken.isCancellationRequested()) break onCancellation; - const { project, position } = initialPositionQueue.shift()!; + const { project, location } = queue.shift()!; - if (isLocationProjectReferenceRedirect(project, position)) continue; + if (isLocationProjectReferenceRedirect(project, location)) continue; - if (!tryAddToSet(initialPositionSearchedProjects, getProjectKey(project))) continue; - searchedProjects.add(getProjectKey(project)); // Unconditional - initialPositionProjects.push(project); + if (!tryAddToSet(searchedProjects, getProjectKey(project))) continue; - const projectResults = searchPosition(project, position); + const projectResults = searchPosition(project, location); if (projectResults) { - // There may already be an other-position search result in the map, - // in which case, clobbering it is desirable resultsMap.set(project, projectResults); } } @@ -535,76 +501,47 @@ namespace ts.server { // At this point, we know about all projects passed in as arguments and any projects in which // `getResultsForPosition` has returned results. We expand that set to include any projects // downstream from any of these and then queue new initial-position searches for any new project - // containing `initialPosition`. + // containing `initialLocation`. if (defaultDefinition) { // This seems to mean "load all projects downstream from any member of `seenProjects`". projectService.loadAncestorProjectTree(searchedProjects); projectService.forEachEnabledProject(project => { if (cancellationToken.isCancellationRequested()) return; // There's no mechanism for skipping the remaining projects - if (initialPositionSearchedProjects.has(getProjectKey(project))) return; // Can loop forever without this (enqueue here, dequeue above, repeat) - const position = mapDefinitionInProject(defaultDefinition, project, getGeneratedDefinition, getSourceDefinition); - if (position) { - initialPositionQueue.push({ project, position }); + if (searchedProjects.has(getProjectKey(project))) return; // Can loop forever without this (enqueue here, dequeue above, repeat) + const location = mapDefinitionInProject(defaultDefinition, project, getGeneratedDefinition, getSourceDefinition); + if (location) { + queue.push({ project, location }); } }); } - - // Ignore `otherPositionQueue` until `initialPositionQueue` is empty. - // If we didn't, we would still prioritize initial-position results, but we'd likely search more projects twice. - if (initialPositionQueue.length) continue; - - // Drain the `otherPositionQueue`. This can't add to `initialPositionQueue`, but it could cause more projects to - // be loaded, which might lead to more initial-position searches. - while (otherPositionQueue.length) { - if (cancellationToken.isCancellationRequested()) break onCancellation; - - const { project, position } = otherPositionQueue.shift()!; - - if (isLocationProjectReferenceRedirect(project, position)) continue; - - if (!tryAddToSet(searchedProjects, getProjectKey(project))) continue; - otherPositionProjects.push(project); - - const projectResults = searchPosition(project, position); - if (projectResults) { - Debug.assert(!resultsMap.has(project)); // Or we wouldn't have tried searching - resultsMap.set(project, projectResults); - } - } - } - - // It's not worth allocating a new array to hold the concatenation - const allProjects = initialPositionProjects; - for (const project of otherPositionProjects) { - if (!initialPositionSearchedProjects.has(getProjectKey(project))) { - allProjects.push(project); - } } // In the common case where there's only one project, return a simpler result to make // it easier for the caller to skip post-processing. - if (allProjects.length === 1) { - return resultsMap.get(allProjects[0]) ?? []; + if (searchedProjects.size === 1) { + const it = resultsMap.values().next(); + Debug.assert(!it.done); + return it.value; } - return { projects: allProjects, resultsMap }; + return resultsMap; // May enqueue to otherPositionQueue - function searchPosition(project: Project, position: DocumentPosition): readonly TResult[] | undefined { - const projectResults = getResultsForPosition(project, position); + function searchPosition(project: Project, location: DocumentPosition): readonly TResult[] | undefined { + const projectResults = getResultsForPosition(project, location); if (!projectResults) return undefined; for (const result of projectResults) { forPositionInResult(result, position => { // This may trigger a search for a tsconfig, but there are several layers of caching that make it inexpensive - const originalPosition = projectService.getOriginalLocationEnsuringConfiguredProject(project, position); - if (!originalPosition) return; + const originalLocation = projectService.getOriginalLocationEnsuringConfiguredProject(project, position); + if (!originalLocation) return; - const originalScriptInfo = projectService.getScriptInfo(originalPosition.fileName)!; + const originalScriptInfo = projectService.getScriptInfo(originalLocation.fileName)!; for (const project of originalScriptInfo.containingProjects) { if (!project.isOrphan()) { - otherPositionQueue.push({ project, position: originalPosition }); + queue.push({ project, location: originalLocation }); } } @@ -613,7 +550,7 @@ namespace ts.server { symlinkedProjectsMap.forEach((symlinkedProjects, symlinkedPath) => { for (const symlinkedProject of symlinkedProjects) { if (!symlinkedProject.isOrphan()) { - otherPositionQueue.push({ project: symlinkedProject, position: { fileName: symlinkedPath as string, pos: originalPosition.pos } }); + queue.push({ project: symlinkedProject, location: { fileName: symlinkedPath as string, pos: originalLocation.pos } }); } } }); From fe0713f9872913c46a5751d6fe7cbab9042420b3 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 6 Apr 2022 17:36:39 -0700 Subject: [PATCH 03/11] Introduce LanguageService.updateIsDefinitionOfReferencedSymbols ...to allow use of the checker when computing isDefinition across projects. --- src/harness/client.ts | 4 + src/harness/harnessLanguageService.ts | 3 + src/server/session.ts | 106 ++++++++++++++++---------- src/services/findAllReferences.ts | 2 +- src/services/services.ts | 57 ++++++++++++++ src/services/types.ts | 5 ++ src/services/utilities.ts | 42 ++++++++++ 7 files changed, 176 insertions(+), 43 deletions(-) diff --git a/src/harness/client.ts b/src/harness/client.ts index 7c8869995bb05..4537dc84b10b1 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -880,6 +880,10 @@ namespace ts.server { throw new Error("Program objects are not serializable through the server protocol."); } + updateIsDefinitionOfReferencedSymbols(_referencedSymbols: readonly ReferencedSymbol[], _knownSymbolSpans: Set): boolean { + return notImplemented(); + } + getNonBoundSourceFile(_fileName: string): SourceFile { throw new Error("SourceFile objects are not serializable through the server protocol."); } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 5468068d92224..820b92e2de7a5 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -630,6 +630,9 @@ namespace Harness.LanguageService { getAutoImportProvider(): ts.Program | undefined { throw new Error("Program can not be marshaled across the shim layer."); } + updateIsDefinitionOfReferencedSymbols(_referencedSymbols: readonly ts.ReferencedSymbol[], _knownSymbolSpans: ts.Set): boolean { + return ts.notImplemented(); + } getNonBoundSourceFile(): ts.SourceFile { throw new Error("SourceFile can not be marshaled across the shim layer."); } diff --git a/src/server/session.ts b/src/server/session.ts index 06c2a7b871f81..9e9cfa0aff042 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -330,7 +330,7 @@ namespace ts.server { perProjectResults.forEach((projectResults, project) => { for (const result of projectResults) { // If there's a mapped location, it'll appear in the results for another project - if (!seen.has(result) && !getMappedLocation(documentSpanLocation(result), project)) { + if (!seen.has(result) && !getMappedLocationForProject(documentSpanLocation(result), project)) { results.push(result); seen.add(result); } @@ -368,7 +368,7 @@ namespace ts.server { }, ); - // No re-mapping is required if there's exactly one project + // No re-mapping or isDefinition updatses are required if there's exactly one project if (isArray(perProjectResults)) { return perProjectResults; } @@ -378,18 +378,66 @@ namespace ts.server { const results: ReferencedSymbol[] = []; - const clearIsDefinition = perProjectResults.get(defaultProject)![0].references[0].isDefinition === undefined; + const defaultProjectResults = perProjectResults.get(defaultProject)!; + if (defaultProjectResults[0].references[0].isDefinition === undefined) { + // Clear all isDefinition properties + perProjectResults.forEach(projectResults => { + for (const referencedSymbol of projectResults) { + for (const ref of referencedSymbol.references) { + delete ref.isDefinition; + } + } + }); + } + else { + // Correct isDefinition properties from projects other than defaultProject + const knownSymbolSpans = createDocumentSpanSet(); + for (const referencedSymbol of defaultProjectResults) { + for (const ref of referencedSymbol.references) { + if (ref.isDefinition) { + knownSymbolSpans.add(ref); + // One is enough - updateIsDefinitionOfReferencedSymbols will fill out the set based on symbols + break; + } + } + } + + const updatedProjects = new Set(); + while (true) { + let progress = false; + perProjectResults.forEach((referencedSymbols, project) => { + if (updatedProjects.has(project)) return; + const updated = project.getLanguageService().updateIsDefinitionOfReferencedSymbols(referencedSymbols, knownSymbolSpans); + if (updated) { + updatedProjects.add(project); + progress = true; + } + }); + if (!progress) break; + } + + perProjectResults.forEach((referencedSymbols, project) => { + if (updatedProjects.has(project)) return; + for (const referencedSymbol of referencedSymbols) { + for (const ref of referencedSymbol.references) { + ref.isDefinition = false; + } + } + }); + } + + // TODO (acasey): skip this aggregation when simplifying results? perProjectResults.forEach((projectResults, project) => { for (const referencedSymbol of projectResults) { - const mappedDefinitionFile = getMappedLocation(documentSpanLocation(referencedSymbol.definition), project); + const mappedDefinitionFile = getMappedLocationForProject(documentSpanLocation(referencedSymbol.definition), project); const definition: ReferencedSymbolDefinitionInfo = mappedDefinitionFile === undefined ? referencedSymbol.definition : { ...referencedSymbol.definition, textSpan: createTextSpan(mappedDefinitionFile.pos, referencedSymbol.definition.textSpan.length), // Why would the length be the same in the original? fileName: mappedDefinitionFile.fileName, - contextSpan: getMappedContextSpan(referencedSymbol.definition, project) + contextSpan: getMappedContextSpanForProject(referencedSymbol.definition, project) }; let symbolToAddTo = find(results, o => documentSpansEqual(o.definition, definition)); @@ -399,10 +447,7 @@ namespace ts.server { } for (const ref of referencedSymbol.references) { - if (!contains(symbolToAddTo.references, ref, documentSpansEqual) && !getMappedLocation(documentSpanLocation(ref), project)) { - if (clearIsDefinition) { - delete ref.isDefinition; - } + if (!contains(symbolToAddTo.references, ref, documentSpansEqual) && !getMappedLocationForProject(documentSpanLocation(ref), project)) { symbolToAddTo.references.push(ref); } } @@ -603,39 +648,16 @@ namespace ts.server { return { fileName, pos: textSpan.start }; } - function getMappedLocation(location: DocumentPosition, project: Project): DocumentPosition | undefined { - const mapsTo = project.getSourceMapper().tryGetSourcePosition(location); - return mapsTo && project.projectService.fileExists(toNormalizedPath(mapsTo.fileName)) ? mapsTo : undefined; + function getMappedLocationForProject(location: DocumentPosition, project: Project): DocumentPosition | undefined { + return getMappedLocation(location, project.getSourceMapper(), p => project.projectService.fileExists(p as NormalizedPath)); } - function getMappedDocumentSpan(documentSpan: DocumentSpan, project: Project): DocumentSpan | undefined { - const newPosition = getMappedLocation(documentSpanLocation(documentSpan), project); - if (!newPosition) return undefined; - return { - fileName: newPosition.fileName, - textSpan: { - start: newPosition.pos, - length: documentSpan.textSpan.length - }, - originalFileName: documentSpan.fileName, - originalTextSpan: documentSpan.textSpan, - contextSpan: getMappedContextSpan(documentSpan, project), - originalContextSpan: documentSpan.contextSpan - }; + function getMappedDocumentSpanForProject(documentSpan: DocumentSpan, project: Project): DocumentSpan | undefined { + return getMappedDocumentSpan(documentSpan, project.getSourceMapper(), p => project.projectService.fileExists(p as NormalizedPath)); } - function getMappedContextSpan(documentSpan: DocumentSpan, project: Project): TextSpan | undefined { - const contextSpanStart = documentSpan.contextSpan && getMappedLocation( - { fileName: documentSpan.fileName, pos: documentSpan.contextSpan.start }, - project - ); - const contextSpanEnd = documentSpan.contextSpan && getMappedLocation( - { fileName: documentSpan.fileName, pos: documentSpan.contextSpan.start + documentSpan.contextSpan.length }, - project - ); - return contextSpanStart && contextSpanEnd ? - { start: contextSpanStart.pos, length: contextSpanEnd.pos - contextSpanStart.pos } : - undefined; + function getMappedContextSpanForProject(documentSpan: DocumentSpan, project: Project): TextSpan | undefined { + return getMappedContextSpan(documentSpan, project.getSourceMapper(), p => project.projectService.fileExists(p as NormalizedPath)); } const invalidPartialSemanticModeCommands: readonly CommandNames[] = [ @@ -1249,7 +1271,7 @@ namespace ts.server { private mapDefinitionInfoLocations(definitions: readonly DefinitionInfo[], project: Project): readonly DefinitionInfo[] { return definitions.map((info): DefinitionInfo => { - const newDocumentSpan = getMappedDocumentSpan(info, project); + const newDocumentSpan = getMappedDocumentSpanForProject(info, project); return !newDocumentSpan ? info : { ...newDocumentSpan, containerKind: info.containerKind, @@ -1544,7 +1566,7 @@ namespace ts.server { private mapImplementationLocations(implementations: readonly ImplementationLocation[], project: Project): readonly ImplementationLocation[] { return implementations.map((info): ImplementationLocation => { - const newDocumentSpan = getMappedDocumentSpan(info, project); + const newDocumentSpan = getMappedDocumentSpanForProject(info, project); return !newDocumentSpan ? info : { ...newDocumentSpan, kind: info.kind, @@ -1780,7 +1802,7 @@ namespace ts.server { const symbolStartOffset = nameSpan ? scriptInfo.positionToLineOffset(nameSpan.start).offset : 0; const symbolName = nameSpan ? scriptInfo.getSnapshot().getText(nameSpan.start, textSpanEnd(nameSpan)) : ""; const refs: readonly protocol.ReferencesResponseItem[] = flatMap(references, referencedSymbol => { - return referencedSymbol.references.map(entry => referenceEntryToReferencesResponseItem(this.projectService, entry)); + return referencedSymbol.references.map(entry => referenceEntryToReferencesResponseItem(this.projectService, entry)); // TODO (acasey): de-dup }); return { refs, symbolName, symbolStartOffset, symbolDisplayString }; } @@ -2384,7 +2406,7 @@ namespace ts.server { // Mutates `outputs` function addItemsForProject(project: Project) { const projectItems = project.getLanguageService().getNavigateToItems(searchValue, maxResultCount, /*filename*/ undefined, /*excludeDts*/ project.isNonTsProject()); - const unseenItems = filter(projectItems, item => tryAddSeenItem(item) && !getMappedLocation(documentSpanLocation(item), project)); + const unseenItems = filter(projectItems, item => tryAddSeenItem(item) && !getMappedLocationForProject(documentSpanLocation(item), project)); if (unseenItems.length) { outputs.push({ project, navigateToItems: unseenItems }); } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index ba46b5d311f46..a6253eeafa5da 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -564,7 +564,7 @@ namespace ts.FindAllReferences { } /** Whether a reference, `node`, is a definition of the `target` symbol */ - function isDeclarationOfSymbol(node: Node, target: Symbol | undefined): boolean { + export function isDeclarationOfSymbol(node: Node, target: Symbol | undefined): boolean { if (!target) return false; const source = getDeclarationFromName(node) || (node.kind === SyntaxKind.DefaultKeyword ? node.parent diff --git a/src/services/services.ts b/src/services/services.ts index 7633f079061c4..f653390e3d843 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1601,6 +1601,62 @@ namespace ts { return host.getPackageJsonAutoImportProvider?.(); } + function updateIsDefinitionOfReferencedSymbols(referencedSymbols: readonly ReferencedSymbol[], knownSymbolSpans: Set): boolean { + const checker = program.getTypeChecker(); + const symbol = getSymbolForProgram(); + + if (!symbol) return false; + + for (const referencedSymbol of referencedSymbols) { + for (const ref of referencedSymbol.references) { + const refNode = getNodeForSpan(ref); + Debug.assertIsDefined(refNode); + if (knownSymbolSpans.has(ref) || FindAllReferences.isDeclarationOfSymbol(refNode, symbol)) { + knownSymbolSpans.add(ref); + ref.isDefinition = true; + const mappedSpan = getMappedDocumentSpan(ref, sourceMapper, maybeBind(host, host.fileExists)); + if (mappedSpan) { + knownSymbolSpans.add(mappedSpan); + } + } + else { + ref.isDefinition = false; + } + } + } + + return true; + + function getSymbolForProgram(): Symbol | undefined { + for (const referencedSymbol of referencedSymbols) { + for (const ref of referencedSymbol.references) { + if (knownSymbolSpans.has(ref)) { + const refNode = getNodeForSpan(ref); + Debug.assertIsDefined(refNode); + return checker.getSymbolAtLocation(refNode); + } + const mappedSpan = getMappedDocumentSpan(ref, sourceMapper, maybeBind(host, host.fileExists)); + if (mappedSpan && knownSymbolSpans.has(mappedSpan)) { + const refNode = getNodeForSpan(mappedSpan); + if (refNode) { + return checker.getSymbolAtLocation(refNode); + } + } + } + } + + return undefined; + } + + function getNodeForSpan(docSpan: DocumentSpan): Node | undefined { + const sourceFile = program.getSourceFile(docSpan.fileName); + if (!sourceFile) return undefined; + const rawNode = getTouchingPropertyName(sourceFile, docSpan.textSpan.start); + const adjustedNode = FindAllReferences.Core.getAdjustedNode(rawNode, { use: FindAllReferences.FindReferencesUse.References }); + return adjustedNode; + } + } + function cleanupSemanticCache(): void { program = undefined!; // TODO: GH#18217 } @@ -2716,6 +2772,7 @@ namespace ts { getNonBoundSourceFile, getProgram, getAutoImportProvider, + updateIsDefinitionOfReferencedSymbols, getApplicableRefactors, getEditsForRefactor, toLineColumnOffset, diff --git a/src/services/types.ts b/src/services/types.ts index 82ed0b9412455..be927d6e8a4fe 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -552,6 +552,11 @@ namespace ts { /* @internal */ getNonBoundSourceFile(fileName: string): SourceFile; /* @internal */ getAutoImportProvider(): Program | undefined; + /// Returns true if a suitable symbol was found in the project. + /// May set isDefinition properties in `referencedSymbols` to false. + /// May add elements to `knownSymbolSpans`. + /* @internal */ updateIsDefinitionOfReferencedSymbols(referencedSymbols: readonly ReferencedSymbol[], knownSymbolSpans: Set): boolean; + toggleLineComment(fileName: string, textRange: TextRange): TextChange[]; toggleMultilineComment(fileName: string, textRange: TextRange): TextChange[]; commentSelection(fileName: string, textRange: TextRange): TextChange[]; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 60aa2c7d1945e..0f8132e3de399 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2117,6 +2117,48 @@ namespace ts { return true; } + export function getMappedLocation(location: DocumentPosition, sourceMapper: SourceMapper, fileExists: ((path: string) => boolean) | undefined): DocumentPosition | undefined { + const mapsTo = sourceMapper.tryGetSourcePosition(location); + return mapsTo && (!fileExists || fileExists(normalizePath(mapsTo.fileName)) ? mapsTo : undefined); + } + + export function getMappedDocumentSpan(documentSpan: DocumentSpan, sourceMapper: SourceMapper, fileExists?: (path: string) => boolean): DocumentSpan | undefined { + const { fileName, textSpan } = documentSpan; + const newPosition = getMappedLocation({ fileName, pos: textSpan.start }, sourceMapper, fileExists); + if (!newPosition) return undefined; + const newEndPosition = getMappedLocation({ fileName, pos: textSpan.start + textSpan.length }, sourceMapper, fileExists); + const newLength = newEndPosition + ? newEndPosition.pos - newPosition.pos + : textSpan.length; // This shouldn't happen + return { + fileName: newPosition.fileName, + textSpan: { + start: newPosition.pos, + length: newLength, + }, + originalFileName: documentSpan.fileName, + originalTextSpan: documentSpan.textSpan, + contextSpan: getMappedContextSpan(documentSpan, sourceMapper, fileExists), + originalContextSpan: documentSpan.contextSpan + }; + } + + export function getMappedContextSpan(documentSpan: DocumentSpan, sourceMapper: SourceMapper, fileExists?: (path: string) => boolean): TextSpan | undefined { + const contextSpanStart = documentSpan.contextSpan && getMappedLocation( + { fileName: documentSpan.fileName, pos: documentSpan.contextSpan.start }, + sourceMapper, + fileExists + ); + const contextSpanEnd = documentSpan.contextSpan && getMappedLocation( + { fileName: documentSpan.fileName, pos: documentSpan.contextSpan.start + documentSpan.contextSpan.length }, + sourceMapper, + fileExists + ); + return contextSpanStart && contextSpanEnd ? + { start: contextSpanStart.pos, length: contextSpanEnd.pos - contextSpanStart.pos } : + undefined; + } + // #endregion // Display-part writer helpers From 12a78b02714b091ef7555efe204100a51c779a72 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 6 Apr 2022 17:46:31 -0700 Subject: [PATCH 04/11] Update baselines --- .../unittests/tsserver/declarationFileMaps.ts | 4 +- .../ancestor-and-project-ref-management.js | 2 + ...ssfully-find-references-with-out-option.js | 2 + ...-are-disabled-and-a-decl-map-is-present.js | 2 +- ...s-are-enabled-and-a-decl-map-is-missing.js | 2 +- ...s-are-enabled-and-a-decl-map-is-present.js | 2 +- ...-are-disabled-and-a-decl-map-is-present.js | 2 +- ...s-are-enabled-and-a-decl-map-is-missing.js | 2 +- ...s-are-enabled-and-a-decl-map-is-present.js | 2 +- ...-are-disabled-and-a-decl-map-is-present.js | 2 +- ...s-are-enabled-and-a-decl-map-is-missing.js | 2 +- ...s-are-enabled-and-a-decl-map-is-present.js | 2 +- .../sibling-projects.js | 4 ++ ...ject-is-directly-referenced-by-solution.js | 2 +- ...ct-is-indirectly-referenced-by-solution.js | 22 +++++- ...ot-file-is-file-from-referenced-project.js | 6 ++ ...ces-open-file-through-project-reference.js | 13 ++-- ...ct-is-indirectly-referenced-by-solution.js | 70 ++++++++++++------- ...nction-as-object-literal-property-types.js | 6 +- ...ss-when-using-arrow-function-assignment.js | 6 +- ...s-when-using-method-of-class-expression.js | 6 +- ...ness-when-using-object-literal-property.js | 6 +- 22 files changed, 117 insertions(+), 50 deletions(-) diff --git a/src/testRunner/unittests/tsserver/declarationFileMaps.ts b/src/testRunner/unittests/tsserver/declarationFileMaps.ts index 2ceb75d6b6015..00118dbbcea95 100644 --- a/src/testRunner/unittests/tsserver/declarationFileMaps.ts +++ b/src/testRunner/unittests/tsserver/declarationFileMaps.ts @@ -400,7 +400,7 @@ namespace ts.projectSystem { const response = executeSessionRequest(session, protocol.CommandTypes.References, protocolFileLocationFromSubstring(userTs, "fnA()")); assert.deepEqual(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() {}" }), ], }, ]); diff --git a/tests/baselines/reference/tsserver/projectReferences/ancestor-and-project-ref-management.js b/tests/baselines/reference/tsserver/projectReferences/ancestor-and-project-ref-management.js index 79bc5aad59d86..05cc515ab97fe 100644 --- a/tests/baselines/reference/tsserver/projectReferences/ancestor-and-project-ref-management.js +++ b/tests/baselines/reference/tsserver/projectReferences/ancestor-and-project-ref-management.js @@ -203,6 +203,8 @@ Project '/user/username/projects/container/exec/tsconfig.json' (Configured) Part of 'files' list in tsconfig.json ----------------------------------------------- +Search path: /user/username/projects/container/lib +For info: /user/username/projects/container/lib/index.ts :: Config file name: /user/username/projects/container/lib/tsconfig.json response:{"response":{"info":{"canRename":true,"displayName":"myConst","fullDisplayName":"container.myConst","kind":"const","kindModifiers":"export","triggerSpan":{"start":{"line":3,"offset":16},"end":{"line":3,"offset":23}}},"locs":[{"file":"/user/username/projects/container/lib/index.ts","locs":[{"start":{"line":2,"offset":18},"end":{"line":2,"offset":25},"contextStart":{"line":2,"offset":5},"contextEnd":{"line":2,"offset":31}}]},{"file":"/user/username/projects/container/compositeExec/index.ts","locs":[{"start":{"line":3,"offset":16},"end":{"line":3,"offset":23}}]},{"file":"/user/username/projects/container/exec/index.ts","locs":[{"start":{"line":3,"offset":16},"end":{"line":3,"offset":23}}]}]},"responseRequired":true} FileWatcher:: Close:: WatchInfo: /user/username/projects/temp/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root FileWatcher:: Close:: WatchInfo: /user/username/projects/temp/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root diff --git a/tests/baselines/reference/tsserver/projectReferences/can-successfully-find-references-with-out-option.js b/tests/baselines/reference/tsserver/projectReferences/can-successfully-find-references-with-out-option.js index 1b0c0d2f7c153..383622c4754e2 100644 --- a/tests/baselines/reference/tsserver/projectReferences/can-successfully-find-references-with-out-option.js +++ b/tests/baselines/reference/tsserver/projectReferences/can-successfully-find-references-with-out-option.js @@ -163,4 +163,6 @@ Project '/user/username/projects/container/exec/tsconfig.json' (Configured) Part of 'files' list in tsconfig.json ----------------------------------------------- +Search path: /user/username/projects/container/lib +For info: /user/username/projects/container/lib/index.ts :: Config file name: /user/username/projects/container/lib/tsconfig.json response:{"response":{"info":{"canRename":true,"displayName":"myConst","fullDisplayName":"container.myConst","kind":"const","kindModifiers":"export","triggerSpan":{"start":{"line":3,"offset":16},"end":{"line":3,"offset":23}}},"locs":[{"file":"/user/username/projects/container/lib/index.ts","locs":[{"start":{"line":2,"offset":18},"end":{"line":2,"offset":25},"contextStart":{"line":2,"offset":5},"contextEnd":{"line":2,"offset":31}}]},{"file":"/user/username/projects/container/compositeExec/index.ts","locs":[{"start":{"line":3,"offset":16},"end":{"line":3,"offset":23}}]},{"file":"/user/username/projects/container/exec/index.ts","locs":[{"start":{"line":3,"offset":16},"end":{"line":3,"offset":23}}]}]},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js index 2425cab99f17c..71d060f23c4fa 100644 --- a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js +++ b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js @@ -123,4 +123,4 @@ For info: /user/username/projects/myproject/b/index.ts :: Config file name: /use Search path: /user/username/projects/myproject/b For info: /user/username/projects/myproject/b/index.ts :: Config file name: /user/username/projects/myproject/b/tsconfig.json Finding references to /user/username/projects/myproject/b/index.ts position 13 in project /user/username/projects/myproject/b/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js index a62b1ae34c945..fd2100eeb09b0 100644 --- a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js +++ b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js @@ -121,4 +121,4 @@ For info: /user/username/projects/myproject/b/index.ts :: Config file name: /use Search path: /user/username/projects/myproject/b For info: /user/username/projects/myproject/b/index.ts :: Config file name: /user/username/projects/myproject/b/tsconfig.json Finding references to /user/username/projects/myproject/b/index.ts position 13 in project /user/username/projects/myproject/b/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js index a62b1ae34c945..fd2100eeb09b0 100644 --- a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js +++ b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js @@ -121,4 +121,4 @@ For info: /user/username/projects/myproject/b/index.ts :: Config file name: /use Search path: /user/username/projects/myproject/b For info: /user/username/projects/myproject/b/index.ts :: Config file name: /user/username/projects/myproject/b/tsconfig.json Finding references to /user/username/projects/myproject/b/index.ts position 13 in project /user/username/projects/myproject/b/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js index a2d046ad30b9d..a83f21fa17096 100644 --- a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js +++ b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js @@ -123,4 +123,4 @@ For info: /user/username/projects/myproject/b/index.ts :: Config file name: /use Search path: /user/username/projects/myproject/b For info: /user/username/projects/myproject/b/index.ts :: Config file name: /user/username/projects/myproject/b/tsconfig.json Finding references to /user/username/projects/myproject/b/index.ts position 13 in project /user/username/projects/myproject/b/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js index d6532782ff1df..7e32faefaa421 100644 --- a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js +++ b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js @@ -121,4 +121,4 @@ For info: /user/username/projects/myproject/b/index.ts :: Config file name: /use Search path: /user/username/projects/myproject/b For info: /user/username/projects/myproject/b/index.ts :: Config file name: /user/username/projects/myproject/b/tsconfig.json Finding references to /user/username/projects/myproject/b/index.ts position 13 in project /user/username/projects/myproject/b/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js index d6532782ff1df..7e32faefaa421 100644 --- a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js +++ b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js @@ -121,4 +121,4 @@ For info: /user/username/projects/myproject/b/index.ts :: Config file name: /use Search path: /user/username/projects/myproject/b For info: /user/username/projects/myproject/b/index.ts :: Config file name: /user/username/projects/myproject/b/tsconfig.json Finding references to /user/username/projects/myproject/b/index.ts position 13 in project /user/username/projects/myproject/b/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js index 00254fbec0e12..15a697e4da0f2 100644 --- a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js +++ b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js @@ -105,4 +105,4 @@ Project '/user/username/projects/myproject/b/tsconfig.json' (Configured) Search path: /user/username/projects/myproject/b For info: /user/username/projects/myproject/b/index.ts :: Config file name: /user/username/projects/myproject/b/tsconfig.json Finding references to /user/username/projects/myproject/b/index.ts position 13 in project /user/username/projects/myproject/b/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js index b24d524cc4d0d..edc733631d0fc 100644 --- a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js +++ b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js @@ -103,4 +103,4 @@ Project '/user/username/projects/myproject/b/tsconfig.json' (Configured) Search path: /user/username/projects/myproject/b For info: /user/username/projects/myproject/b/index.ts :: Config file name: /user/username/projects/myproject/b/tsconfig.json Finding references to /user/username/projects/myproject/b/index.ts position 13 in project /user/username/projects/myproject/b/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js index b24d524cc4d0d..edc733631d0fc 100644 --- a/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js +++ b/tests/baselines/reference/tsserver/projectReferences/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js @@ -103,4 +103,4 @@ Project '/user/username/projects/myproject/b/tsconfig.json' (Configured) Search path: /user/username/projects/myproject/b For info: /user/username/projects/myproject/b/index.ts :: Config file name: /user/username/projects/myproject/b/tsconfig.json Finding references to /user/username/projects/myproject/b/index.ts position 13 in project /user/username/projects/myproject/b/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false,"isDefinition":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"import { B } from \"../b/lib\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/a/index.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":15},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":3,"offset":2},"lineText":"export class B {","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":11},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":23},"lineText":"import { B } from \".\";","isWriteAccess":true},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":11},"lineText":"const b: B = new B();","isWriteAccess":false},{"file":"/user/username/projects/myproject/b/helper.ts","start":{"line":3,"offset":18},"end":{"line":3,"offset":19},"lineText":"const b: B = new B();","isWriteAccess":false}],"symbolName":"B","symbolStartOffset":10,"symbolDisplayString":"(alias) class B\nimport B"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/finding-local-reference-doesnt-load-ancestor/sibling-projects.js b/tests/baselines/reference/tsserver/projectReferences/finding-local-reference-doesnt-load-ancestor/sibling-projects.js index 9b3f7a01a6bda..b402e7bcfc8d8 100644 --- a/tests/baselines/reference/tsserver/projectReferences/finding-local-reference-doesnt-load-ancestor/sibling-projects.js +++ b/tests/baselines/reference/tsserver/projectReferences/finding-local-reference-doesnt-load-ancestor/sibling-projects.js @@ -132,4 +132,8 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/solution/compiler/types Finding references to /user/username/projects/solution/compiler/types.ts position 103 in project /user/username/projects/solution/services/tsconfig.json Search path: /user/username/projects/solution/compiler For info: /user/username/projects/solution/compiler/types.ts :: Config file name: /user/username/projects/solution/compiler/tsconfig.json +Search path: /user/username/projects/solution/compiler +For info: /user/username/projects/solution/compiler/types.ts :: Config file name: /user/username/projects/solution/compiler/tsconfig.json +Search path: /user/username/projects/solution/compiler +For info: /user/username/projects/solution/compiler/program.ts :: Config file name: /user/username/projects/solution/compiler/tsconfig.json response:{"response":{"refs":[{"file":"/user/username/projects/solution/compiler/types.ts","start":{"line":4,"offset":25},"end":{"line":4,"offset":39},"contextStart":{"line":4,"offset":25},"contextEnd":{"line":4,"offset":52},"lineText":" getSourceFiles(): string[];","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/solution/compiler/program.ts","start":{"line":4,"offset":25},"end":{"line":4,"offset":39},"contextStart":{"line":4,"offset":25},"contextEnd":{"line":4,"offset":64},"lineText":" getSourceFiles: () => [getSourceFile()]","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/solution/services/services.ts","start":{"line":3,"offset":44},"end":{"line":3,"offset":58},"lineText":" const result = program.getSourceFiles();","isWriteAccess":false,"isDefinition":false}],"symbolName":"getSourceFiles","symbolStartOffset":25,"symbolDisplayString":"(method) ts.Program.getSourceFiles(): string[]"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/project-is-directly-referenced-by-solution.js b/tests/baselines/reference/tsserver/projectReferences/project-is-directly-referenced-by-solution.js index cba2ddff4107a..91ea0ec4f741d 100644 --- a/tests/baselines/reference/tsserver/projectReferences/project-is-directly-referenced-by-solution.js +++ b/tests/baselines/reference/tsserver/projectReferences/project-is-directly-referenced-by-solution.js @@ -689,4 +689,4 @@ For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config f Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig-src.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nimport foo"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nimport foo"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/project-is-indirectly-referenced-by-solution.js b/tests/baselines/reference/tsserver/projectReferences/project-is-indirectly-referenced-by-solution.js index f3a766b7f6371..09c46c5d7cc45 100644 --- a/tests/baselines/reference/tsserver/projectReferences/project-is-indirectly-referenced-by-solution.js +++ b/tests/baselines/reference/tsserver/projectReferences/project-is-indirectly-referenced-by-solution.js @@ -656,11 +656,23 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/target/src/he Finding references to /user/username/projects/myproject/src/helpers/functions.ts position 13 in project /user/username/projects/myproject/tsconfig-indirect1.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src/helpers +For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Finding references to /user/username/projects/myproject/src/helpers/functions.ts position 13 in project /user/username/projects/myproject/tsconfig-indirect2.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src/helpers +For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json response:{"response":{"refs":[{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nexport foo"},"responseRequired":true} @@ -982,6 +994,7 @@ Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig-src.json Creating configuration project /user/username/projects/myproject/tsconfig-indirect1.json event: {"seq":0,"type":"event","event":"projectLoadingStart","body":{"projectName":"/user/username/projects/myproject/tsconfig-indirect1.json","reason":"Creating project referenced by : /user/username/projects/myproject/tsconfig.json as it references project /user/username/projects/myproject/tsconfig-src.json"}} @@ -1054,7 +1067,12 @@ For info: /user/username/projects/myproject/src/main.ts :: Config file name: /us Finding references to /user/username/projects/myproject/src/helpers/functions.ts position 13 in project /user/username/projects/myproject/tsconfig-indirect2.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src/helpers +For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig-src.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nimport foo"},"responseRequired":true} \ No newline at end of file +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nimport foo"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/root-file-is-file-from-referenced-project.js b/tests/baselines/reference/tsserver/projectReferences/root-file-is-file-from-referenced-project.js index a823144beeea4..5abee9b0f29ac 100644 --- a/tests/baselines/reference/tsserver/projectReferences/root-file-is-file-from-referenced-project.js +++ b/tests/baselines/reference/tsserver/projectReferences/root-file-is-file-from-referenced-project.js @@ -148,5 +148,11 @@ Finding references to /user/username/projects/project/src/common/input/keyboard. Search path: /user/username/projects/project/src/common/input For info: /user/username/projects/project/src/common/input/keyboard.ts :: Config file name: /user/username/projects/project/src/common/tsconfig.json Search path: /user/username/projects/project/src/common/input +For info: /user/username/projects/project/src/common/input/keyboard.ts :: Config file name: /user/username/projects/project/src/common/tsconfig.json +Search path: /user/username/projects/project/src/common/input +For info: /user/username/projects/project/src/common/input/keyboard.test.ts :: Config file name: /user/username/projects/project/src/common/tsconfig.json +Search path: /user/username/projects/project/src/common/input +For info: /user/username/projects/project/src/common/input/keyboard.test.ts :: Config file name: /user/username/projects/project/src/common/tsconfig.json +Search path: /user/username/projects/project/src/common/input For info: /user/username/projects/project/src/common/input/keyboard.test.ts :: Config file name: /user/username/projects/project/src/common/tsconfig.json response:{"response":{"refs":[{"file":"/user/username/projects/project/src/common/input/keyboard.ts","start":{"line":2,"offset":17},"end":{"line":2,"offset":38},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":44},"lineText":"export function evaluateKeyboardEvent() { }","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/project/src/common/input/keyboard.test.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":31},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":63},"lineText":"import { evaluateKeyboardEvent } from 'common/input/keyboard';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/project/src/common/input/keyboard.test.ts","start":{"line":3,"offset":12},"end":{"line":3,"offset":33},"lineText":" return evaluateKeyboardEvent();","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/project/src/terminal.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":31},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":63},"lineText":"import { evaluateKeyboardEvent } from 'common/input/keyboard';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/project/src/terminal.ts","start":{"line":3,"offset":12},"end":{"line":3,"offset":33},"lineText":" return evaluateKeyboardEvent();","isWriteAccess":false,"isDefinition":false}],"symbolName":"evaluateKeyboardEvent","symbolStartOffset":17,"symbolDisplayString":"function evaluateKeyboardEvent(): void"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/solution-with-its-own-files-and-project-found-is-not-solution-but-references-open-file-through-project-reference.js b/tests/baselines/reference/tsserver/projectReferences/solution-with-its-own-files-and-project-found-is-not-solution-but-references-open-file-through-project-reference.js index 0db18dfe0b64c..8d10ed845d58f 100644 --- a/tests/baselines/reference/tsserver/projectReferences/solution-with-its-own-files-and-project-found-is-not-solution-but-references-open-file-through-project-reference.js +++ b/tests/baselines/reference/tsserver/projectReferences/solution-with-its-own-files-and-project-found-is-not-solution-but-references-open-file-through-project-reference.js @@ -533,6 +533,7 @@ Open files: FileName: /dummy/dummy.ts ProjectRootPath: undefined Projects: /dev/null/inferredProject1* request:{"command":"references","arguments":{"file":"/user/username/projects/myproject/src/main.ts","line":2,"offset":10},"seq":2,"type":"request"} +Finding references to /user/username/projects/myproject/src/main.ts position 50 in project /user/username/projects/myproject/tsconfig-src.json Finding references to /user/username/projects/myproject/src/main.ts position 50 in project /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json @@ -544,10 +545,8 @@ Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Finding references to /user/username/projects/myproject/src/main.ts position 50 in project /user/username/projects/myproject/tsconfig-src.json FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/target/src/helpers/functions.d.ts 500 undefined WatchType: Closed Script info FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/target/src/helpers/functions.d.ts.map 500 undefined WatchType: Closed Script info -Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig-src.json response:{"response":{"refs":[{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/own/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/own/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nexport foo"},"responseRequired":true} FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/src/main.ts 500 undefined WatchType: Closed Script info Project '/user/username/projects/myproject/tsconfig.json' (Configured) @@ -800,10 +799,16 @@ Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig-src.json Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/own/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/own/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nimport foo"},"responseRequired":true} \ No newline at end of file +Search path: /user/username/projects/myproject/src/helpers +For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig-src.json +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/own/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/own/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nimport foo"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/solution-with-its-own-files-and-project-is-indirectly-referenced-by-solution.js b/tests/baselines/reference/tsserver/projectReferences/solution-with-its-own-files-and-project-is-indirectly-referenced-by-solution.js index e361cbb220485..0de5a6853a3a9 100644 --- a/tests/baselines/reference/tsserver/projectReferences/solution-with-its-own-files-and-project-is-indirectly-referenced-by-solution.js +++ b/tests/baselines/reference/tsserver/projectReferences/solution-with-its-own-files-and-project-is-indirectly-referenced-by-solution.js @@ -667,6 +667,7 @@ Open files: FileName: /dummy/dummy.ts ProjectRootPath: undefined Projects: /dev/null/inferredProject1* request:{"command":"references","arguments":{"file":"/user/username/projects/myproject/src/main.ts","line":2,"offset":10},"seq":2,"type":"request"} +Finding references to /user/username/projects/myproject/src/main.ts position 50 in project /user/username/projects/myproject/tsconfig-src.json Finding references to /user/username/projects/myproject/src/main.ts position 50 in project /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json @@ -714,10 +715,15 @@ Search path: /user/username/projects/myproject/indirect1 For info: /user/username/projects/myproject/indirect1/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/indirect1 For info: /user/username/projects/myproject/indirect1/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Finding references to /user/username/projects/myproject/src/main.ts position 50 in project /user/username/projects/myproject/tsconfig-src.json -Finding references to /user/username/projects/myproject/src/main.ts position 50 in project /user/username/projects/myproject/tsconfig-indirect1.json +Finding references to /user/username/projects/myproject/indirect1/main.ts position 9 in project /user/username/projects/myproject/tsconfig-indirect1.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src/helpers +For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Creating configuration project /user/username/projects/myproject/tsconfig-indirect2.json @@ -751,19 +757,19 @@ event: {"seq":0,"type":"event","event":"projectLoadingFinish","body":{"projectName":"/user/username/projects/myproject/tsconfig-indirect2.json"}} event: {"seq":0,"type":"event","event":"telemetry","body":{"telemetryEventName":"projectInfo","payload":{"projectId":"d9a040bddd6b85b85abd507a988a4b809b1515b5e61257ea3f8263da59589565","fileStats":{"js":0,"jsSize":0,"jsx":0,"jsxSize":0,"ts":3,"tsSize":134,"tsx":0,"tsxSize":0,"dts":1,"dtsSize":334,"deferred":0,"deferredSize":0},"compilerOptions":{"composite":true,"outDir":"","baseUrl":""},"typeAcquisition":{"enable":false,"include":false,"exclude":false},"extends":false,"files":true,"include":false,"exclude":false,"compileOnSave":false,"configFileName":"other","projectType":"configured","languageServiceEnabled":true,"version":"FakeVersion"}}} +FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/target/src/helpers/functions.d.ts 500 undefined WatchType: Closed Script info +FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/target/src/helpers/functions.d.ts.map 500 undefined WatchType: Closed Script info Finding references to /user/username/projects/myproject/src/helpers/functions.ts position 13 in project /user/username/projects/myproject/tsconfig-indirect2.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src/helpers +For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/target/src/helpers/functions.d.ts 500 undefined WatchType: Closed Script info -FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/target/src/helpers/functions.d.ts.map 500 undefined WatchType: Closed Script info -Finding references to /user/username/projects/myproject/indirect1/main.ts position 9 in project /user/username/projects/myproject/tsconfig-indirect1.json Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Search path: /user/username/projects/myproject/src/helpers -For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig-src.json response:{"response":{"refs":[{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nexport foo"},"responseRequired":true} FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/src/main.ts 500 undefined WatchType: Closed Script info Project '/user/username/projects/myproject/tsconfig.json' (Configured) @@ -1125,9 +1131,22 @@ Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src/helpers +For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src/helpers +For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/indirect1 +For info: /user/username/projects/myproject/indirect1/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Creating configuration project /user/username/projects/myproject/tsconfig-indirect1.json event: - {"seq":0,"type":"event","event":"projectLoadingStart","body":{"projectName":"/user/username/projects/myproject/tsconfig-indirect1.json","reason":"Creating project referenced by : /user/username/projects/myproject/tsconfig.json as it references project /user/username/projects/myproject/tsconfig-src.json"}} + {"seq":0,"type":"event","event":"projectLoadingStart","body":{"projectName":"/user/username/projects/myproject/tsconfig-indirect1.json","reason":"Creating project referenced in solution /user/username/projects/myproject/tsconfig.json to find possible configured project for original file: /user/username/projects/myproject/indirect1/main.ts"}} Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded Starting updateGraphWorker: Project: /user/username/projects/myproject/tsconfig-indirect1.json DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules/@types 1 undefined Project: /user/username/projects/myproject/tsconfig-indirect1.json WatchType: Type roots @@ -1153,6 +1172,22 @@ Project '/user/username/projects/myproject/tsconfig-indirect1.json' (Configured) ----------------------------------------------- event: {"seq":0,"type":"event","event":"projectLoadingFinish","body":{"projectName":"/user/username/projects/myproject/tsconfig-indirect1.json"}} +Search path: /user/username/projects/myproject/indirect1 +For info: /user/username/projects/myproject/indirect1/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/indirect1 +For info: /user/username/projects/myproject/indirect1/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig-src.json +Finding references to /user/username/projects/myproject/indirect1/main.ts position 9 in project /user/username/projects/myproject/tsconfig-indirect1.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src +For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src/helpers +For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json +Search path: /user/username/projects/myproject/src/helpers +For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Creating configuration project /user/username/projects/myproject/tsconfig-indirect2.json event: {"seq":0,"type":"event","event":"projectLoadingStart","body":{"projectName":"/user/username/projects/myproject/tsconfig-indirect2.json","reason":"Creating project referenced by : /user/username/projects/myproject/tsconfig.json as it references project /user/username/projects/myproject/tsconfig-src.json"}} @@ -1182,7 +1217,7 @@ Project '/user/username/projects/myproject/tsconfig-indirect2.json' (Configured) ----------------------------------------------- event: {"seq":0,"type":"event","event":"projectLoadingFinish","body":{"projectName":"/user/username/projects/myproject/tsconfig-indirect2.json"}} -Finding references to /user/username/projects/myproject/src/helpers/functions.ts position 13 in project /user/username/projects/myproject/tsconfig-indirect1.json +Finding references to /user/username/projects/myproject/src/helpers/functions.ts position 13 in project /user/username/projects/myproject/tsconfig-indirect2.json Search path: /user/username/projects/myproject/src/helpers For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src/helpers @@ -1193,17 +1228,4 @@ Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json Search path: /user/username/projects/myproject/src For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Finding references to /user/username/projects/myproject/src/helpers/functions.ts position 13 in project /user/username/projects/myproject/tsconfig-indirect2.json -Search path: /user/username/projects/myproject/src/helpers -For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Search path: /user/username/projects/myproject/src -For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig-src.json -Finding references to /user/username/projects/myproject/src/main.ts position 9 in project /user/username/projects/myproject/tsconfig.json -Search path: /user/username/projects/myproject/src -For info: /user/username/projects/myproject/src/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Search path: /user/username/projects/myproject/src/helpers -For info: /user/username/projects/myproject/src/helpers/functions.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -Search path: /user/username/projects/myproject/indirect1 -For info: /user/username/projects/myproject/indirect1/main.ts :: Config file name: /user/username/projects/myproject/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nimport foo"},"responseRequired":true} \ No newline at end of file +response:{"response":{"refs":[{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":true},{"file":"/user/username/projects/myproject/indirect3/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":41},"lineText":"import { foo } from 'helpers/functions';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/main.ts","start":{"line":2,"offset":10},"end":{"line":2,"offset":13},"contextStart":{"line":2,"offset":1},"contextEnd":{"line":2,"offset":16},"lineText":"export { foo };","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/src/helpers/functions.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":22},"lineText":"export const foo = 1;","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect1/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":1,"offset":10},"end":{"line":1,"offset":13},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":28},"lineText":"import { foo } from 'main';","isWriteAccess":true,"isDefinition":false},{"file":"/user/username/projects/myproject/indirect2/main.ts","start":{"line":2,"offset":1},"end":{"line":2,"offset":4},"lineText":"foo;","isWriteAccess":false,"isDefinition":false}],"symbolName":"foo","symbolStartOffset":10,"symbolDisplayString":"(alias) const foo: 1\nimport foo"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-arrow-function-as-object-literal-property-types.js b/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-arrow-function-as-object-literal-property-types.js index 6e436bbfa9e79..a3568e50d46e8 100644 --- a/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-arrow-function-as-object-literal-property-types.js +++ b/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-arrow-function-as-object-literal-property-types.js @@ -107,6 +107,7 @@ Project '/user/username/projects/solution/shared/tsconfig.json' (Configured) ----------------------------------------------- Search path: /user/username/projects/solution/shared/src For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json +Finding references to /user/username/projects/solution/shared/src/index.ts position 21 in project /user/username/projects/solution/shared/tsconfig.json Loading configured project /user/username/projects/solution/tsconfig.json Config: /user/username/projects/solution/tsconfig.json : { "rootNames": [], @@ -179,5 +180,6 @@ Project '/user/username/projects/solution/app/tsconfig.json' (Configured) Finding references to /user/username/projects/solution/shared/src/index.ts position 21 in project /user/username/projects/solution/app/tsconfig.json Search path: /user/username/projects/solution/shared/src For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json -Finding references to /user/username/projects/solution/shared/src/index.ts position 21 in project /user/username/projects/solution/shared/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/solution/shared/src/index.ts","start":{"line":1,"offset":22},"end":{"line":1,"offset":25},"contextStart":{"line":1,"offset":22},"contextEnd":{"line":1,"offset":36},"lineText":"export const foo = { bar: () => { } };","isWriteAccess":true},{"file":"/user/username/projects/solution/api/src/server.ts","start":{"line":2,"offset":12},"end":{"line":2,"offset":15},"lineText":"shared.foo.bar();","isWriteAccess":false},{"file":"/user/username/projects/solution/app/src/app.ts","start":{"line":2,"offset":12},"end":{"line":2,"offset":15},"lineText":"shared.foo.bar();","isWriteAccess":false,"isDefinition":false}],"symbolName":"bar","symbolStartOffset":12,"symbolDisplayString":"(property) bar: () => void"},"responseRequired":true} \ No newline at end of file +Search path: /user/username/projects/solution/shared/src +For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json +response:{"response":{"refs":[{"file":"/user/username/projects/solution/shared/src/index.ts","start":{"line":1,"offset":22},"end":{"line":1,"offset":25},"contextStart":{"line":1,"offset":22},"contextEnd":{"line":1,"offset":36},"lineText":"export const foo = { bar: () => { } };","isWriteAccess":true},{"file":"/user/username/projects/solution/api/src/server.ts","start":{"line":2,"offset":12},"end":{"line":2,"offset":15},"lineText":"shared.foo.bar();","isWriteAccess":false},{"file":"/user/username/projects/solution/app/src/app.ts","start":{"line":2,"offset":12},"end":{"line":2,"offset":15},"lineText":"shared.foo.bar();","isWriteAccess":false}],"symbolName":"bar","symbolStartOffset":12,"symbolDisplayString":"(property) bar: () => void"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-arrow-function-assignment.js b/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-arrow-function-assignment.js index 7745ab9fc6c81..45ae480650574 100644 --- a/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-arrow-function-assignment.js +++ b/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-arrow-function-assignment.js @@ -107,6 +107,7 @@ Project '/user/username/projects/solution/shared/tsconfig.json' (Configured) ----------------------------------------------- Search path: /user/username/projects/solution/shared/src For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json +Finding references to /user/username/projects/solution/shared/src/index.ts position 13 in project /user/username/projects/solution/shared/tsconfig.json Loading configured project /user/username/projects/solution/tsconfig.json Config: /user/username/projects/solution/tsconfig.json : { "rootNames": [], @@ -179,5 +180,6 @@ Project '/user/username/projects/solution/app/tsconfig.json' (Configured) Finding references to /user/username/projects/solution/shared/src/index.ts position 13 in project /user/username/projects/solution/app/tsconfig.json Search path: /user/username/projects/solution/shared/src For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json -Finding references to /user/username/projects/solution/shared/src/index.ts position 13 in project /user/username/projects/solution/shared/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/solution/shared/src/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"export const dog = () => { };","isWriteAccess":true},{"file":"/user/username/projects/solution/api/src/server.ts","start":{"line":2,"offset":8},"end":{"line":2,"offset":11},"lineText":"shared.dog();","isWriteAccess":false},{"file":"/user/username/projects/solution/app/src/app.ts","start":{"line":2,"offset":8},"end":{"line":2,"offset":11},"lineText":"shared.dog();","isWriteAccess":false,"isDefinition":false}],"symbolName":"dog","symbolStartOffset":8,"symbolDisplayString":"const dog: () => void"},"responseRequired":true} \ No newline at end of file +Search path: /user/username/projects/solution/shared/src +For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json +response:{"response":{"refs":[{"file":"/user/username/projects/solution/shared/src/index.ts","start":{"line":1,"offset":14},"end":{"line":1,"offset":17},"contextStart":{"line":1,"offset":1},"contextEnd":{"line":1,"offset":30},"lineText":"export const dog = () => { };","isWriteAccess":true},{"file":"/user/username/projects/solution/api/src/server.ts","start":{"line":2,"offset":8},"end":{"line":2,"offset":11},"lineText":"shared.dog();","isWriteAccess":false},{"file":"/user/username/projects/solution/app/src/app.ts","start":{"line":2,"offset":8},"end":{"line":2,"offset":11},"lineText":"shared.dog();","isWriteAccess":false}],"symbolName":"dog","symbolStartOffset":8,"symbolDisplayString":"const dog: () => void"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-method-of-class-expression.js b/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-method-of-class-expression.js index e3725c5adf728..1febd80d37564 100644 --- a/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-method-of-class-expression.js +++ b/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-method-of-class-expression.js @@ -107,6 +107,7 @@ Project '/user/username/projects/solution/shared/tsconfig.json' (Configured) ----------------------------------------------- Search path: /user/username/projects/solution/shared/src For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json +Finding references to /user/username/projects/solution/shared/src/index.ts position 27 in project /user/username/projects/solution/shared/tsconfig.json Loading configured project /user/username/projects/solution/tsconfig.json Config: /user/username/projects/solution/tsconfig.json : { "rootNames": [], @@ -179,5 +180,6 @@ Project '/user/username/projects/solution/app/tsconfig.json' (Configured) Finding references to /user/username/projects/solution/shared/src/index.ts position 27 in project /user/username/projects/solution/app/tsconfig.json Search path: /user/username/projects/solution/shared/src For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json -Finding references to /user/username/projects/solution/shared/src/index.ts position 27 in project /user/username/projects/solution/shared/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/solution/shared/src/index.ts","start":{"line":1,"offset":28},"end":{"line":1,"offset":31},"contextStart":{"line":1,"offset":28},"contextEnd":{"line":1,"offset":36},"lineText":"export const foo = class { fly() {} };","isWriteAccess":true},{"file":"/user/username/projects/solution/api/src/server.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":13},"lineText":"instance.fly();","isWriteAccess":false},{"file":"/user/username/projects/solution/app/src/app.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":13},"lineText":"instance.fly();","isWriteAccess":false,"isDefinition":false}],"symbolName":"fly","symbolStartOffset":10,"symbolDisplayString":"(method) foo.fly(): void"},"responseRequired":true} \ No newline at end of file +Search path: /user/username/projects/solution/shared/src +For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json +response:{"response":{"refs":[{"file":"/user/username/projects/solution/shared/src/index.ts","start":{"line":1,"offset":28},"end":{"line":1,"offset":31},"contextStart":{"line":1,"offset":28},"contextEnd":{"line":1,"offset":36},"lineText":"export const foo = class { fly() {} };","isWriteAccess":true},{"file":"/user/username/projects/solution/api/src/server.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":13},"lineText":"instance.fly();","isWriteAccess":false},{"file":"/user/username/projects/solution/app/src/app.ts","start":{"line":3,"offset":10},"end":{"line":3,"offset":13},"lineText":"instance.fly();","isWriteAccess":false}],"symbolName":"fly","symbolStartOffset":10,"symbolDisplayString":"(method) foo.fly(): void"},"responseRequired":true} \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-object-literal-property.js b/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-object-literal-property.js index ece9490849429..4a715b6965ab3 100644 --- a/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-object-literal-property.js +++ b/tests/baselines/reference/tsserver/projectReferences/special-handling-of-localness-when-using-object-literal-property.js @@ -107,6 +107,7 @@ Project '/user/username/projects/solution/shared/tsconfig.json' (Configured) ----------------------------------------------- Search path: /user/username/projects/solution/shared/src For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json +Finding references to /user/username/projects/solution/shared/src/index.ts position 22 in project /user/username/projects/solution/shared/tsconfig.json Loading configured project /user/username/projects/solution/tsconfig.json Config: /user/username/projects/solution/tsconfig.json : { "rootNames": [], @@ -179,5 +180,6 @@ Project '/user/username/projects/solution/app/tsconfig.json' (Configured) Finding references to /user/username/projects/solution/shared/src/index.ts position 22 in project /user/username/projects/solution/app/tsconfig.json Search path: /user/username/projects/solution/shared/src For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json -Finding references to /user/username/projects/solution/shared/src/index.ts position 22 in project /user/username/projects/solution/shared/tsconfig.json -response:{"response":{"refs":[{"file":"/user/username/projects/solution/shared/src/index.ts","start":{"line":1,"offset":23},"end":{"line":1,"offset":26},"contextStart":{"line":1,"offset":23},"contextEnd":{"line":1,"offset":33},"lineText":"export const foo = { baz: \"BAZ\" };","isWriteAccess":true},{"file":"/user/username/projects/solution/api/src/server.ts","start":{"line":2,"offset":12},"end":{"line":2,"offset":15},"lineText":"shared.foo.baz;","isWriteAccess":false},{"file":"/user/username/projects/solution/app/src/app.ts","start":{"line":2,"offset":12},"end":{"line":2,"offset":15},"lineText":"shared.foo.baz;","isWriteAccess":false,"isDefinition":false}],"symbolName":"baz","symbolStartOffset":12,"symbolDisplayString":"(property) baz: string"},"responseRequired":true} \ No newline at end of file +Search path: /user/username/projects/solution/shared/src +For info: /user/username/projects/solution/shared/src/index.ts :: Config file name: /user/username/projects/solution/shared/tsconfig.json +response:{"response":{"refs":[{"file":"/user/username/projects/solution/shared/src/index.ts","start":{"line":1,"offset":23},"end":{"line":1,"offset":26},"contextStart":{"line":1,"offset":23},"contextEnd":{"line":1,"offset":33},"lineText":"export const foo = { baz: \"BAZ\" };","isWriteAccess":true},{"file":"/user/username/projects/solution/api/src/server.ts","start":{"line":2,"offset":12},"end":{"line":2,"offset":15},"lineText":"shared.foo.baz;","isWriteAccess":false},{"file":"/user/username/projects/solution/app/src/app.ts","start":{"line":2,"offset":12},"end":{"line":2,"offset":15},"lineText":"shared.foo.baz;","isWriteAccess":false}],"symbolName":"baz","symbolStartOffset":12,"symbolDisplayString":"(property) baz: string"},"responseRequired":true} \ No newline at end of file From b5fab0dc916b1b8c035875758899a6b15f99e661 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 7 Apr 2022 15:48:36 -0700 Subject: [PATCH 05/11] Tidy diff --- src/server/session.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index 9e9cfa0aff042..ef1fc647554e5 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -373,10 +373,9 @@ namespace ts.server { return perProjectResults; } - // We need to de-duplicate and aggregate the results by choosing an authoritative version - // of each definition and merging references from all the projects where they appear. - - const results: ReferencedSymbol[] = []; + // `isDefinition` is only (definitely) correct in `defaultProject` because we might + // have started the other project searches from related symbols. Propagate the + // correct results to all other projects. const defaultProjectResults = perProjectResults.get(defaultProject)!; if (defaultProjectResults[0].references[0].isDefinition === undefined) { @@ -426,7 +425,10 @@ namespace ts.server { }); } - // TODO (acasey): skip this aggregation when simplifying results? + // We need to de-duplicate and aggregate the results by choosing an authoritative version + // of each definition and merging references from all the projects where they appear. + + const results: ReferencedSymbol[] = []; perProjectResults.forEach((projectResults, project) => { for (const referencedSymbol of projectResults) { From 5f088f67c6208808f17534e302fe7c2a3fdbed98 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 7 Apr 2022 15:49:59 -0700 Subject: [PATCH 06/11] De-dup simplified results --- src/server/session.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index ef1fc647554e5..6bff9131db46e 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1803,8 +1803,14 @@ namespace ts.server { const nameSpan = nameInfo && nameInfo.textSpan; const symbolStartOffset = nameSpan ? scriptInfo.positionToLineOffset(nameSpan.start).offset : 0; const symbolName = nameSpan ? scriptInfo.getSnapshot().getText(nameSpan.start, textSpanEnd(nameSpan)) : ""; - const refs: readonly protocol.ReferencesResponseItem[] = flatMap(references, referencedSymbol => { - return referencedSymbol.references.map(entry => referenceEntryToReferencesResponseItem(this.projectService, entry)); // TODO (acasey): de-dup + const refs: protocol.ReferencesResponseItem[] = []; + const seen = createDocumentSpanSet(); + references.forEach(referencedSymbol => { + referencedSymbol.references.forEach(entry => { + if (tryAddToSet(seen, entry)) { + refs.push(referenceEntryToReferencesResponseItem(this.projectService, entry)); + } + }); }); return { refs, symbolName, symbolStartOffset, symbolDisplayString }; } From d9ff2cc08ecaa3ad700bc8933cff7e21eb5f624a Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 7 Apr 2022 16:38:53 -0700 Subject: [PATCH 07/11] Baseline cross-project isDefinition results --- ...initionAcrossGlobalProjects.baseline.jsonc | 1276 +++++++++++ ...initionAcrossModuleProjects.baseline.jsonc | 1915 +++++++++++++++++ .../isDefinitionAcrossGlobalProjects.ts | 92 + .../isDefinitionAcrossModuleProjects.ts | 134 ++ 4 files changed, 3417 insertions(+) create mode 100644 tests/baselines/reference/isDefinitionAcrossGlobalProjects.baseline.jsonc create mode 100644 tests/baselines/reference/isDefinitionAcrossModuleProjects.baseline.jsonc create mode 100644 tests/cases/fourslash/server/isDefinitionAcrossGlobalProjects.ts create mode 100644 tests/cases/fourslash/server/isDefinitionAcrossModuleProjects.ts diff --git a/tests/baselines/reference/isDefinitionAcrossGlobalProjects.baseline.jsonc b/tests/baselines/reference/isDefinitionAcrossGlobalProjects.baseline.jsonc new file mode 100644 index 0000000000000..7d8a26458c931 --- /dev/null +++ b/tests/baselines/reference/isDefinitionAcrossGlobalProjects.baseline.jsonc @@ -0,0 +1,1276 @@ +// === /a/index.ts === +// namespace NS { +// export function /*FIND ALL REFS*/[|FA|]() { +// FB(); +// } +// } +// +// interface I { +// FA(); +// } +// +// const ia: I = { +// FA() { }, +// FB() { }, +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a/index.ts", + "kind": "function", + "name": "function NS.FA(): void", + "textSpan": { + "start": 35, + "length": 2 + }, + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "NS", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FA", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 19, + "length": 42 + } + }, + "references": [ + { + "textSpan": { + "start": 35, + "length": 2 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 19, + "length": 42 + }, + "isWriteAccess": true, + "isDefinition": true + } + ] + } +] + +// === /b/index.ts === +// namespace NS { +// export function FB() {} +// } +// +// interface [|I|] { +// FB(); +// } +// +// const ib: [|I|] = { FB() {} }; + +// === /c/index.ts === +// namespace NS { +// export function FC() {} +// } +// +// interface [|I|][|I|] { +// FC(); +// } +// +// const ic: [|I|][|I|] = { FC() {} }; + +// === /a/index.ts === +// namespace NS { +// export function FA() { +// FB(); +// } +// } +// +// interface /*FIND ALL REFS*/[|I|] { +// FA(); +// } +// +// const ia: [|I|] = { +// FA() { }, +// FB() { }, +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/b/index.ts", + "kind": "interface", + "name": "interface I", + "textSpan": { + "start": 56, + "length": 1 + }, + "displayParts": [ + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + } + ], + "contextSpan": { + "start": 46, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 56, + "length": 1 + }, + "fileName": "/b/index.ts", + "contextSpan": { + "start": 46, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 83, + "length": 1 + }, + "fileName": "/b/index.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 56, + "length": 1 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 46, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 83, + "length": 1 + }, + "fileName": "/c/index.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 75, + "length": 1 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 65, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 102, + "length": 1 + }, + "fileName": "/a/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + }, + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/c/index.ts", + "kind": "interface", + "name": "interface I", + "textSpan": { + "start": 56, + "length": 1 + }, + "displayParts": [ + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + } + ], + "contextSpan": { + "start": 46, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 56, + "length": 1 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 46, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 83, + "length": 1 + }, + "fileName": "/c/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] + +// === /a/index.ts === +// namespace NS { +// export function FA() { +// FB(); +// } +// } +// +// interface I { +// /*FIND ALL REFS*/[|FA|](); +// } +// +// const ia: I = { +// [|FA|]() { }, +// FB() { }, +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a/index.ts", + "kind": "method", + "name": "(method) I.FA(): any", + "textSpan": { + "start": 83, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FA", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 83, + "length": 5 + } + }, + "references": [ + { + "textSpan": { + "start": 83, + "length": 2 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 83, + "length": 5 + }, + "isWriteAccess": false, + "isDefinition": true + }, + { + "textSpan": { + "start": 112, + "length": 2 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 112, + "length": 8 + }, + "isWriteAccess": true, + "isDefinition": false + } + ] + } +] + +// === /b/index.ts === +// namespace NS { +// export function /*FIND ALL REFS*/[|FB|]() {} +// } +// +// interface I { +// FB(); +// } +// +// const ib: I = { FB() {} }; + +// === /a/index.ts === +// namespace NS { +// export function FA() { +// [|FB|](); +// } +// } +// +// interface I { +// FA(); +// } +// +// const ia: I = { +// FA() { }, +// FB() { }, +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/b/index.ts", + "kind": "function", + "name": "function NS.FB(): void", + "textSpan": { + "start": 35, + "length": 2 + }, + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "NS", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FB", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 19, + "length": 23 + } + }, + "references": [ + { + "textSpan": { + "start": 35, + "length": 2 + }, + "fileName": "/b/index.ts", + "contextSpan": { + "start": 19, + "length": 23 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 50, + "length": 2 + }, + "fileName": "/a/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] + +// === /b/index.ts === +// namespace NS { +// export function FB() {} +// } +// +// interface /*FIND ALL REFS*/[|I|] { +// FB(); +// } +// +// const ib: [|I|] = { FB() {} }; + +// === /c/index.ts === +// namespace NS { +// export function FC() {} +// } +// +// interface [|I|][|I|] { +// FC(); +// } +// +// const ic: [|I|][|I|] = { FC() {} }; + +// === /a/index.ts === +// namespace NS { +// export function FA() { +// FB(); +// } +// } +// +// interface [|I|] { +// FA(); +// } +// +// const ia: [|I|] = { +// FA() { }, +// FB() { }, +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/b/index.ts", + "kind": "interface", + "name": "interface I", + "textSpan": { + "start": 56, + "length": 1 + }, + "displayParts": [ + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + } + ], + "contextSpan": { + "start": 46, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 56, + "length": 1 + }, + "fileName": "/b/index.ts", + "contextSpan": { + "start": 46, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 83, + "length": 1 + }, + "fileName": "/b/index.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 56, + "length": 1 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 46, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 83, + "length": 1 + }, + "fileName": "/c/index.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 75, + "length": 1 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 65, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 102, + "length": 1 + }, + "fileName": "/a/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + }, + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/c/index.ts", + "kind": "interface", + "name": "interface I", + "textSpan": { + "start": 56, + "length": 1 + }, + "displayParts": [ + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + } + ], + "contextSpan": { + "start": 46, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 56, + "length": 1 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 46, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 83, + "length": 1 + }, + "fileName": "/c/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] + +// === /b/index.ts === +// namespace NS { +// export function FB() {} +// } +// +// interface I { +// /*FIND ALL REFS*/[|FB|](); +// } +// +// const ib: I = { [|FB|]() {} }; + +// === /a/index.ts === +// namespace NS { +// export function FA() { +// FB(); +// } +// } +// +// interface I { +// FA(); +// } +// +// const ia: I = { +// FA() { }, +// [|FB|]() { }, +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/b/index.ts", + "kind": "method", + "name": "(method) I.FB(): any", + "textSpan": { + "start": 64, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FB", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 64, + "length": 5 + } + }, + "references": [ + { + "textSpan": { + "start": 64, + "length": 2 + }, + "fileName": "/b/index.ts", + "contextSpan": { + "start": 64, + "length": 5 + }, + "isWriteAccess": false, + "isDefinition": true + }, + { + "textSpan": { + "start": 89, + "length": 2 + }, + "fileName": "/b/index.ts", + "contextSpan": { + "start": 89, + "length": 7 + }, + "isWriteAccess": true, + "isDefinition": false + }, + { + "textSpan": { + "start": 126, + "length": 2 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 126, + "length": 8 + }, + "isWriteAccess": true, + "isDefinition": false + } + ] + } +] + +// === /c/index.ts === +// namespace NS { +// export function /*FIND ALL REFS*/[|FC|]() {} +// } +// +// interface I { +// FC(); +// } +// +// const ic: I = { FC() {} }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/c/index.ts", + "kind": "function", + "name": "function NS.FC(): void", + "textSpan": { + "start": 35, + "length": 2 + }, + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "NS", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FC", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 19, + "length": 23 + } + }, + "references": [ + { + "textSpan": { + "start": 35, + "length": 2 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 19, + "length": 23 + }, + "isWriteAccess": true, + "isDefinition": true + } + ] + } +] + +// === /c/index.ts === +// namespace NS { +// export function FC() {} +// } +// +// interface /*FIND ALL REFS*/[|I|]/*FIND ALL REFS*/[|I|] { +// FC(); +// } +// +// const ic: [|I|][|I|] = { FC() {} }; + +// === /b/index.ts === +// namespace NS { +// export function FB() {} +// } +// +// interface [|I|] { +// FB(); +// } +// +// const ib: [|I|] = { FB() {} }; + +// === /a/index.ts === +// namespace NS { +// export function FA() { +// FB(); +// } +// } +// +// interface [|I|] { +// FA(); +// } +// +// const ia: [|I|] = { +// FA() { }, +// FB() { }, +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/c/index.ts", + "kind": "interface", + "name": "interface I", + "textSpan": { + "start": 56, + "length": 1 + }, + "displayParts": [ + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + } + ], + "contextSpan": { + "start": 46, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 56, + "length": 1 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 46, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 83, + "length": 1 + }, + "fileName": "/c/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + }, + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/b/index.ts", + "kind": "interface", + "name": "interface I", + "textSpan": { + "start": 56, + "length": 1 + }, + "displayParts": [ + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + } + ], + "contextSpan": { + "start": 46, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 56, + "length": 1 + }, + "fileName": "/b/index.ts", + "contextSpan": { + "start": 46, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 83, + "length": 1 + }, + "fileName": "/b/index.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 56, + "length": 1 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 46, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 83, + "length": 1 + }, + "fileName": "/c/index.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 75, + "length": 1 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 65, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 102, + "length": 1 + }, + "fileName": "/a/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] + +// === /c/index.ts === +// namespace NS { +// export function FC() {} +// } +// +// interface I { +// /*FIND ALL REFS*/[|FC|](); +// } +// +// const ic: I = { [|FC|]() {} }; + +// === /a/index.ts === +// namespace NS { +// export function FA() { +// FB(); +// } +// } +// +// interface I { +// FA(); +// } +// +// const ia: I = { +// FA() { }, +// FB() { }, +// [|FC|]() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/c/index.ts", + "kind": "method", + "name": "(method) I.FC(): any", + "textSpan": { + "start": 64, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FC", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 64, + "length": 5 + } + }, + "references": [ + { + "textSpan": { + "start": 64, + "length": 2 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 64, + "length": 5 + }, + "isWriteAccess": false, + "isDefinition": true + }, + { + "textSpan": { + "start": 89, + "length": 2 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 89, + "length": 7 + }, + "isWriteAccess": true, + "isDefinition": false + }, + { + "textSpan": { + "start": 140, + "length": 2 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 140, + "length": 8 + }, + "isWriteAccess": true, + "isDefinition": false + } + ] + } +] \ No newline at end of file diff --git a/tests/baselines/reference/isDefinitionAcrossModuleProjects.baseline.jsonc b/tests/baselines/reference/isDefinitionAcrossModuleProjects.baseline.jsonc new file mode 100644 index 0000000000000..4c5b75a2d1e68 --- /dev/null +++ b/tests/baselines/reference/isDefinitionAcrossModuleProjects.baseline.jsonc @@ -0,0 +1,1915 @@ +// === /a/index.ts === +// import { NS } from "../b"; +// import { I } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function /*FIND ALL REFS*/[|FA|](); +// } +// } +// +// declare module "../c" { +// export interface I { +// FA(); +// } +// } +// +// const ia: I = { +// FA: NS.[|FA|], +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a/index.ts", + "kind": "function", + "name": "function NS.FA(): any", + "textSpan": { + "start": 128, + "length": 2 + }, + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "NS", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FA", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 112, + "length": 21 + } + }, + "references": [ + { + "textSpan": { + "start": 128, + "length": 2 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 112, + "length": 21 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 242, + "length": 2 + }, + "fileName": "/a/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] + +// === /a/index.ts === +// import { NS } from "../b"; +// import { [|I|] } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function FA(); +// } +// } +// +// declare module "../c" { +// export interface /*FIND ALL REFS*/[|I|] { +// FA(); +// } +// } +// +// const ia: [|I|] = { +// FA: NS.FA, +// FC() { }, +// }; + +// === /a2/index.ts === +// import { NS } from "../b"; +// import { [|I|] } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function FA(); +// } +// } +// +// declare module "../c" { +// export interface [|I|] { +// FA(); +// } +// } +// +// const ia: [|I|] = { +// FA: NS.FA, +// FC() { }, +// }; + +// === /c/index.ts === +// export namespace NS { +// export function FC() {} +// } +// +// export interface [|I|] { +// FC(); +// } +// +// const ic: [|I|] = { FC() {} }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/c/index.ts", + "kind": "interface", + "name": "interface I", + "textSpan": { + "start": 70, + "length": 1 + }, + "displayParts": [ + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + } + ], + "contextSpan": { + "start": 53, + "length": 32 + } + }, + "references": [ + { + "textSpan": { + "start": 70, + "length": 1 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 53, + "length": 32 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 188, + "length": 1 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 171, + "length": 40 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 97, + "length": 1 + }, + "fileName": "/c/index.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 188, + "length": 1 + }, + "fileName": "/a2/index.ts", + "contextSpan": { + "start": 171, + "length": 40 + }, + "isWriteAccess": true, + "isDefinition": true + } + ] + }, + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a/index.ts", + "kind": "alias", + "name": "(alias) interface I\nimport I", + "textSpan": { + "start": 36, + "length": 1 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + } + ], + "contextSpan": { + "start": 27, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 36, + "length": 1 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 27, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": false + }, + { + "textSpan": { + "start": 225, + "length": 1 + }, + "fileName": "/a/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + }, + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a2/index.ts", + "kind": "alias", + "name": "(alias) interface I\nimport I", + "textSpan": { + "start": 36, + "length": 1 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + } + ], + "contextSpan": { + "start": 27, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 36, + "length": 1 + }, + "fileName": "/a2/index.ts", + "contextSpan": { + "start": 27, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": false + }, + { + "textSpan": { + "start": 225, + "length": 1 + }, + "fileName": "/a2/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] + +// === /a/index.ts === +// import { NS } from "../b"; +// import { I } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function FA(); +// } +// } +// +// declare module "../c" { +// export interface I { +// /*FIND ALL REFS*/[|FA|](); +// } +// } +// +// const ia: I = { +// [|FA|]: NS.FA, +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a/index.ts", + "kind": "method", + "name": "(method) I.FA(): any", + "textSpan": { + "start": 200, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FA", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 200, + "length": 5 + } + }, + "references": [ + { + "textSpan": { + "start": 200, + "length": 2 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 200, + "length": 5 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 235, + "length": 2 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 235, + "length": 9 + }, + "isWriteAccess": true, + "isDefinition": false + } + ] + } +] + +// === /a2/index.ts === +// import { NS } from "../b"; +// import { I } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function /*FIND ALL REFS*/[|FA|](); +// } +// } +// +// declare module "../c" { +// export interface I { +// FA(); +// } +// } +// +// const ia: I = { +// FA: NS.[|FA|], +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a2/index.ts", + "kind": "function", + "name": "function NS.FA(): any", + "textSpan": { + "start": 128, + "length": 2 + }, + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "NS", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FA", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 112, + "length": 21 + } + }, + "references": [ + { + "textSpan": { + "start": 128, + "length": 2 + }, + "fileName": "/a2/index.ts", + "contextSpan": { + "start": 112, + "length": 21 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 242, + "length": 2 + }, + "fileName": "/a2/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] + +// === /a2/index.ts === +// import { NS } from "../b"; +// import { [|I|] } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function FA(); +// } +// } +// +// declare module "../c" { +// export interface /*FIND ALL REFS*/[|I|] { +// FA(); +// } +// } +// +// const ia: [|I|] = { +// FA: NS.FA, +// FC() { }, +// }; + +// === /a/index.ts === +// import { NS } from "../b"; +// import { [|I|] } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function FA(); +// } +// } +// +// declare module "../c" { +// export interface [|I|] { +// FA(); +// } +// } +// +// const ia: [|I|] = { +// FA: NS.FA, +// FC() { }, +// }; + +// === /c/index.ts === +// export namespace NS { +// export function FC() {} +// } +// +// export interface [|I|] { +// FC(); +// } +// +// const ic: [|I|] = { FC() {} }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/c/index.ts", + "kind": "interface", + "name": "interface I", + "textSpan": { + "start": 70, + "length": 1 + }, + "displayParts": [ + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + } + ], + "contextSpan": { + "start": 53, + "length": 32 + } + }, + "references": [ + { + "textSpan": { + "start": 70, + "length": 1 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 53, + "length": 32 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 188, + "length": 1 + }, + "fileName": "/a2/index.ts", + "contextSpan": { + "start": 171, + "length": 40 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 97, + "length": 1 + }, + "fileName": "/c/index.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 188, + "length": 1 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 171, + "length": 40 + }, + "isWriteAccess": true, + "isDefinition": true + } + ] + }, + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a2/index.ts", + "kind": "alias", + "name": "(alias) interface I\nimport I", + "textSpan": { + "start": 36, + "length": 1 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + } + ], + "contextSpan": { + "start": 27, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 36, + "length": 1 + }, + "fileName": "/a2/index.ts", + "contextSpan": { + "start": 27, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": false + }, + { + "textSpan": { + "start": 225, + "length": 1 + }, + "fileName": "/a2/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + }, + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a/index.ts", + "kind": "alias", + "name": "(alias) interface I\nimport I", + "textSpan": { + "start": 36, + "length": 1 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + } + ], + "contextSpan": { + "start": 27, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 36, + "length": 1 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 27, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": false + }, + { + "textSpan": { + "start": 225, + "length": 1 + }, + "fileName": "/a/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] + +// === /a2/index.ts === +// import { NS } from "../b"; +// import { I } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function FA(); +// } +// } +// +// declare module "../c" { +// export interface I { +// /*FIND ALL REFS*/[|FA|](); +// } +// } +// +// const ia: I = { +// [|FA|]: NS.FA, +// FC() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a2/index.ts", + "kind": "method", + "name": "(method) I.FA(): any", + "textSpan": { + "start": 200, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FA", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 200, + "length": 5 + } + }, + "references": [ + { + "textSpan": { + "start": 200, + "length": 2 + }, + "fileName": "/a2/index.ts", + "contextSpan": { + "start": 200, + "length": 5 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 235, + "length": 2 + }, + "fileName": "/a2/index.ts", + "contextSpan": { + "start": 235, + "length": 9 + }, + "isWriteAccess": true, + "isDefinition": false + } + ] + } +] + +// === /b/index.ts === +// export namespace NS { +// export function /*FIND ALL REFS*/[|FB|]() {} +// } +// +// export interface I { +// FB(); +// } +// +// const ib: I = { FB() {} }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/b/index.ts", + "kind": "function", + "name": "function NS.FB(): void", + "textSpan": { + "start": 42, + "length": 2 + }, + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "NS", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FB", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 26, + "length": 23 + } + }, + "references": [ + { + "textSpan": { + "start": 42, + "length": 2 + }, + "fileName": "/b/index.ts", + "contextSpan": { + "start": 26, + "length": 23 + }, + "isWriteAccess": true, + "isDefinition": true + } + ] + } +] + +// === /b/index.ts === +// export namespace NS { +// export function FB() {} +// } +// +// export interface /*FIND ALL REFS*/[|I|] { +// FB(); +// } +// +// const ib: [|I|] = { FB() {} }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/b/index.ts", + "kind": "interface", + "name": "interface I", + "textSpan": { + "start": 70, + "length": 1 + }, + "displayParts": [ + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + } + ], + "contextSpan": { + "start": 53, + "length": 32 + } + }, + "references": [ + { + "textSpan": { + "start": 70, + "length": 1 + }, + "fileName": "/b/index.ts", + "contextSpan": { + "start": 53, + "length": 32 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 97, + "length": 1 + }, + "fileName": "/b/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] + +// === /b/index.ts === +// export namespace NS { +// export function FB() {} +// } +// +// export interface I { +// /*FIND ALL REFS*/[|FB|](); +// } +// +// const ib: I = { [|FB|]() {} }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/b/index.ts", + "kind": "method", + "name": "(method) I.FB(): any", + "textSpan": { + "start": 78, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FB", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 78, + "length": 5 + } + }, + "references": [ + { + "textSpan": { + "start": 78, + "length": 2 + }, + "fileName": "/b/index.ts", + "contextSpan": { + "start": 78, + "length": 5 + }, + "isWriteAccess": false, + "isDefinition": true + }, + { + "textSpan": { + "start": 103, + "length": 2 + }, + "fileName": "/b/index.ts", + "contextSpan": { + "start": 103, + "length": 7 + }, + "isWriteAccess": true, + "isDefinition": false + } + ] + } +] + +// === /c/index.ts === +// export namespace NS { +// export function /*FIND ALL REFS*/[|FC|]() {} +// } +// +// export interface I { +// FC(); +// } +// +// const ic: I = { FC() {} }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/c/index.ts", + "kind": "function", + "name": "function NS.FC(): void", + "textSpan": { + "start": 42, + "length": 2 + }, + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "NS", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FC", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 26, + "length": 23 + } + }, + "references": [ + { + "textSpan": { + "start": 42, + "length": 2 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 26, + "length": 23 + }, + "isWriteAccess": true, + "isDefinition": true + } + ] + } +] + +// === /a/index.ts === +// import { NS } from "../b"; +// import { [|I|] } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function FA(); +// } +// } +// +// declare module "../c" { +// export interface [|I|] { +// FA(); +// } +// } +// +// const ia: [|I|] = { +// FA: NS.FA, +// FC() { }, +// }; + +// === /a2/index.ts === +// import { NS } from "../b"; +// import { [|I|] } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function FA(); +// } +// } +// +// declare module "../c" { +// export interface [|I|] { +// FA(); +// } +// } +// +// const ia: [|I|] = { +// FA: NS.FA, +// FC() { }, +// }; + +// === /c/index.ts === +// export namespace NS { +// export function FC() {} +// } +// +// export interface /*FIND ALL REFS*/[|I|] { +// FC(); +// } +// +// const ic: [|I|] = { FC() {} }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/c/index.ts", + "kind": "interface", + "name": "interface I", + "textSpan": { + "start": 70, + "length": 1 + }, + "displayParts": [ + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + } + ], + "contextSpan": { + "start": 53, + "length": 32 + } + }, + "references": [ + { + "textSpan": { + "start": 70, + "length": 1 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 53, + "length": 32 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 97, + "length": 1 + }, + "fileName": "/c/index.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 188, + "length": 1 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 171, + "length": 40 + }, + "isWriteAccess": true, + "isDefinition": true + }, + { + "textSpan": { + "start": 188, + "length": 1 + }, + "fileName": "/a2/index.ts", + "contextSpan": { + "start": 171, + "length": 40 + }, + "isWriteAccess": true, + "isDefinition": true + } + ] + }, + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a/index.ts", + "kind": "alias", + "name": "(alias) interface I\nimport I", + "textSpan": { + "start": 36, + "length": 1 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + } + ], + "contextSpan": { + "start": 27, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 36, + "length": 1 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 27, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": false + }, + { + "textSpan": { + "start": 225, + "length": 1 + }, + "fileName": "/a/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + }, + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/a2/index.ts", + "kind": "alias", + "name": "(alias) interface I\nimport I", + "textSpan": { + "start": 36, + "length": 1 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "interface", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "aliasName" + } + ], + "contextSpan": { + "start": 27, + "length": 25 + } + }, + "references": [ + { + "textSpan": { + "start": 36, + "length": 1 + }, + "fileName": "/a2/index.ts", + "contextSpan": { + "start": 27, + "length": 25 + }, + "isWriteAccess": true, + "isDefinition": false + }, + { + "textSpan": { + "start": 225, + "length": 1 + }, + "fileName": "/a2/index.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] + +// === /c/index.ts === +// export namespace NS { +// export function FC() {} +// } +// +// export interface I { +// /*FIND ALL REFS*/[|FC|](); +// } +// +// const ic: I = { [|FC|]() {} }; + +// === /a/index.ts === +// import { NS } from "../b"; +// import { I } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function FA(); +// } +// } +// +// declare module "../c" { +// export interface I { +// FA(); +// } +// } +// +// const ia: I = { +// FA: NS.FA, +// [|FC|]() { }, +// }; + +// === /a2/index.ts === +// import { NS } from "../b"; +// import { I } from "../c"; +// +// declare module "../b" { +// export namespace NS { +// export function FA(); +// } +// } +// +// declare module "../c" { +// export interface I { +// FA(); +// } +// } +// +// const ia: I = { +// FA: NS.FA, +// [|FC|]() { }, +// }; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/c/index.ts", + "kind": "method", + "name": "(method) I.FC(): any", + "textSpan": { + "start": 78, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "FC", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "contextSpan": { + "start": 78, + "length": 5 + } + }, + "references": [ + { + "textSpan": { + "start": 78, + "length": 2 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 78, + "length": 5 + }, + "isWriteAccess": false, + "isDefinition": true + }, + { + "textSpan": { + "start": 103, + "length": 2 + }, + "fileName": "/c/index.ts", + "contextSpan": { + "start": 103, + "length": 7 + }, + "isWriteAccess": true, + "isDefinition": false + }, + { + "textSpan": { + "start": 250, + "length": 2 + }, + "fileName": "/a/index.ts", + "contextSpan": { + "start": 250, + "length": 8 + }, + "isWriteAccess": true, + "isDefinition": false + }, + { + "textSpan": { + "start": 250, + "length": 2 + }, + "fileName": "/a2/index.ts", + "contextSpan": { + "start": 250, + "length": 8 + }, + "isWriteAccess": true, + "isDefinition": false + } + ] + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/server/isDefinitionAcrossGlobalProjects.ts b/tests/cases/fourslash/server/isDefinitionAcrossGlobalProjects.ts new file mode 100644 index 0000000000000..127f59df8dfe2 --- /dev/null +++ b/tests/cases/fourslash/server/isDefinitionAcrossGlobalProjects.ts @@ -0,0 +1,92 @@ +/// + +// @Filename: /a/index.ts +////namespace NS { +//// export function /*1*/FA() { +//// FB(); +//// } +////} +//// +////interface /*2*/I { +//// /*3*/FA(); +////} +//// +////const ia: I = { +//// FA() { }, +//// FB() { }, +//// FC() { }, +//// }; + +// @Filename: /a/tsconfig.json +////{ +//// "extends": "../tsconfig.settings.json", +//// "references": [ +//// { "path": "../b" }, +//// { "path": "../c" }, +//// ], +//// "files": [ +//// "index.ts", +//// ], +////} + +// @Filename: /b/index.ts +////namespace NS { +//// export function /*4*/FB() {} +////} +//// +////interface /*5*/I { +//// /*6*/FB(); +////} +//// +////const ib: I = { FB() {} }; + +// @Filename: /b/tsconfig.json +////{ +//// "extends": "../tsconfig.settings.json", +//// "files": [ +//// "index.ts", +//// ], +////} + +// @Filename: /c/index.ts +////namespace NS { +//// export function /*7*/FC() {} +////} +//// +////interface /*8*/I { +//// /*9*/FC(); +////} +//// +////const ic: I = { FC() {} }; + +// @Filename: /c/tsconfig.json +////{ +//// "extends": "../tsconfig.settings.json", +//// "files": [ +//// "index.ts", +//// ], +////} + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "composite": true, +//// }, +//// "references": [ +//// { "path": "a" }, +//// ], +//// "files": [] +////} + +// @Filename: /tsconfig.settings.json +////{ +//// "compilerOptions": { +//// "composite": true, +//// "skipLibCheck": true, +//// "declarationMap": true, +//// "module": "none", +//// "emitDeclarationOnly": true, +//// } +////} + +verify.baselineFindAllReferences('1', '2', '3', '4', '5', '6', '7', '8', '9'); diff --git a/tests/cases/fourslash/server/isDefinitionAcrossModuleProjects.ts b/tests/cases/fourslash/server/isDefinitionAcrossModuleProjects.ts new file mode 100644 index 0000000000000..cbab02f8b80cb --- /dev/null +++ b/tests/cases/fourslash/server/isDefinitionAcrossModuleProjects.ts @@ -0,0 +1,134 @@ +/// + +// @Filename: /a/index.ts +////import { NS } from "../b"; +////import { I } from "../c"; +//// +////declare module "../b" { +//// export namespace NS { +//// export function /*1*/FA(); +//// } +////} +//// +////declare module "../c" { +//// export interface /*2*/I { +//// /*3*/FA(); +//// } +////} +//// +////const ia: I = { +//// FA: NS.FA, +//// FC() { }, +////}; + +// @Filename: /a/tsconfig.json +////{ +//// "extends": "../tsconfig.settings.json", +//// "references": [ +//// { "path": "../b" }, +//// { "path": "../c" }, +//// ], +//// "files": [ +//// "index.ts", +//// ], +////} + +// @Filename: /a2/index.ts +////import { NS } from "../b"; +////import { I } from "../c"; +//// +////declare module "../b" { +//// export namespace NS { +//// export function /*4*/FA(); +//// } +////} +//// +////declare module "../c" { +//// export interface /*5*/I { +//// /*6*/FA(); +//// } +////} +//// +////const ia: I = { +//// FA: NS.FA, +//// FC() { }, +////}; + +// @Filename: /a2/tsconfig.json +////{ +//// "extends": "../tsconfig.settings.json", +//// "references": [ +//// { "path": "../b" }, +//// { "path": "../c" }, +//// ], +//// "files": [ +//// "index.ts", +//// ], +////} + +// @Filename: /b/index.ts +////export namespace NS { +//// export function /*7*/FB() {} +////} +//// +////export interface /*8*/I { +//// /*9*/FB(); +////} +//// +////const ib: I = { FB() {} }; + +// @Filename: /b/other.ts +////export const Other = 1; + +// @Filename: /b/tsconfig.json +////{ +//// "extends": "../tsconfig.settings.json", +//// "files": [ +//// "index.ts", +//// "other.ts", +//// ], +////} + +// @Filename: /c/index.ts +////export namespace NS { +//// export function /*10*/FC() {} +////} +//// +////export interface /*11*/I { +//// /*12*/FC(); +////} +//// +////const ic: I = { FC() {} }; + +// @Filename: /c/tsconfig.json +////{ +//// "extends": "../tsconfig.settings.json", +//// "files": [ +//// "index.ts", +//// ], +////} + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "composite": true, +//// }, +//// "references": [ +//// { "path": "a" }, +//// { "path": "a2" }, +//// ], +//// "files": [] +////} + +// @Filename: /tsconfig.settings.json +////{ +//// "compilerOptions": { +//// "composite": true, +//// "skipLibCheck": true, +//// "declarationMap": true, +//// "module": "CommonJS", +//// "emitDeclarationOnly": true, +//// } +////} + +verify.baselineFindAllReferences('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'); From 70032036f6f5e289f56643fb94c13e44cc968e0d Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 7 Apr 2022 17:30:45 -0700 Subject: [PATCH 08/11] Move de-duping upstream to fix Full output --- src/server/session.ts | 17 +-- ...initionAcrossGlobalProjects.baseline.jsonc | 144 +----------------- 2 files changed, 14 insertions(+), 147 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index 6bff9131db46e..21959f078904d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -429,7 +429,11 @@ namespace ts.server { // of each definition and merging references from all the projects where they appear. const results: ReferencedSymbol[] = []; + const seenRefs = createDocumentSpanSet(); // It doesn't make sense to have a reference in two definition lists, so we de-dup globally + // TODO: We might end up with a more logical allocation of refs to defs if we pre-sorted the defs by descending ref-count. + // Otherwise, it just ends up attached to the first corresponding def we happen to process. The others may or may not be + // dropped later when we check for defs with ref-count 0. perProjectResults.forEach((projectResults, project) => { for (const referencedSymbol of projectResults) { const mappedDefinitionFile = getMappedLocationForProject(documentSpanLocation(referencedSymbol.definition), project); @@ -449,7 +453,8 @@ namespace ts.server { } for (const ref of referencedSymbol.references) { - if (!contains(symbolToAddTo.references, ref, documentSpansEqual) && !getMappedLocationForProject(documentSpanLocation(ref), project)) { + if (!seenRefs.has(ref) && !getMappedLocationForProject(documentSpanLocation(ref), project)) { + seenRefs.add(ref); symbolToAddTo.references.push(ref); } } @@ -1803,14 +1808,8 @@ namespace ts.server { const nameSpan = nameInfo && nameInfo.textSpan; const symbolStartOffset = nameSpan ? scriptInfo.positionToLineOffset(nameSpan.start).offset : 0; const symbolName = nameSpan ? scriptInfo.getSnapshot().getText(nameSpan.start, textSpanEnd(nameSpan)) : ""; - const refs: protocol.ReferencesResponseItem[] = []; - const seen = createDocumentSpanSet(); - references.forEach(referencedSymbol => { - referencedSymbol.references.forEach(entry => { - if (tryAddToSet(seen, entry)) { - refs.push(referenceEntryToReferencesResponseItem(this.projectService, entry)); - } - }); + const refs: readonly protocol.ReferencesResponseItem[] = flatMap(references, referencedSymbol => { + return referencedSymbol.references.map(entry => referenceEntryToReferencesResponseItem(this.projectService, entry)); }); return { refs, symbolName, symbolStartOffset, symbolDisplayString }; } diff --git a/tests/baselines/reference/isDefinitionAcrossGlobalProjects.baseline.jsonc b/tests/baselines/reference/isDefinitionAcrossGlobalProjects.baseline.jsonc index 7d8a26458c931..cc0ce5e09e75e 100644 --- a/tests/baselines/reference/isDefinitionAcrossGlobalProjects.baseline.jsonc +++ b/tests/baselines/reference/isDefinitionAcrossGlobalProjects.baseline.jsonc @@ -108,11 +108,11 @@ // export function FC() {} // } // -// interface [|I|][|I|] { +// interface [|I|] { // FC(); // } // -// const ic: [|I|][|I|] = { FC() {} }; +// const ic: [|I|] = { FC() {} }; // === /a/index.ts === // namespace NS { @@ -230,61 +230,6 @@ "isDefinition": false } ] - }, - { - "definition": { - "containerKind": "", - "containerName": "", - "fileName": "/c/index.ts", - "kind": "interface", - "name": "interface I", - "textSpan": { - "start": 56, - "length": 1 - }, - "displayParts": [ - { - "text": "interface", - "kind": "keyword" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "I", - "kind": "interfaceName" - } - ], - "contextSpan": { - "start": 46, - "length": 25 - } - }, - "references": [ - { - "textSpan": { - "start": 56, - "length": 1 - }, - "fileName": "/c/index.ts", - "contextSpan": { - "start": 46, - "length": 25 - }, - "isWriteAccess": true, - "isDefinition": true - }, - { - "textSpan": { - "start": 83, - "length": 1 - }, - "fileName": "/c/index.ts", - "isWriteAccess": false, - "isDefinition": false - } - ] } ] @@ -533,11 +478,11 @@ // export function FC() {} // } // -// interface [|I|][|I|] { +// interface [|I|] { // FC(); // } // -// const ic: [|I|][|I|] = { FC() {} }; +// const ic: [|I|] = { FC() {} }; // === /a/index.ts === // namespace NS { @@ -655,61 +600,6 @@ "isDefinition": false } ] - }, - { - "definition": { - "containerKind": "", - "containerName": "", - "fileName": "/c/index.ts", - "kind": "interface", - "name": "interface I", - "textSpan": { - "start": 56, - "length": 1 - }, - "displayParts": [ - { - "text": "interface", - "kind": "keyword" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "I", - "kind": "interfaceName" - } - ], - "contextSpan": { - "start": 46, - "length": 25 - } - }, - "references": [ - { - "textSpan": { - "start": 56, - "length": 1 - }, - "fileName": "/c/index.ts", - "contextSpan": { - "start": 46, - "length": 25 - }, - "isWriteAccess": true, - "isDefinition": true - }, - { - "textSpan": { - "start": 83, - "length": 1 - }, - "fileName": "/c/index.ts", - "isWriteAccess": false, - "isDefinition": false - } - ] } ] @@ -945,11 +835,11 @@ // export function FC() {} // } // -// interface /*FIND ALL REFS*/[|I|]/*FIND ALL REFS*/[|I|] { +// interface /*FIND ALL REFS*/[|I|] { // FC(); // } // -// const ic: [|I|][|I|] = { FC() {} }; +// const ic: [|I|] = { FC() {} }; // === /b/index.ts === // namespace NS { @@ -1088,28 +978,6 @@ "isWriteAccess": false, "isDefinition": false }, - { - "textSpan": { - "start": 56, - "length": 1 - }, - "fileName": "/c/index.ts", - "contextSpan": { - "start": 46, - "length": 25 - }, - "isWriteAccess": true, - "isDefinition": true - }, - { - "textSpan": { - "start": 83, - "length": 1 - }, - "fileName": "/c/index.ts", - "isWriteAccess": false, - "isDefinition": false - }, { "textSpan": { "start": 75, From 780a84ec891319b1781ee5935abd76bdda32784c Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 8 Apr 2022 16:53:57 -0700 Subject: [PATCH 09/11] Add server baseline test to confirm searches are not repeated --- .../unittests/tsserver/projectReferences.ts | 120 +++++++ ...ding-references-in-overlapping-projects.js | 308 ++++++++++++++++++ 2 files changed, 428 insertions(+) create mode 100644 tests/baselines/reference/tsserver/projectReferences/finding-references-in-overlapping-projects.js diff --git a/src/testRunner/unittests/tsserver/projectReferences.ts b/src/testRunner/unittests/tsserver/projectReferences.ts index ba4604be5aabf..1605fe2311308 100644 --- a/src/testRunner/unittests/tsserver/projectReferences.ts +++ b/src/testRunner/unittests/tsserver/projectReferences.ts @@ -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({ + 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({ + 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, () => { diff --git a/tests/baselines/reference/tsserver/projectReferences/finding-references-in-overlapping-projects.js b/tests/baselines/reference/tsserver/projectReferences/finding-references-in-overlapping-projects.js new file mode 100644 index 0000000000000..509e2eb95838b --- /dev/null +++ b/tests/baselines/reference/tsserver/projectReferences/finding-references-in-overlapping-projects.js @@ -0,0 +1,308 @@ +Provided types map file "/a/lib/typesMap.json" doesn't exist +request:{"seq":0,"type":"request","command":"open","arguments":{"file":"/user/username/projects/solution/b/index.ts"}} +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Creating configuration project /user/username/projects/solution/b/tsconfig.json +FileWatcher:: Added:: WatchInfo: /user/username/projects/solution/b/tsconfig.json 2000 undefined Project: /user/username/projects/solution/b/tsconfig.json WatchType: Config file +Config: /user/username/projects/solution/b/tsconfig.json : { + "rootNames": [ + "/user/username/projects/solution/b/index.ts" + ], + "options": { + "composite": true, + "configFilePath": "/user/username/projects/solution/b/tsconfig.json" + }, + "projectReferences": [ + { + "path": "/user/username/projects/solution/a", + "originalPath": "../a" + } + ] +} +Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded +Starting updateGraphWorker: Project: /user/username/projects/solution/b/tsconfig.json +Config: /user/username/projects/solution/a/tsconfig.json : { + "rootNames": [ + "/user/username/projects/solution/a/index.ts" + ], + "options": { + "composite": true, + "module": 0, + "configFilePath": "/user/username/projects/solution/a/tsconfig.json" + } +} +FileWatcher:: Added:: WatchInfo: /user/username/projects/solution/a/tsconfig.json 2000 undefined Project: /user/username/projects/solution/b/tsconfig.json WatchType: Config file +FileWatcher:: Added:: WatchInfo: /user/username/projects/solution/a/index.ts 500 undefined WatchType: Closed Script info +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution 0 undefined Project: /user/username/projects/solution/b/tsconfig.json WatchType: Failed Lookup Locations +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution 0 undefined Project: /user/username/projects/solution/b/tsconfig.json WatchType: Failed Lookup Locations +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/a 1 undefined Project: /user/username/projects/solution/b/tsconfig.json WatchType: Failed Lookup Locations +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/a 1 undefined Project: /user/username/projects/solution/b/tsconfig.json WatchType: Failed Lookup Locations +FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined WatchType: Closed Script info +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/b/node_modules/@types 1 undefined Project: /user/username/projects/solution/b/tsconfig.json WatchType: Type roots +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/b/node_modules/@types 1 undefined Project: /user/username/projects/solution/b/tsconfig.json WatchType: Type roots +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/node_modules/@types 1 undefined Project: /user/username/projects/solution/b/tsconfig.json WatchType: Type roots +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/node_modules/@types 1 undefined Project: /user/username/projects/solution/b/tsconfig.json WatchType: Type roots +Finishing updateGraphWorker: Project: /user/username/projects/solution/b/tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Project '/user/username/projects/solution/b/tsconfig.json' (Configured) + Files (3) + /a/lib/lib.d.ts + /user/username/projects/solution/a/index.ts + /user/username/projects/solution/b/index.ts + + + ../../../../../a/lib/lib.d.ts + Default library for target 'es3' + ../a/index.ts + Source from referenced project '../a/tsconfig.json' included because '--module' is specified as 'none' + Imported via "../a" from file 'index.ts' + index.ts + Part of 'files' list in tsconfig.json + +----------------------------------------------- +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/tsconfig.json :: Config file name: /user/username/projects/solution/tsconfig.json +Creating configuration project /user/username/projects/solution/tsconfig.json +FileWatcher:: Added:: WatchInfo: /user/username/projects/solution/tsconfig.json 2000 undefined Project: /user/username/projects/solution/tsconfig.json WatchType: Config file +Search path: /user/username/projects/solution +For info: /user/username/projects/solution/tsconfig.json :: No config files found. +Project '/user/username/projects/solution/b/tsconfig.json' (Configured) + Files (3) + +----------------------------------------------- +Project '/user/username/projects/solution/tsconfig.json' (Configured) + Files (0) InitialLoadPending + +----------------------------------------------- +Open files: + FileName: /user/username/projects/solution/b/index.ts ProjectRootPath: undefined + Projects: /user/username/projects/solution/b/tsconfig.json +response:{"responseRequired":false} +request:{"command":"references","arguments":{"file":"/user/username/projects/solution/b/index.ts","line":4,"offset":43},"seq":1,"type":"request"} +Finding references to /user/username/projects/solution/b/index.ts position 86 in project /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Creating configuration project /user/username/projects/solution/a/tsconfig.json +Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded +Starting updateGraphWorker: Project: /user/username/projects/solution/a/tsconfig.json +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/a/node_modules/@types 1 undefined Project: /user/username/projects/solution/a/tsconfig.json WatchType: Type roots +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/a/node_modules/@types 1 undefined Project: /user/username/projects/solution/a/tsconfig.json WatchType: Type roots +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/node_modules/@types 1 undefined Project: /user/username/projects/solution/a/tsconfig.json WatchType: Type roots +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/node_modules/@types 1 undefined Project: /user/username/projects/solution/a/tsconfig.json WatchType: Type roots +Finishing updateGraphWorker: Project: /user/username/projects/solution/a/tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Project '/user/username/projects/solution/a/tsconfig.json' (Configured) + Files (2) + /a/lib/lib.d.ts + /user/username/projects/solution/a/index.ts + + + ../../../../../a/lib/lib.d.ts + Default library for target 'es3' + index.ts + Part of 'files' list in tsconfig.json + +----------------------------------------------- +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Finding references to /user/username/projects/solution/a/index.ts position 34 in project /user/username/projects/solution/a/tsconfig.json +Loading configured project /user/username/projects/solution/tsconfig.json +Config: /user/username/projects/solution/tsconfig.json : { + "rootNames": [], + "options": { + "configFilePath": "/user/username/projects/solution/tsconfig.json" + }, + "projectReferences": [ + { + "path": "/user/username/projects/solution/a", + "originalPath": "./a" + }, + { + "path": "/user/username/projects/solution/b", + "originalPath": "./b" + }, + { + "path": "/user/username/projects/solution/c", + "originalPath": "./c" + }, + { + "path": "/user/username/projects/solution/d", + "originalPath": "./d" + } + ] +} +Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded +Starting updateGraphWorker: Project: /user/username/projects/solution/tsconfig.json +Config: /user/username/projects/solution/c/tsconfig.json : { + "rootNames": [ + "/user/username/projects/solution/c/index.ts" + ], + "options": { + "composite": true, + "configFilePath": "/user/username/projects/solution/c/tsconfig.json" + }, + "projectReferences": [ + { + "path": "/user/username/projects/solution/b", + "originalPath": "../b" + } + ] +} +FileWatcher:: Added:: WatchInfo: /user/username/projects/solution/c/tsconfig.json 2000 undefined Project: /user/username/projects/solution/tsconfig.json WatchType: Config file +Config: /user/username/projects/solution/d/tsconfig.json : { + "rootNames": [ + "/user/username/projects/solution/d/index.ts" + ], + "options": { + "composite": true, + "configFilePath": "/user/username/projects/solution/d/tsconfig.json" + }, + "projectReferences": [ + { + "path": "/user/username/projects/solution/c", + "originalPath": "../c" + } + ] +} +FileWatcher:: Added:: WatchInfo: /user/username/projects/solution/d/tsconfig.json 2000 undefined Project: /user/username/projects/solution/tsconfig.json WatchType: Config file +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/node_modules/@types 1 undefined Project: /user/username/projects/solution/tsconfig.json WatchType: Type roots +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/node_modules/@types 1 undefined Project: /user/username/projects/solution/tsconfig.json WatchType: Type roots +Finishing updateGraphWorker: Project: /user/username/projects/solution/tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Different program with same set of files +Creating configuration project /user/username/projects/solution/c/tsconfig.json +Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded +FileWatcher:: Added:: WatchInfo: /user/username/projects/solution/c/index.ts 500 undefined WatchType: Closed Script info +Starting updateGraphWorker: Project: /user/username/projects/solution/c/tsconfig.json +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution 0 undefined Project: /user/username/projects/solution/c/tsconfig.json WatchType: Failed Lookup Locations +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution 0 undefined Project: /user/username/projects/solution/c/tsconfig.json WatchType: Failed Lookup Locations +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/a 1 undefined Project: /user/username/projects/solution/c/tsconfig.json WatchType: Failed Lookup Locations +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/a 1 undefined Project: /user/username/projects/solution/c/tsconfig.json WatchType: Failed Lookup Locations +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/b 1 undefined Project: /user/username/projects/solution/c/tsconfig.json WatchType: Failed Lookup Locations +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/b 1 undefined Project: /user/username/projects/solution/c/tsconfig.json WatchType: Failed Lookup Locations +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/c/node_modules/@types 1 undefined Project: /user/username/projects/solution/c/tsconfig.json WatchType: Type roots +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/c/node_modules/@types 1 undefined Project: /user/username/projects/solution/c/tsconfig.json WatchType: Type roots +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/node_modules/@types 1 undefined Project: /user/username/projects/solution/c/tsconfig.json WatchType: Type roots +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/node_modules/@types 1 undefined Project: /user/username/projects/solution/c/tsconfig.json WatchType: Type roots +Finishing updateGraphWorker: Project: /user/username/projects/solution/c/tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Project '/user/username/projects/solution/c/tsconfig.json' (Configured) + Files (4) + /a/lib/lib.d.ts + /user/username/projects/solution/a/index.ts + /user/username/projects/solution/b/index.ts + /user/username/projects/solution/c/index.ts + + + ../../../../../a/lib/lib.d.ts + Default library for target 'es3' + ../a/index.ts + Imported via "../a" from file 'index.ts' + Imported via "../a" from file '../b/index.ts' + ../b/index.ts + Imported via "../b" from file 'index.ts' + index.ts + Part of 'files' list in tsconfig.json + +----------------------------------------------- +Creating configuration project /user/username/projects/solution/d/tsconfig.json +Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded +FileWatcher:: Added:: WatchInfo: /user/username/projects/solution/d/index.ts 500 undefined WatchType: Closed Script info +Starting updateGraphWorker: Project: /user/username/projects/solution/d/tsconfig.json +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution 0 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Failed Lookup Locations +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution 0 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Failed Lookup Locations +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/a 1 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Failed Lookup Locations +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/a 1 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Failed Lookup Locations +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/c 1 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Failed Lookup Locations +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/c 1 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Failed Lookup Locations +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/b 1 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Failed Lookup Locations +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/b 1 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Failed Lookup Locations +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/d/node_modules/@types 1 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Type roots +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/d/node_modules/@types 1 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Type roots +DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/node_modules/@types 1 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Type roots +Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/solution/node_modules/@types 1 undefined Project: /user/username/projects/solution/d/tsconfig.json WatchType: Type roots +Finishing updateGraphWorker: Project: /user/username/projects/solution/d/tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Project '/user/username/projects/solution/d/tsconfig.json' (Configured) + Files (5) + /a/lib/lib.d.ts + /user/username/projects/solution/a/index.ts + /user/username/projects/solution/b/index.ts + /user/username/projects/solution/c/index.ts + /user/username/projects/solution/d/index.ts + + + ../../../../../a/lib/lib.d.ts + Default library for target 'es3' + ../a/index.ts + Imported via "../a" from file 'index.ts' + Imported via "../a" from file '../c/index.ts' + Imported via "../a" from file '../b/index.ts' + ../b/index.ts + Imported via "../b" from file '../c/index.ts' + ../c/index.ts + Imported via "../c" from file 'index.ts' + index.ts + Part of 'files' list in tsconfig.json + +----------------------------------------------- +Finding references to /user/username/projects/solution/a/index.ts position 34 in project /user/username/projects/solution/c/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Finding references to /user/username/projects/solution/a/index.ts position 34 in project /user/username/projects/solution/d/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/c +For info: /user/username/projects/solution/c/index.ts :: Config file name: /user/username/projects/solution/c/tsconfig.json +Search path: /user/username/projects/solution/c +For info: /user/username/projects/solution/c/index.ts :: Config file name: /user/username/projects/solution/c/tsconfig.json +Search path: /user/username/projects/solution/c +For info: /user/username/projects/solution/c/index.ts :: Config file name: /user/username/projects/solution/c/tsconfig.json +response:{"response":{"refs":[{"file":"/user/username/projects/solution/b/index.ts","start":{"line":2,"offset":26},"end":{"line":2,"offset":27},"contextStart":{"line":2,"offset":17},"contextEnd":{"line":2,"offset":42},"lineText":" import { I } from \"../a\";","isWriteAccess":true},{"file":"/user/username/projects/solution/b/index.ts","start":{"line":4,"offset":43},"end":{"line":4,"offset":44},"lineText":" export class B implements I {","isWriteAccess":false},{"file":"/user/username/projects/solution/a/index.ts","start":{"line":2,"offset":34},"end":{"line":2,"offset":35},"contextStart":{"line":2,"offset":17},"contextEnd":{"line":4,"offset":18},"lineText":" export interface I {","isWriteAccess":true},{"file":"/user/username/projects/solution/c/index.ts","start":{"line":2,"offset":26},"end":{"line":2,"offset":27},"contextStart":{"line":2,"offset":17},"contextEnd":{"line":2,"offset":42},"lineText":" import { I } from \"../a\";","isWriteAccess":true},{"file":"/user/username/projects/solution/c/index.ts","start":{"line":5,"offset":33},"end":{"line":5,"offset":34},"lineText":" export const C: I = new B();","isWriteAccess":false},{"file":"/user/username/projects/solution/d/index.ts","start":{"line":2,"offset":26},"end":{"line":2,"offset":27},"contextStart":{"line":2,"offset":17},"contextEnd":{"line":2,"offset":42},"lineText":" import { I } from \"../a\";","isWriteAccess":true},{"file":"/user/username/projects/solution/d/index.ts","start":{"line":5,"offset":33},"end":{"line":5,"offset":34},"lineText":" export const D: I = C;","isWriteAccess":false}],"symbolName":"I","symbolStartOffset":43,"symbolDisplayString":"(alias) interface I\nimport I"},"responseRequired":true} +request:{"command":"references","arguments":{"file":"/user/username/projects/solution/b/index.ts","line":4,"offset":43},"seq":2,"type":"request"} +Finding references to /user/username/projects/solution/b/index.ts position 86 in project /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Finding references to /user/username/projects/solution/b/index.ts position 86 in project /user/username/projects/solution/c/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Finding references to /user/username/projects/solution/b/index.ts position 86 in project /user/username/projects/solution/d/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/b +For info: /user/username/projects/solution/b/index.ts :: Config file name: /user/username/projects/solution/b/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Search path: /user/username/projects/solution/a +For info: /user/username/projects/solution/a/index.ts :: Config file name: /user/username/projects/solution/a/tsconfig.json +Search path: /user/username/projects/solution/c +For info: /user/username/projects/solution/c/index.ts :: Config file name: /user/username/projects/solution/c/tsconfig.json +Search path: /user/username/projects/solution/c +For info: /user/username/projects/solution/c/index.ts :: Config file name: /user/username/projects/solution/c/tsconfig.json +Search path: /user/username/projects/solution/c +For info: /user/username/projects/solution/c/index.ts :: Config file name: /user/username/projects/solution/c/tsconfig.json +Finding references to /user/username/projects/solution/a/index.ts position 34 in project /user/username/projects/solution/a/tsconfig.json +response:{"response":{"refs":[{"file":"/user/username/projects/solution/b/index.ts","start":{"line":2,"offset":26},"end":{"line":2,"offset":27},"contextStart":{"line":2,"offset":17},"contextEnd":{"line":2,"offset":42},"lineText":" import { I } from \"../a\";","isWriteAccess":true},{"file":"/user/username/projects/solution/b/index.ts","start":{"line":4,"offset":43},"end":{"line":4,"offset":44},"lineText":" export class B implements I {","isWriteAccess":false},{"file":"/user/username/projects/solution/a/index.ts","start":{"line":2,"offset":34},"end":{"line":2,"offset":35},"contextStart":{"line":2,"offset":17},"contextEnd":{"line":4,"offset":18},"lineText":" export interface I {","isWriteAccess":true},{"file":"/user/username/projects/solution/c/index.ts","start":{"line":2,"offset":26},"end":{"line":2,"offset":27},"contextStart":{"line":2,"offset":17},"contextEnd":{"line":2,"offset":42},"lineText":" import { I } from \"../a\";","isWriteAccess":true},{"file":"/user/username/projects/solution/c/index.ts","start":{"line":5,"offset":33},"end":{"line":5,"offset":34},"lineText":" export const C: I = new B();","isWriteAccess":false},{"file":"/user/username/projects/solution/d/index.ts","start":{"line":2,"offset":26},"end":{"line":2,"offset":27},"contextStart":{"line":2,"offset":17},"contextEnd":{"line":2,"offset":42},"lineText":" import { I } from \"../a\";","isWriteAccess":true},{"file":"/user/username/projects/solution/d/index.ts","start":{"line":5,"offset":33},"end":{"line":5,"offset":34},"lineText":" export const D: I = C;","isWriteAccess":false}],"symbolName":"I","symbolStartOffset":43,"symbolDisplayString":"(alias) interface I\nimport I"},"responseRequired":true} \ No newline at end of file From d47ae8a90817ba4308dbf0c7a22ef21d8c4498fd Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 17 May 2022 10:20:30 -0700 Subject: [PATCH 10/11] Manually merge #48758 --- src/server/session.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index 21959f078904d..2a524516ed4fc 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -315,6 +315,7 @@ namespace ts.server { projects, defaultProject, initialLocation, + /*isForRename*/ true, (project, position) => project.getLanguageService().findRenameLocations(position.fileName, position.pos, findInStrings, findInComments, providePrefixAndSuffixTextForRename), (renameLocation, cb) => cb(documentSpanLocation(renameLocation)), ); @@ -340,8 +341,8 @@ namespace ts.server { return results; } - function getDefinitionLocation(defaultProject: Project, initialLocation: DocumentPosition): DocumentPosition | undefined { - const infos = defaultProject.getLanguageService().getDefinitionAtPosition(initialLocation.fileName, initialLocation.pos); + function getDefinitionLocation(defaultProject: Project, initialLocation: DocumentPosition, isForRename: boolean): DocumentPosition | undefined { + const infos = defaultProject.getLanguageService().getDefinitionAtPosition(initialLocation.fileName, initialLocation.pos, /*searchOtherFilesOnly*/ false, /*stopAtAlias*/ isForRename); const info = infos && firstOrUndefined(infos); return info && !info.isLocal ? { fileName: info.fileName, pos: info.textSpan.start } : undefined; } @@ -356,6 +357,7 @@ namespace ts.server { projects, defaultProject, initialLocation, + /*isForRename*/ false, (project, position) => { logger.info(`Finding references to ${position.fileName} position ${position.pos} in project ${project.getProjectName()}`); return project.getLanguageService().findReferences(position.fileName, position.pos); @@ -495,6 +497,7 @@ namespace ts.server { projects: Projects, defaultProject: Project, initialLocation: DocumentPosition, + isForRename: boolean, getResultsForPosition: (project: Project, location: DocumentPosition) => readonly TResult[] | undefined, forPositionInResult: (result: TResult, cb: (location: DocumentPosition) => void) => void, ): readonly TResult[] | ESMap { @@ -518,7 +521,7 @@ namespace ts.server { const projectService = defaultProject.projectService; const cancellationToken = defaultProject.getCancellationToken(); - const defaultDefinition = getDefinitionLocation(defaultProject, initialLocation); + const defaultDefinition = getDefinitionLocation(defaultProject, initialLocation, isForRename); // Don't call these unless !!defaultDefinition const getGeneratedDefinition = memoize(() => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition!.fileName) ? From 827f5f3f11a2e2180a5821ee646a52bcd3371bb0 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 17 May 2022 10:23:33 -0700 Subject: [PATCH 11/11] Update baseline for newer fix to #48963 --- ...onPropertyNameStringLiteral.baseline.jsonc | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/referencesToNonPropertyNameStringLiteral.baseline.jsonc b/tests/baselines/reference/referencesToNonPropertyNameStringLiteral.baseline.jsonc index 0637a088a01e8..5726d6b471ef6 100644 --- a/tests/baselines/reference/referencesToNonPropertyNameStringLiteral.baseline.jsonc +++ b/tests/baselines/reference/referencesToNonPropertyNameStringLiteral.baseline.jsonc @@ -1 +1,22 @@ -[] \ No newline at end of file +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/tests/cases/fourslash/server/referencesToNonPropertyNameStringLiteral.ts", + "kind": "var", + "name": "hello", + "textSpan": { + "start": 21, + "length": 5 + }, + "displayParts": [ + { + "text": "\"hello\"", + "kind": "stringLiteral" + } + ] + }, + "references": [] + } +] \ No newline at end of file