mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-12 20:01:02 -05:00
Merge pull request #32688 from uniqueiniquity/skipCOSForDTS
Avoid compile on save when there is no emit impact
This commit is contained in:
@@ -42,6 +42,11 @@ namespace ts.server {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function dtsChangeCanAffectEmit(compilationSettings: CompilerOptions) {
|
||||
return getEmitDeclarations(compilationSettings) || !!compilationSettings.emitDecoratorMetadata;
|
||||
}
|
||||
|
||||
function formatDiag(fileName: NormalizedPath, project: Project, diag: Diagnostic): protocol.Diagnostic {
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(fileName)!; // TODO: GH#18217
|
||||
return {
|
||||
@@ -1606,15 +1611,22 @@ namespace ts.server {
|
||||
path => this.projectService.getScriptInfoForPath(path)!,
|
||||
projects,
|
||||
(project, info) => {
|
||||
let result: protocol.CompileOnSaveAffectedFileListSingleProject | undefined;
|
||||
if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.isOrphan() && !project.getCompilationSettings().noEmit) {
|
||||
result = {
|
||||
projectFileName: project.getProjectName(),
|
||||
fileNames: project.getCompileOnSaveAffectedFileList(info),
|
||||
projectUsesOutFile: !!project.getCompilationSettings().outFile || !!project.getCompilationSettings().out
|
||||
};
|
||||
if (!project.compileOnSaveEnabled || !project.languageServiceEnabled || project.isOrphan()) {
|
||||
return undefined;
|
||||
}
|
||||
return result;
|
||||
|
||||
const compilationSettings = project.getCompilationSettings();
|
||||
|
||||
if (!!compilationSettings.noEmit || fileExtensionIs(info.fileName, Extension.Dts) && !dtsChangeCanAffectEmit(compilationSettings)) {
|
||||
// avoid triggering emit when a change is made in a .d.ts when declaration emit and decorator metadata emit are disabled
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
projectFileName: project.getProjectName(),
|
||||
fileNames: project.getCompileOnSaveAffectedFileList(info),
|
||||
projectUsesOutFile: !!compilationSettings.outFile || !!compilationSettings.out
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -503,6 +503,112 @@ namespace ts.projectSystem {
|
||||
});
|
||||
});
|
||||
|
||||
describe("for changes in declaration files", () => {
|
||||
function testDTS(dtsFileContents: string, tsFileContents: string, opts: CompilerOptions, expectDTSEmit: boolean) {
|
||||
const dtsFile = {
|
||||
path: "/a/runtime/a.d.ts",
|
||||
content: dtsFileContents
|
||||
};
|
||||
const f2 = {
|
||||
path: "/a/b.ts",
|
||||
content: tsFileContents
|
||||
};
|
||||
const config = {
|
||||
path: "/a/tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: opts,
|
||||
compileOnSave: true
|
||||
})
|
||||
};
|
||||
const host = createServerHost([dtsFile, f2, config]);
|
||||
const session = projectSystem.createSession(host);
|
||||
session.executeCommand(<protocol.OpenRequest>{
|
||||
seq: 1,
|
||||
type: "request",
|
||||
command: "open",
|
||||
arguments: { file: dtsFile.path }
|
||||
});
|
||||
const projectService = session.getProjectService();
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const project = projectService.configuredProjects.get(config.path)!;
|
||||
checkProjectRootFiles(project, [dtsFile.path, f2.path]);
|
||||
session.executeCommand(<protocol.OpenRequest>{
|
||||
seq: 2,
|
||||
type: "request",
|
||||
command: "open",
|
||||
arguments: { file: f2.path }
|
||||
});
|
||||
checkNumberOfProjects(session.getProjectService(), { configuredProjects: 1 });
|
||||
const { response } = session.executeCommand(<protocol.CompileOnSaveAffectedFileListRequest>{
|
||||
seq: 3,
|
||||
type: "request",
|
||||
command: "compileOnSaveAffectedFileList",
|
||||
arguments: { file: dtsFile.path }
|
||||
});
|
||||
if (expectDTSEmit) {
|
||||
assert.equal((response as protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 1, "expected output from 1 project");
|
||||
assert.equal((response as protocol.CompileOnSaveAffectedFileListSingleProject[])[0].fileNames.length, 2, "expected to affect 2 files");
|
||||
}
|
||||
else {
|
||||
assert.equal((response as protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 0, "expected no output");
|
||||
}
|
||||
|
||||
|
||||
const { response: response2 } = session.executeCommand(<protocol.CompileOnSaveAffectedFileListRequest>{
|
||||
seq: 4,
|
||||
type: "request",
|
||||
command: "compileOnSaveAffectedFileList",
|
||||
arguments: { file: f2.path }
|
||||
});
|
||||
assert.equal((response2 as protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 1, "expected output from 1 project");
|
||||
}
|
||||
|
||||
it("should return empty array if change is made in a global declaration file", () => {
|
||||
testDTS(
|
||||
/*dtsFileContents*/ "declare const x: string;",
|
||||
/*tsFileContents*/ "var y = 1;",
|
||||
/*opts*/ {},
|
||||
/*expectDTSEmit*/ false
|
||||
);
|
||||
});
|
||||
|
||||
it("should return empty array if change is made in a module declaration file", () => {
|
||||
testDTS(
|
||||
/*dtsFileContents*/ "export const x: string;",
|
||||
/*tsFileContents*/ "import { x } from './runtime/a;",
|
||||
/*opts*/ {},
|
||||
/*expectDTSEmit*/ false
|
||||
);
|
||||
});
|
||||
|
||||
it("should return results if change is made in a global declaration file with declaration emit", () => {
|
||||
testDTS(
|
||||
/*dtsFileContents*/ "declare const x: string;",
|
||||
/*tsFileContents*/ "var y = 1;",
|
||||
/*opts*/ { declaration: true },
|
||||
/*expectDTSEmit*/ true
|
||||
);
|
||||
});
|
||||
|
||||
it("should return results if change is made in a global declaration file with composite enabled", () => {
|
||||
testDTS(
|
||||
/*dtsFileContents*/ "declare const x: string;",
|
||||
/*tsFileContents*/ "var y = 1;",
|
||||
/*opts*/ { composite: true },
|
||||
/*expectDTSEmit*/ true
|
||||
);
|
||||
});
|
||||
|
||||
it("should return results if change is made in a global declaration file with decorator emit enabled", () => {
|
||||
testDTS(
|
||||
/*dtsFileContents*/ "declare const x: string;",
|
||||
/*tsFileContents*/ "var y = 1;",
|
||||
/*opts*/ { experimentalDecorators: true, emitDecoratorMetadata: true },
|
||||
/*expectDTSEmit*/ true
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem emit with outFile or out setting", () => {
|
||||
function test(opts: CompilerOptions, expectedUsesOutFile: boolean) {
|
||||
const f1 = {
|
||||
|
||||
Reference in New Issue
Block a user