mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-10 18:04:18 -05:00
Merge pull request #34403 from microsoft/commandlinePath
Make sure commandline options are absolute paths so they dont conflict with options from tsbuild info
This commit is contained in:
@@ -1118,7 +1118,7 @@ namespace ts {
|
||||
|
||||
const state: ReusableBuilderProgramState = {
|
||||
fileInfos,
|
||||
compilerOptions: convertFromReusableCompilerOptions(program.options, toAbsolutePath),
|
||||
compilerOptions: convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath),
|
||||
referencedMap: getMapOfReferencedSet(program.referencedMap, toPath),
|
||||
exportedModulesMap: getMapOfReferencedSet(program.exportedModulesMap, toPath),
|
||||
semanticDiagnosticsPerFile: program.semanticDiagnosticsPerFile && arrayToMap(program.semanticDiagnosticsPerFile, value => toPath(isString(value) ? value : value[0]), value => isString(value) ? emptyArray : value[1]),
|
||||
@@ -1156,40 +1156,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function convertFromReusableCompilerOptions(options: CompilerOptions, toAbsolutePath: (path: string) => string) {
|
||||
const result: CompilerOptions = {};
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
|
||||
for (const name in options) {
|
||||
if (hasProperty(options, name)) {
|
||||
result[name] = convertFromReusableCompilerOptionValue(
|
||||
optionsNameMap.get(name.toLowerCase()),
|
||||
options[name] as CompilerOptionsValue,
|
||||
toAbsolutePath
|
||||
);
|
||||
}
|
||||
}
|
||||
if (result.configFilePath) {
|
||||
result.configFilePath = toAbsolutePath(result.configFilePath);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function convertFromReusableCompilerOptionValue(option: CommandLineOption | undefined, value: CompilerOptionsValue, toAbsolutePath: (path: string) => string) {
|
||||
if (option) {
|
||||
if (option.type === "list") {
|
||||
const values = value as readonly (string | number)[];
|
||||
if (option.element.isFilePath && values.length) {
|
||||
return values.map(toAbsolutePath);
|
||||
}
|
||||
}
|
||||
else if (option.isFilePath) {
|
||||
return toAbsolutePath(value as string);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function createRedirectedBuilderProgram(state: { program: Program | undefined; compilerOptions: CompilerOptions; }, configFileParsingDiagnostics: readonly Diagnostic[]): BuilderProgram {
|
||||
return {
|
||||
getState: notImplemented,
|
||||
|
||||
@@ -2041,6 +2041,41 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function convertToOptionsWithAbsolutePaths(options: CompilerOptions, toAbsolutePath: (path: string) => string) {
|
||||
const result: CompilerOptions = {};
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
|
||||
for (const name in options) {
|
||||
if (hasProperty(options, name)) {
|
||||
result[name] = convertToOptionValueWithAbsolutePaths(
|
||||
optionsNameMap.get(name.toLowerCase()),
|
||||
options[name] as CompilerOptionsValue,
|
||||
toAbsolutePath
|
||||
);
|
||||
}
|
||||
}
|
||||
if (result.configFilePath) {
|
||||
result.configFilePath = toAbsolutePath(result.configFilePath);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function convertToOptionValueWithAbsolutePaths(option: CommandLineOption | undefined, value: CompilerOptionsValue, toAbsolutePath: (path: string) => string) {
|
||||
if (option) {
|
||||
if (option.type === "list") {
|
||||
const values = value as readonly (string | number)[];
|
||||
if (option.element.isFilePath && values.length) {
|
||||
return values.map(toAbsolutePath);
|
||||
}
|
||||
}
|
||||
else if (option.isFilePath) {
|
||||
return toAbsolutePath(value as string);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the contents of a config file (tsconfig.json).
|
||||
* @param json The contents of the config file to parse
|
||||
|
||||
@@ -524,7 +524,7 @@ ${indentText}${text}`;
|
||||
|
||||
export const version = "FakeTSVersion";
|
||||
|
||||
export function patchSolutionBuilderHost(host: ts.SolutionBuilderHost<ts.BuilderProgram>, sys: System) {
|
||||
export function patchHostForBuildInfoReadWrite(host: ts.CompilerHost | ts.SolutionBuilderHost<ts.BuilderProgram>) {
|
||||
const originalReadFile = host.readFile;
|
||||
host.readFile = (path, encoding) => {
|
||||
const value = originalReadFile.call(host, path, encoding);
|
||||
@@ -537,7 +537,7 @@ ${indentText}${text}`;
|
||||
|
||||
if (host.writeFile) {
|
||||
const originalWriteFile = host.writeFile;
|
||||
host.writeFile = (fileName, content, writeByteOrderMark) => {
|
||||
host.writeFile = (fileName: string, content: string, writeByteOrderMark: boolean) => {
|
||||
if (!ts.isBuildInfoFile(fileName)) return originalWriteFile.call(host, fileName, content, writeByteOrderMark);
|
||||
const buildInfo = ts.getBuildInfo(content);
|
||||
sanitizeBuildInfoProgram(buildInfo);
|
||||
@@ -545,6 +545,10 @@ ${indentText}${text}`;
|
||||
originalWriteFile.call(host, fileName, ts.getBuildInfoText(buildInfo), writeByteOrderMark);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function patchSolutionBuilderHost(host: ts.SolutionBuilderHost<ts.BuilderProgram>, sys: System) {
|
||||
patchHostForBuildInfoReadWrite(host);
|
||||
|
||||
ts.Debug.assert(host.now === undefined);
|
||||
host.now = () => new Date(sys.vfs.time());
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
"unittests/tsbuild/watchEnvironment.ts",
|
||||
"unittests/tsbuild/watchMode.ts",
|
||||
"unittests/tsc/declarationEmit.ts",
|
||||
"unittests/tsc/incremental.ts",
|
||||
"unittests/tscWatch/consoleClearing.ts",
|
||||
"unittests/tscWatch/emit.ts",
|
||||
"unittests/tscWatch/emitAndErrorUpdates.ts",
|
||||
|
||||
@@ -290,7 +290,7 @@ interface Symbol {
|
||||
baselineSourceMap, modifyFs, baselineReadFileCalls,
|
||||
incrementalScenarios
|
||||
}: VerifyTsBuildInput) {
|
||||
describe(`tsc --b ${scenario}:: ${subScenario}`, () => {
|
||||
describe(`tsc ${commandLineArgs.join(" ")} ${scenario}:: ${subScenario}`, () => {
|
||||
let tick: () => void;
|
||||
let sys: TscCompileSystem;
|
||||
before(() => {
|
||||
|
||||
@@ -50,8 +50,15 @@ namespace ts {
|
||||
|
||||
Debug.assert(commandLine.fileNames.length !== 0 || !!configFileName);
|
||||
|
||||
const currentDirectory = sys.getCurrentDirectory();
|
||||
const getCanonicalFileName = createGetCanonicalFileName(sys.useCaseSensitiveFileNames);
|
||||
const commandLineOptions = convertToOptionsWithAbsolutePaths(
|
||||
commandLine.options,
|
||||
fileName => toPath(fileName, currentDirectory, getCanonicalFileName)
|
||||
);
|
||||
|
||||
if (configFileName) {
|
||||
const configParseResult = Debug.assertDefined(parseConfigFileWithSystem(configFileName, commandLine.options, sys, reportDiagnostic));
|
||||
const configParseResult = Debug.assertDefined(parseConfigFileWithSystem(configFileName, commandLineOptions, sys, reportDiagnostic));
|
||||
if (isIncrementalCompilation(configParseResult.options)) {
|
||||
performIncrementalCompilation(sys, configParseResult);
|
||||
}
|
||||
@@ -61,10 +68,16 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
if (isIncrementalCompilation(commandLine.options)) {
|
||||
performIncrementalCompilation(sys, commandLine);
|
||||
performIncrementalCompilation(sys, {
|
||||
...commandLine,
|
||||
options: commandLineOptions
|
||||
});
|
||||
}
|
||||
else {
|
||||
performCompilation(sys, commandLine);
|
||||
performCompilation(sys, {
|
||||
...commandLine,
|
||||
options: commandLineOptions
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,6 +92,7 @@ namespace ts {
|
||||
const { fileNames, options, projectReferences } = config;
|
||||
const reportDiagnostic = createDiagnosticReporter(sys, options.pretty);
|
||||
const host = createCompilerHostWorker(options, /*setParentPos*/ undefined, sys);
|
||||
fakes.patchHostForBuildInfoReadWrite(host);
|
||||
const currentDirectory = host.getCurrentDirectory();
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
|
||||
changeCompilerHostLikeToUseCache(host, fileName => toPath(fileName, currentDirectory, getCanonicalFileName));
|
||||
@@ -102,7 +116,10 @@ namespace ts {
|
||||
function performIncrementalCompilation(sys: TscCompileSystem, config: ParsedCommandLine) {
|
||||
const reportDiagnostic = createDiagnosticReporter(sys, config.options.pretty);
|
||||
const { options, fileNames, projectReferences } = config;
|
||||
const host = createIncrementalCompilerHost(options, sys);
|
||||
fakes.patchHostForBuildInfoReadWrite(host);
|
||||
const exitCode = ts.performIncrementalCompilation({
|
||||
host,
|
||||
system: sys,
|
||||
rootNames: fileNames,
|
||||
options,
|
||||
|
||||
42
src/testRunner/unittests/tsc/incremental.ts
Normal file
42
src/testRunner/unittests/tsc/incremental.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
namespace ts {
|
||||
describe("unittests:: tsc:: incremental::", () => {
|
||||
verifyTscIncrementalEdits({
|
||||
scenario: "incremental",
|
||||
subScenario: "when passing filename for buildinfo on commandline",
|
||||
fs: () => loadProjectFromFiles({
|
||||
"/src/project/src/main.ts": "export const x = 10;",
|
||||
"/src/project/tsconfig.json": utils.dedent`
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
]
|
||||
}`,
|
||||
}),
|
||||
commandLineArgs: ["--incremental", "--p", "src/project", "--tsBuildInfoFile", "src/project/.tsbuildinfo"],
|
||||
incrementalScenarios: [{
|
||||
buildKind: BuildKind.IncrementalDtsUnchanged,
|
||||
modifyFs: noop,
|
||||
}]
|
||||
});
|
||||
|
||||
verifyTsc({
|
||||
scenario: "incremental",
|
||||
subScenario: "when passing rootDir from commandline",
|
||||
fs: () => loadProjectFromFiles({
|
||||
"/src/project/src/main.ts": "export const x = 10;",
|
||||
"/src/project/tsconfig.json": utils.dedent`
|
||||
{
|
||||
"compilerOptions": {
|
||||
"incremental": true,
|
||||
"outDir": "dist",
|
||||
},
|
||||
}`,
|
||||
}),
|
||||
commandLineArgs: ["--p", "src/project", "--rootDir", "src/project/src"],
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -120,7 +120,12 @@ namespace ts {
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
|
||||
const commandLineOptions = commandLine.options;
|
||||
const currentDirectory = sys.getCurrentDirectory();
|
||||
const getCanonicalFileName = createGetCanonicalFileName(sys.useCaseSensitiveFileNames);
|
||||
const commandLineOptions = convertToOptionsWithAbsolutePaths(
|
||||
commandLine.options,
|
||||
fileName => toPath(fileName, currentDirectory, getCanonicalFileName)
|
||||
);
|
||||
if (configFileName) {
|
||||
const configParseResult = parseConfigFileWithSystem(configFileName, commandLineOptions, sys, reportDiagnostic)!; // TODO: GH#18217
|
||||
if (commandLineOptions.showConfig) {
|
||||
@@ -148,7 +153,7 @@ namespace ts {
|
||||
else {
|
||||
if (commandLineOptions.showConfig) {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
sys.write(JSON.stringify(convertToTSConfig(commandLine, combinePaths(sys.getCurrentDirectory(), "tsconfig.json"), sys), null, 4) + sys.newLine);
|
||||
sys.write(JSON.stringify(convertToTSConfig(commandLine, combinePaths(currentDirectory, "tsconfig.json"), sys), null, 4) + sys.newLine);
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
updateReportDiagnostic(commandLineOptions);
|
||||
@@ -157,7 +162,10 @@ namespace ts {
|
||||
createWatchOfFilesAndCompilerOptions(commandLine.fileNames, commandLineOptions);
|
||||
}
|
||||
else if (isIncrementalCompilation(commandLineOptions)) {
|
||||
performIncrementalCompilation(commandLine);
|
||||
performIncrementalCompilation({
|
||||
...commandLine,
|
||||
options: commandLineOptions
|
||||
});
|
||||
}
|
||||
else {
|
||||
performCompilation(commandLine.fileNames, /*references*/ undefined, commandLineOptions);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
//// [/lib/incremental-declaration-doesnt-changeOutput.txt]
|
||||
/lib/tsc --incremental --p src/project --tsBuildInfoFile src/project/.tsbuildinfo
|
||||
exitCode:: 0
|
||||
|
||||
|
||||
//// [/src/project/.tsbuildinfo] file written with same contents
|
||||
@@ -0,0 +1,42 @@
|
||||
//// [/lib/initial-buildOutput.txt]
|
||||
/lib/tsc --incremental --p src/project --tsBuildInfoFile src/project/.tsbuildinfo
|
||||
exitCode:: 0
|
||||
|
||||
|
||||
//// [/src/project/.tsbuildinfo]
|
||||
{
|
||||
"program": {
|
||||
"fileInfos": {
|
||||
"../../lib/lib.d.ts": {
|
||||
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
|
||||
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };"
|
||||
},
|
||||
"./src/main.ts": {
|
||||
"version": "-10726455937-export const x = 10;",
|
||||
"signature": "-6057683066-export declare const x = 10;\r\n"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"target": 1,
|
||||
"module": 1,
|
||||
"incremental": true,
|
||||
"project": "./",
|
||||
"tsBuildInfoFile": "./.tsbuildinfo",
|
||||
"configFilePath": "./tsconfig.json"
|
||||
},
|
||||
"referencedMap": {},
|
||||
"exportedModulesMap": {},
|
||||
"semanticDiagnosticsPerFile": [
|
||||
"../../lib/lib.d.ts",
|
||||
"./src/main.ts"
|
||||
]
|
||||
},
|
||||
"version": "FakeTSVersion"
|
||||
}
|
||||
|
||||
//// [/src/project/src/main.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.x = 10;
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
//// [/lib/initial-buildOutput.txt]
|
||||
/lib/tsc --p src/project --rootDir src/project/src
|
||||
exitCode:: 0
|
||||
|
||||
|
||||
//// [/src/project/dist/main.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.x = 10;
|
||||
|
||||
|
||||
//// [/src/project/tsconfig.tsbuildinfo]
|
||||
{
|
||||
"program": {
|
||||
"fileInfos": {
|
||||
"../../lib/lib.d.ts": {
|
||||
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
|
||||
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };"
|
||||
},
|
||||
"./src/main.ts": {
|
||||
"version": "-10726455937-export const x = 10;",
|
||||
"signature": "-6057683066-export declare const x = 10;\r\n"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"incremental": true,
|
||||
"outDir": "./dist",
|
||||
"project": "./",
|
||||
"rootDir": "./src",
|
||||
"configFilePath": "./tsconfig.json"
|
||||
},
|
||||
"referencedMap": {},
|
||||
"exportedModulesMap": {},
|
||||
"semanticDiagnosticsPerFile": [
|
||||
"../../lib/lib.d.ts",
|
||||
"./src/main.ts"
|
||||
]
|
||||
},
|
||||
"version": "FakeTSVersion"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user