mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Support dynamic file names with project root path (#35111)
* Support dynamic file names with project root path Fixes #35094 * Remove unexpected change
This commit is contained in:
parent
ef0cca7d12
commit
aa0cb889da
@ -1141,7 +1141,7 @@ namespace ts.server {
|
||||
|
||||
const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) ||
|
||||
this.getOrCreateSingleInferredProjectIfEnabled() ||
|
||||
this.getOrCreateSingleInferredWithoutProjectRoot(info.isDynamic ? this.currentDirectory : getDirectoryPath(info.path));
|
||||
this.getOrCreateSingleInferredWithoutProjectRoot(info.isDynamic ? projectRootPath || this.currentDirectory : getDirectoryPath(info.path));
|
||||
|
||||
project.addRoot(info);
|
||||
if (info.containingProjects[0] !== project) {
|
||||
@ -1503,6 +1503,8 @@ namespace ts.server {
|
||||
|
||||
Debug.assert(!isOpenScriptInfo(info) || this.openFiles.has(info.path));
|
||||
const projectRootPath = this.openFiles.get(info.path);
|
||||
const scriptInfo = Debug.assertDefined(this.getScriptInfo(info.path));
|
||||
if (scriptInfo.isDynamic) return undefined;
|
||||
|
||||
let searchPath = asNormalizedPath(getDirectoryPath(info.fileName));
|
||||
const isSearchPathInProjectRoot = () => containsPath(projectRootPath!, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames);
|
||||
@ -1943,7 +1945,9 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getOrCreateInferredProjectForProjectRootPathIfEnabled(info: ScriptInfo, projectRootPath: NormalizedPath | undefined): InferredProject | undefined {
|
||||
if (info.isDynamic || !this.useInferredProjectPerProjectRoot) {
|
||||
if (!this.useInferredProjectPerProjectRoot ||
|
||||
// Its a dynamic info opened without project root
|
||||
(info.isDynamic && projectRootPath === undefined)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -2228,7 +2232,7 @@ namespace ts.server {
|
||||
const isDynamic = isDynamicFileName(fileName);
|
||||
Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nScript info with non-dynamic relative file name can only be open script info or in context of host currentDirectory`);
|
||||
Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nOpen script files with non rooted disk path opened with current directory context cannot have same canonical names`);
|
||||
Debug.assert(!isDynamic || this.currentDirectory === currentDirectory, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nDynamic files must always have current directory context since containing external project name will always match the script info name.`);
|
||||
Debug.assert(!isDynamic || this.currentDirectory === currentDirectory || this.useInferredProjectPerProjectRoot, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nDynamic files must always be opened with service's current directory or service should support inferred project per projectRootPath.`);
|
||||
// If the file is not opened by client and the file doesnot exist on the disk, return
|
||||
if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) {
|
||||
return;
|
||||
@ -2239,7 +2243,7 @@ namespace ts.server {
|
||||
if (!openedByClient) {
|
||||
this.watchClosedScriptInfo(info);
|
||||
}
|
||||
else if (!isRootedDiskPath(fileName) && !isDynamic) {
|
||||
else if (!isRootedDiskPath(fileName) && (!isDynamic || this.currentDirectory !== currentDirectory)) {
|
||||
// File that is opened by user but isn't rooted disk path
|
||||
this.openFilesWithNonRootedDiskPath.set(this.toCanonicalFileName(fileName), info);
|
||||
}
|
||||
|
||||
@ -1131,6 +1131,62 @@ var x = 10;`
|
||||
checkProjectActualFiles(project, [file.path, libFile.path]);
|
||||
});
|
||||
|
||||
describe("dynamic file with projectRootPath", () => {
|
||||
const file: File = {
|
||||
path: "^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js",
|
||||
content: "var x = 10;"
|
||||
};
|
||||
const configFile: File = {
|
||||
path: `${projectRoot}/tsconfig.json`,
|
||||
content: "{}"
|
||||
};
|
||||
const configProjectFile: File = {
|
||||
path: `${projectRoot}/a.ts`,
|
||||
content: "let y = 10;"
|
||||
};
|
||||
it("with useInferredProjectPerProjectRoot", () => {
|
||||
const host = createServerHost([libFile, configFile, configProjectFile], { useCaseSensitiveFileNames: true });
|
||||
const session = createSession(host, { useInferredProjectPerProjectRoot: true });
|
||||
openFilesForSession([{ file: file.path, projectRootPath: projectRoot }], session);
|
||||
|
||||
const projectService = session.getProjectService();
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.inferredProjects[0], [file.path, libFile.path]);
|
||||
|
||||
session.executeCommandSeq<protocol.OutliningSpansRequest>({
|
||||
command: protocol.CommandTypes.GetOutliningSpans,
|
||||
arguments: {
|
||||
file: file.path
|
||||
}
|
||||
});
|
||||
|
||||
// Without project root
|
||||
const file2Path = file.path.replace("#1", "#2");
|
||||
projectService.openClientFile(file2Path, file.content);
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 2 });
|
||||
checkProjectActualFiles(projectService.inferredProjects[0], [file.path, libFile.path]);
|
||||
checkProjectActualFiles(projectService.inferredProjects[1], [file2Path, libFile.path]);
|
||||
});
|
||||
|
||||
it("fails when useInferredProjectPerProjectRoot is false", () => {
|
||||
const host = createServerHost([libFile, configFile, configProjectFile], { useCaseSensitiveFileNames: true });
|
||||
const projectService = createProjectService(host);
|
||||
try {
|
||||
projectService.openClientFile(file.path, file.content, /*scriptKind*/ undefined, projectRoot);
|
||||
}
|
||||
catch (e) {
|
||||
assert.strictEqual(
|
||||
e.message.replace(/\r?\n/, "\n"),
|
||||
`Debug Failure. False expression: \nVerbose Debug Information: {"fileName":"^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js","currentDirectory":"/user/username/projects/myproject","hostCurrentDirectory":"/","openKeys":[]}\nDynamic files must always be opened with service's current directory or service should support inferred project per projectRootPath.`
|
||||
);
|
||||
}
|
||||
const file2Path = file.path.replace("#1", "#2");
|
||||
projectService.openClientFile(file2Path, file.content);
|
||||
projectService.checkNumberOfProjects({ inferredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.inferredProjects[0], [file2Path, libFile.path]);
|
||||
});
|
||||
});
|
||||
|
||||
it("files opened, closed affecting multiple projects", () => {
|
||||
const file: File = {
|
||||
path: "/a/b/projects/config/file.ts",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user