Make configFile on compiler options as non enumerable

This commit is contained in:
Sheetal Nandi 2017-05-26 17:06:15 -07:00
parent 16fd947ac3
commit 7bd9e092ac
13 changed files with 38 additions and 62 deletions

View File

@ -1380,6 +1380,13 @@ namespace ts {
return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions);
}
/*@internal*/
export function setConfigFileInOptions(options: CompilerOptions, configFile: JsonSourceFile) {
if (configFile) {
Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile });
}
}
/**
* Parse the contents of a config file from json or json source file (tsconfig.json).
* @param json The contents of the config file to parse
@ -1406,8 +1413,7 @@ namespace ts {
const { raw } = parsedConfig;
const options = extend(existingOptions, parsedConfig.options || {});
options.configFilePath = configFileName;
options.configFile = sourceFile;
setConfigFileInOptions(options, sourceFile);
const { fileNames, wildcardDirectories } = getFileNames();
return {
options,

View File

@ -3449,7 +3449,7 @@ namespace ts {
charset?: string;
checkJs?: boolean;
/* @internal */ configFilePath?: string;
/* @internal */ configFile?: JsonSourceFile;
/* @internal */ readonly configFile?: JsonSourceFile;
declaration?: boolean;
declarationDir?: string;
/* @internal */ diagnostics?: boolean;

View File

@ -82,7 +82,7 @@ class CompilerBaselineRunner extends RunnerBase {
if (testCaseContent.tsConfig) {
assert.equal(testCaseContent.tsConfig.fileNames.length, 0, `list of files in tsconfig is not currently supported`);
tsConfigOptions = ts.clone(testCaseContent.tsConfig.options);
tsConfigOptions = ts.cloneCompilerOptions(testCaseContent.tsConfig.options);
tsConfigFiles.push(this.createHarnessTestFile(testCaseContent.tsConfigFileUnitData, rootDir, ts.combinePaths(rootDir, tsConfigOptions.configFilePath)));
}
else {

View File

@ -1123,7 +1123,7 @@ namespace Harness {
compilerOptions: ts.CompilerOptions,
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
currentDirectory: string): CompilationOutput {
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.clone(compilerOptions) : { noResolve: false };
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.cloneCompilerOptions(compilerOptions) : { noResolve: false };
options.target = options.target || ts.ScriptTarget.ES3;
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
options.noErrorTruncation = true;

View File

@ -87,6 +87,7 @@ namespace RWC {
const configParseResult = ts.parseJsonSourceFileConfigFileContent(parsedTsconfigFileContents, configParseHost, ts.getDirectoryPath(tsconfigFile.path));
fileNames = configParseResult.fileNames;
opts.options = ts.extend(opts.options, configParseResult.options);
ts.setConfigFileInOptions(opts.options, configParseResult.options.configFile);
}
// Load the files
@ -262,4 +263,4 @@ class RWCRunner extends RunnerBase {
private runTest(jsonFileName: string) {
RWC.runRWCTest(jsonFileName);
}
}
}

View File

@ -158,7 +158,7 @@ namespace ts {
// setting compiler options discards module resolution cache
fileExistsCalled = false;
const compilerOptions = ts.clone(project.getCompilerOptions());
const compilerOptions = ts.cloneCompilerOptions(project.getCompilerOptions());
compilerOptions.target = ts.ScriptTarget.ES5;
project.setCompilerOptions(compilerOptions);

View File

@ -131,14 +131,15 @@ namespace ts {
it(name, () => {
const parsed = getParseCommandLine(entry);
assert(!parsed.errors.length, flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n"));
assert.deepEqual(parsed.options, ts.extend(expected, <CompilerOptions>{ configFile: undefined }));
assert.deepEqual(parsed.options, expected);
assert.deepEqual(parsed.fileNames, expectedFiles);
});
it(name + " with jsonSourceFile", () => {
const { parsed, jsonSourceFile } = getParseCommandLineJsonSourceFile(entry);
assert(!parsed.errors.length, flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n"));
assert.deepEqual(parsed.options, ts.extend(expected, <CompilerOptions>{ configFile: jsonSourceFile }));
assert.deepEqual(parsed.options, expected);
assert.equal(parsed.options.configFile, jsonSourceFile);
assert.deepEqual(parsed.fileNames, expectedFiles);
});
}
@ -208,4 +209,4 @@ namespace ts {
});
});
});
}
}

View File

