-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Navto covers all projects #38027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Navto covers all projects #38027
Changes from 1 commit
b48a724
40e80ca
e212f1e
fc8bc8b
600eb8a
9b218d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
1. Add test 2. Change protocol. navto-all only happens when filename is undefined or missing. 3. Change location to earlier code path. This change was largely type-guided and resulted in some duplicated code, but I think it's less fault-prone.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -448,16 +448,9 @@ namespace ts.server { | |
}); | ||
} | ||
} | ||
else { | ||
projectService.forEachEnabledProject(project => { | ||
if (!addToSeen(seenProjects, project)) return; | ||
projectService.loadAncestorProjectTree(seenProjects); | ||
toDo = callbackProjectAndLocation(project, undefined as TLocation, projectService, toDo, seenProjects, cb); | ||
}); | ||
} | ||
|
||
while (toDo && toDo.length) { | ||
const next = toDo.pop() | ||
const next = toDo.pop(); | ||
Debug.assertIsDefined(next); | ||
toDo = callbackProjectAndLocation(next.project, next.location, projectService, toDo, seenProjects, cb); | ||
} | ||
|
@@ -1907,14 +1900,27 @@ namespace ts.server { | |
|
||
private getFullNavigateToItems(args: protocol.NavtoRequestArgs): readonly NavigateToItem[] { | ||
const { currentFileOnly, searchValue, maxResultCount } = args; | ||
if (!args.file) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Seems like it's now possible to specify a project and no file. If some caller were to do that, I'd expect it to get back There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, With no file and just project, the result should be only from that project. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The original case handles basically this case, but includes hits from all dependencies as well. Any ideas for how to reduce it to just the current project? (It's probably OK to keep the original behaviour, since it won't at least surprise anyone.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For example, in the test cases, the 'user' project that depends on 'a' and 'b' projects returns [user.ts, a.ts, b.ts] for |
||
const items: NavigateToItem[] = []; | ||
this.projectService.forEachEnabledProject(project => { | ||
sandersn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
this.projectService.loadAncestorProjectTree(); | ||
for (const item of project.getLanguageService().getNavigateToItems(searchValue, maxResultCount, /*filename*/ undefined, /*excludeDts*/ project.isNonTsProject())) { | ||
if (!contains(items, item, navigateToItemIsEqualTo)) { | ||
items.push(item); | ||
} | ||
} | ||
}); | ||
return items; | ||
} | ||
const fileArgs = args as protocol.FileRequestArgs; | ||
uniqueiniquity marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (currentFileOnly) { | ||
const { file, project } = this.getFileAndProject(args); | ||
const { file, project } = this.getFileAndProject(fileArgs); | ||
return project.getLanguageService().getNavigateToItems(searchValue, maxResultCount, file); | ||
} | ||
else { | ||
return combineProjectOutputWhileOpeningReferencedProjects<NavigateToItem>( | ||
this.getProjects(args), | ||
this.getDefaultProject(args), | ||
this.getProjects(fileArgs), | ||
this.getDefaultProject(fileArgs), | ||
project => | ||
project.getLanguageService().getNavigateToItems(searchValue, maxResultCount, /*fileName*/ undefined, /*excludeDts*/ project.isNonTsProject()), | ||
documentSpanLocation, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,7 +63,7 @@ namespace ts.projectSystem { | |
}; | ||
const aDts: File = { | ||
path: "/a/bin/a.d.ts", | ||
// Need to mangle the sourceMappingURL part or it breaks the build | ||
// ${""} is needed to mangle the sourceMappingURL part or it breaks the build | ||
content: `export declare function fnA(): void;\nexport interface IfaceA {\n}\nexport declare const instanceA: IfaceA;\n//# source${""}MappingURL=a.d.ts.map`, | ||
}; | ||
|
||
|
@@ -86,7 +86,7 @@ namespace ts.projectSystem { | |
content: JSON.stringify(bDtsMapContent), | ||
}; | ||
const bDts: File = { | ||
// Need to mangle the sourceMappingURL part or it breaks the build | ||
// ${""} is need to mangle the sourceMappingURL part so it doesn't break the build | ||
path: "/b/bin/b.d.ts", | ||
content: `export declare function fnB(): void;\n//# source${""}MappingURL=b.d.ts.map`, | ||
}; | ||
|
@@ -114,15 +114,17 @@ namespace ts.projectSystem { | |
}) | ||
}; | ||
|
||
function makeSampleProjects(addUserTsConfig?: boolean) { | ||
function makeSampleProjects(addUserTsConfig?: boolean, keepAllFiles?: boolean) { | ||
const host = createServerHost([aTs, aTsconfig, aDtsMap, aDts, bTsconfig, bTs, bDtsMap, bDts, ...(addUserTsConfig ? [userTsForConfigProject, userTsconfig] : [userTs]), dummyFile]); | ||
const session = createSession(host); | ||
|
||
checkDeclarationFiles(aTs, session, [aDtsMap, aDts]); | ||
checkDeclarationFiles(bTs, session, [bDtsMap, bDts]); | ||
|
||
// Testing what happens if we delete the original sources. | ||
host.deleteFile(bTs.path); | ||
if (!keepAllFiles) { | ||
host.deleteFile(bTs.path); | ||
} | ||
|
||
openFilesForSession([userTs], session); | ||
const service = session.getProjectService(); | ||
|
@@ -322,6 +324,46 @@ namespace ts.projectSystem { | |
verifyATsConfigOriginalProject(session); | ||
}); | ||
|
||
it("navigateToAll", () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need test when file is not specified and project is... |
||
const session = makeSampleProjects(/*addUserTsConfig*/ true, /*keepAllFiles*/ true); | ||
const response = executeSessionRequest<protocol.NavtoRequest, protocol.NavtoResponse>(session, CommandNames.Navto, { file: undefined, searchValue: "fn" }); | ||
assert.deepEqual<readonly protocol.NavtoItem[] | undefined>(response, [ | ||
{ | ||
...protocolFileSpanFromSubstring({ | ||
file: bTs, | ||
text: "export function fnB() {}" | ||
}), | ||
name: "fnB", | ||
matchKind: "prefix", | ||
isCaseSensitive: true, | ||
kind: ScriptElementKind.functionElement, | ||
kindModifiers: "export", | ||
}, | ||
{ | ||
...protocolFileSpanFromSubstring({ | ||
file: aTs, | ||
text: "export function fnA() {}" | ||
}), | ||
name: "fnA", | ||
matchKind: "prefix", | ||
isCaseSensitive: true, | ||
kind: ScriptElementKind.functionElement, | ||
kindModifiers: "export", | ||
}, | ||
{ | ||
...protocolFileSpanFromSubstring({ | ||
file: userTs, | ||
text: "export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }" | ||
}), | ||
name: "fnUser", | ||
matchKind: "prefix", | ||
isCaseSensitive: true, | ||
kind: ScriptElementKind.functionElement, | ||
kindModifiers: "export", | ||
} | ||
]); | ||
}); | ||
|
||
const referenceATs = (aTs: File): protocol.ReferencesResponseItem => makeReferenceItem({ | ||
file: aTs, | ||
isDefinition: true, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the only substantive change. Everything else is a removal of a frankly ridiculous amount of destructuring/allocation to pass around a project+location pair.