@ -34,11 +34,11 @@ namespace ts {
const host: ParseConfigHost = new Utils.MockParseConfigHost("/apath/", true, []);
const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
expectedResult.compilerOptions["configFilePath"] = configFileName;
expectedResult.compilerOptions.configFile = result;
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions);
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
assert.equal(actualCompilerOptions.configFile, result);
const actualErrors = filter(actualParseErrors, error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
const expectedErrors = expectedResult.errors;

View File

@ -789,7 +789,7 @@ namespace ts.server {
setCompilerOptions(options?: CompilerOptions) {
// Avoid manipulating the given options directly
const newOptions = options ? clone(options) : this.getCompilerOptions();
const newOptions = options ? cloneCompilerOptions(options) : this.getCompilerOptions();
if (!newOptions) {
return;
}

View File

@ -132,20 +132,6 @@ namespace ts.server {
return `Content-Length: ${1 + len}\r\n\r\n${json}${newLine}`;
}
/**
* Get the compiler options without configFile key
* @param options
*/
function getCompilerOptionsWithoutConfigFile(options: CompilerOptions) {
const result: CompilerOptions = {};
for (const option in options) {
if (option !== "configFile") {
result[option] = options[option];
}
}
return result;
}
/**
* Allows to schedule next step in multistep operation
*/
@ -1670,39 +1656,19 @@ namespace ts.server {
},
[CommandNames.SynchronizeProjectList]: (request: protocol.SynchronizeProjectListRequest) => {
const result = this.projectService.synchronizeProjectList(request.arguments.knownProjects);
// Remapping of the result is needed if
// - there are project errors
// - options contain configFile - need to remove it from options before serializing
const shouldRemapProjectFilesWithTSDiagnostics = (p: ProjectFilesWithTSDiagnostics) => (p.projectErrors && !!p.projectErrors.length) || (p.info && !!p.info.options.configFile);
if (!some(result, shouldRemapProjectFilesWithTSDiagnostics)) {
if (!result.some(p => p.projectErrors && p.projectErrors.length !== 0)) {
return this.requiredResponse(result);
}
const converted = map(result, p => {
if (shouldRemapProjectFilesWithTSDiagnostics(p)) {
// Map the project errors
const projectErrors = p.projectErrors && p.projectErrors.length ?
this.convertToDiagnosticsWithLinePosition(p.projectErrors, /*scriptInfo*/ undefined) :
p.projectErrors;
// Remove the configFile in the options before serializing
const info = p.info && !!p.info.options.configFile ?
{
projectName: p.info.projectName,
isInferred: p.info.isInferred,
version: p.info.version,
options: getCompilerOptionsWithoutConfigFile(p.info.options),
languageServiceDisabled: p.info.languageServiceDisabled
} : p.info;
return {
info,
changes: p.changes,
files: p.files,
projectErrors
};
if (!p.projectErrors || p.projectErrors.length === 0) {
return p;
}
return p;
return {
info: p.info,
changes: p.changes,
files: p.files,
projectErrors: this.convertToDiagnosticsWithLinePosition(p.projectErrors, /*scriptInfo*/ undefined)
};
});
return this.requiredResponse(converted);
},

View File

@ -1292,7 +1292,7 @@ namespace ts {
const currentOptions = program.getCompilerOptions();
const newOptions = hostCache.compilationSettings();
// If the compilation settings do no match, then the program is not up-to-date
if (!compareDataObjects(currentOptions, newOptions, "configFile")) {
if (!compareDataObjects(currentOptions, newOptions)) {
return false;
}

View File

@ -130,7 +130,7 @@ namespace ts {
commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || <CommandLineOptionOfCustomType[]>filter(optionDeclarations, o =>
typeof o.type === "object" && !forEachEntry(o.type, v => typeof v !== "number"));
options = clone(options);
options = cloneCompilerOptions(options);
for (const opt of commandLineOptionsStringToEnum) {
if (!hasProperty(options, opt.name)) {

View File

@ -997,16 +997,18 @@ namespace ts {
return false;
}
export function compareDataObjects(dst: any, src: any, ignoreKey?: string): boolean {
export function cloneCompilerOptions(options: CompilerOptions): CompilerOptions {
const result = clone(options);
setConfigFileInOptions(result, options && options.configFile);
return result;
}
export function compareDataObjects(dst: any, src: any): boolean {
if (!dst || !src || Object.keys(dst).length !== Object.keys(src).length) {
return false;
}
for (const e in dst) {
if (ignoreKey && ignoreKey === e) {
continue;
}
if (typeof dst[e] === "object") {
if (!compareDataObjects(dst[e], src[e])) {
return false;