mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Clean up api so that parsing returns JsonSourceFile
This commit is contained in:
@@ -462,7 +462,7 @@ namespace ts {
|
||||
];
|
||||
|
||||
/* @internal */
|
||||
export let typeAcquisitionDeclarations: CommandLineOption[] = [
|
||||
export const typeAcquisitionDeclarations: CommandLineOption[] = [
|
||||
{
|
||||
/* @deprecated typingOptions.enableAutoDiscovery
|
||||
* Use typeAcquisition.enable instead.
|
||||
@@ -723,10 +723,10 @@ namespace ts {
|
||||
* @param jsonText The text of the config file
|
||||
*/
|
||||
export function parseConfigFileTextToJson(fileName: string, jsonText: string): { config?: any; error?: Diagnostic } {
|
||||
const { node, errors } = parseJsonText(fileName, jsonText);
|
||||
const jsonSourceFile = parseJsonText(fileName, jsonText);
|
||||
return {
|
||||
config: convertToJson(node, errors),
|
||||
error: errors.length ? errors[0] : undefined
|
||||
config: convertToJson(jsonSourceFile, jsonSourceFile.parseDiagnostics),
|
||||
error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -734,13 +734,13 @@ namespace ts {
|
||||
* Read tsconfig.json file
|
||||
* @param fileName The path to the config file
|
||||
*/
|
||||
export function readConfigFileToJsonNode(fileName: string, readFile: (path: string) => string): ParsedNodeResults<JsonNode> {
|
||||
export function readConfigFileToJsonSourceFile(fileName: string, readFile: (path: string) => string): JsonSourceFile {
|
||||
let text = "";
|
||||
try {
|
||||
text = readFile(fileName);
|
||||
}
|
||||
catch (e) {
|
||||
return { errors: [createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message)] };
|
||||
return <JsonSourceFile>{ parseDiagnostics: [createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message)] };
|
||||
}
|
||||
return parseJsonText(fileName, text);
|
||||
}
|
||||
@@ -819,8 +819,8 @@ namespace ts {
|
||||
* @param jsonNode
|
||||
* @param errors
|
||||
*/
|
||||
export function convertToJson(jsonNode: JsonNode, errors: Diagnostic[]): any {
|
||||
return convertToJsonWorker(jsonNode, errors);
|
||||
export function convertToJson(sourceFile: JsonSourceFile, errors: Diagnostic[]): any {
|
||||
return convertToJsonWorker(sourceFile, errors);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -828,17 +828,15 @@ namespace ts {
|
||||
* @param jsonNode
|
||||
* @param errors
|
||||
*/
|
||||
function convertToJsonWorker(jsonNode: JsonNode, errors: Diagnostic[], knownRootOptions?: Map<CommandLineOption>, optionsIterator?: JsonConversionNotifier): any {
|
||||
if (!jsonNode) {
|
||||
function convertToJsonWorker(sourceFile: JsonSourceFile, errors: Diagnostic[], knownRootOptions?: Map<CommandLineOption>, optionsIterator?: JsonConversionNotifier): any {
|
||||
if (!sourceFile.jsonObject) {
|
||||
if (sourceFile.endOfFileToken) {
|
||||
return {};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (jsonNode.kind === SyntaxKind.EndOfFileToken) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const sourceFile = <SourceFile>jsonNode.parent;
|
||||
return convertObjectLiteralExpressionToJson(jsonNode, knownRootOptions);
|
||||
return convertObjectLiteralExpressionToJson(sourceFile.jsonObject, knownRootOptions);
|
||||
|
||||
function convertObjectLiteralExpressionToJson(node: ObjectLiteralExpression, options?: Map<CommandLineOption>, extraKeyDiagnosticMessage?: DiagnosticMessage, optionsObject?: string): any {
|
||||
const result: any = {};
|
||||
@@ -1076,7 +1074,7 @@ namespace ts {
|
||||
* file to. e.g. outDir
|
||||
*/
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[]): ParsedCommandLine {
|
||||
return parseJsonConfigFileContentWorker(json, /*jsonNode*/ undefined, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1086,8 +1084,8 @@ namespace ts {
|
||||
* @param basePath A root directory to resolve relative path entries in the config
|
||||
* file to. e.g. outDir
|
||||
*/
|
||||
export function parseJsonNodeConfigFileContent(jsonNode: JsonNode, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[]): ParsedCommandLine {
|
||||
return parseJsonConfigFileContentWorker(/*json*/ undefined, jsonNode, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
export function parseJsonSourceFileConfigFileContent(sourceFile: JsonSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[]): ParsedCommandLine {
|
||||
return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1097,8 +1095,8 @@ namespace ts {
|
||||
* @param basePath A root directory to resolve relative path entries in the config
|
||||
* file to. e.g. outDir
|
||||
*/
|
||||
function parseJsonConfigFileContentWorker(json: any, jsonNode: JsonNode, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string, resolutionStack: Path[] = []): ParsedCommandLine {
|
||||
Debug.assert((json === undefined && jsonNode !== undefined) || (json !== undefined && jsonNode === undefined));
|
||||
function parseJsonConfigFileContentWorker(json: any, sourceFile: JsonSourceFile, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string, resolutionStack: Path[] = []): ParsedCommandLine {
|
||||
Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined));
|
||||
const errors: Diagnostic[] = [];
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
|
||||
const resolvedPath = toPath(configFileName || "", basePath, getCanonicalFileName);
|
||||
@@ -1107,7 +1105,7 @@ namespace ts {
|
||||
options: {},
|
||||
fileNames: [],
|
||||
typeAcquisition: {},
|
||||
raw: json || convertToJson(jsonNode, errors),
|
||||
raw: json || convertToJson(sourceFile, errors),
|
||||
errors: errors.concat(createCompilerDiagnostic(Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, [...resolutionStack, resolvedPath].join(" -> "))),
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
@@ -1141,7 +1139,7 @@ namespace ts {
|
||||
switch (key) {
|
||||
case "extends":
|
||||
const extendsDiagnostic = getExtendsConfigPath(<string>value, (message, arg0) =>
|
||||
createDiagnosticForNodeInSourceFile(<SourceFile>jsonNode.parent, node, message, arg0));
|
||||
createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0));
|
||||
if ((<Diagnostic>extendsDiagnostic).messageText) {
|
||||
errors.push(<Diagnostic>extendsDiagnostic);
|
||||
hasExtendsError = true;
|
||||
@@ -1151,11 +1149,11 @@ namespace ts {
|
||||
}
|
||||
return;
|
||||
case "excludes":
|
||||
errors.push(createDiagnosticForNodeInSourceFile(<SourceFile>jsonNode.parent, propertyName, Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, propertyName, Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
|
||||
return;
|
||||
case "files":
|
||||
if ((<string[]>value).length === 0) {
|
||||
errors.push(createDiagnosticForNodeInSourceFile(<SourceFile>jsonNode.parent, node, Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"));
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, node, Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"));
|
||||
}
|
||||
return;
|
||||
case "compileOnSave":
|
||||
@@ -1164,7 +1162,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
};
|
||||
json = convertToJsonWorker(jsonNode, errors, getTsconfigRootOptionsMap(), optionsIterator);
|
||||
json = convertToJsonWorker(sourceFile, errors, getTsconfigRootOptionsMap(), optionsIterator);
|
||||
if (!typeAcquisition) {
|
||||
if (typingOptionstypeAcquisition) {
|
||||
typeAcquisition = (typingOptionstypeAcquisition.enableAutoDiscovery !== undefined) ?
|
||||
@@ -1244,16 +1242,16 @@ namespace ts {
|
||||
extendedConfigPath = `${extendedConfigPath}.json` as Path;
|
||||
}
|
||||
|
||||
const extendedResult = readConfigFileToJsonNode(extendedConfigPath, path => host.readFile(path));
|
||||
if (extendedResult.errors.length) {
|
||||
errors.push(...extendedResult.errors);
|
||||
const extendedResult = readConfigFileToJsonSourceFile(extendedConfigPath, path => host.readFile(path));
|
||||
if (extendedResult.parseDiagnostics.length) {
|
||||
errors.push(...extendedResult.parseDiagnostics);
|
||||
return;
|
||||
}
|
||||
const extendedDirname = getDirectoryPath(extendedConfigPath);
|
||||
const relativeDifference = convertToRelativePath(extendedDirname, basePath, getCanonicalFileName);
|
||||
const updatePath: (path: string) => string = path => isRootedDiskPath(path) ? path : combinePaths(relativeDifference, path);
|
||||
// Merge configs (copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios)
|
||||
const result = parseJsonNodeConfigFileContent(extendedResult.node, host, extendedDirname, /*existingOptions*/undefined, getBaseFileName(extendedConfigPath), resolutionStack.concat([resolvedPath]));
|
||||
const result = parseJsonSourceFileConfigFileContent(extendedResult, host, extendedDirname, /*existingOptions*/undefined, getBaseFileName(extendedConfigPath), resolutionStack.concat([resolvedPath]));
|
||||
errors.push(...result.errors);
|
||||
const [include, exclude, files] = map(["include", "exclude", "files"], key => {
|
||||
if (!json[key] && result.raw[key]) {
|
||||
@@ -1313,7 +1311,7 @@ namespace ts {
|
||||
includeSpecs = ["**/*"];
|
||||
}
|
||||
|
||||
const result = matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors, jsonNode);
|
||||
const result = matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors, sourceFile);
|
||||
|
||||
if (result.fileNames.length === 0 && !hasProperty(json, "files") && resolutionStack.length === 0) {
|
||||
errors.push(
|
||||
@@ -1328,7 +1326,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createCompilerDiagnosticForJson(message: DiagnosticMessage, arg0?: string, arg1?: string) {
|
||||
if (!jsonNode) {
|
||||
if (!sourceFile) {
|
||||
errors.push(createCompilerDiagnostic(message, arg0, arg1));
|
||||
}
|
||||
}
|
||||
@@ -1548,7 +1546,7 @@ namespace ts {
|
||||
* @param host The host used to resolve files and directories.
|
||||
* @param errors An array for diagnostic reporting.
|
||||
*/
|
||||
function matchFileNames(fileNames: string[], include: string[], exclude: string[], basePath: string, options: CompilerOptions, host: ParseConfigHost, errors: Diagnostic[], jsonNode: JsonNode): ExpandResult {
|
||||
function matchFileNames(fileNames: string[], include: string[], exclude: string[], basePath: string, options: CompilerOptions, host: ParseConfigHost, errors: Diagnostic[], jsonSourceFile: JsonSourceFile): ExpandResult {
|
||||
basePath = normalizePath(basePath);
|
||||
|
||||
// The exclude spec list is converted into a regular expression, which allows us to quickly
|
||||
@@ -1567,11 +1565,11 @@ namespace ts {
|
||||
const wildcardFileMap = createMap<string>();
|
||||
|
||||
if (include) {
|
||||
include = validateSpecs(include, errors, /*allowTrailingRecursion*/ false, jsonNode, "include");
|
||||
include = validateSpecs(include, errors, /*allowTrailingRecursion*/ false, jsonSourceFile, "include");
|
||||
}
|
||||
|
||||
if (exclude) {
|
||||
exclude = validateSpecs(exclude, errors, /*allowTrailingRecursion*/ true, jsonNode, "exclude");
|
||||
exclude = validateSpecs(exclude, errors, /*allowTrailingRecursion*/ true, jsonSourceFile, "exclude");
|
||||
}
|
||||
|
||||
// Wildcard directories (provided as part of a wildcard path) are stored in a
|
||||
@@ -1627,7 +1625,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function validateSpecs(specs: string[], errors: Diagnostic[], allowTrailingRecursion: boolean, jsonNode: JsonNode, specKey: string) {
|
||||
function validateSpecs(specs: string[], errors: Diagnostic[], allowTrailingRecursion: boolean, jsonSourceFile: JsonSourceFile, specKey: string) {
|
||||
const validSpecs: string[] = [];
|
||||
for (const spec of specs) {
|
||||
if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
|
||||
@@ -1647,13 +1645,13 @@ namespace ts {
|
||||
return validSpecs;
|
||||
|
||||
function createDiagnostic(message: DiagnosticMessage, spec: string): Diagnostic {
|
||||
if (jsonNode && jsonNode.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
for (const property of jsonNode.properties) {
|
||||
if (jsonSourceFile && jsonSourceFile.jsonObject) {
|
||||
for (const property of jsonSourceFile.jsonObject.properties) {
|
||||
if (property.kind === SyntaxKind.PropertyAssignment && getTextOfPropertyName(property.name) === specKey) {
|
||||
const specsNode = <ArrayLiteralExpression>property.initializer;
|
||||
for (const element of specsNode.elements) {
|
||||
if (element.kind === SyntaxKind.StringLiteral && (<StringLiteral>element).text === spec) {
|
||||
return createDiagnosticForNodeInSourceFile(<SourceFile>jsonNode.parent, element, message, spec);
|
||||
return createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1928,6 +1928,8 @@ namespace ts {
|
||||
return ScriptKind.TS;
|
||||
case ".tsx":
|
||||
return ScriptKind.TSX;
|
||||
case ".json":
|
||||
return ScriptKind.JSON;
|
||||
default:
|
||||
return ScriptKind.Unknown;
|
||||
}
|
||||
|
||||
+13
-17
@@ -450,14 +450,12 @@ namespace ts {
|
||||
return Parser.parseIsolatedEntityName(text, languageVersion);
|
||||
}
|
||||
|
||||
export type ParsedNodeResults<T extends Node> = { node?: T; errors: Diagnostic[] };
|
||||
|
||||
/**
|
||||
* Parse json text into SyntaxTree and return node and parse errors if any
|
||||
* @param fileName
|
||||
* @param sourceText
|
||||
*/
|
||||
export function parseJsonText(fileName: string, sourceText: string): ParsedNodeResults<JsonNode> {
|
||||
export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile {
|
||||
return Parser.parseJsonText(fileName, sourceText);
|
||||
}
|
||||
|
||||
@@ -622,36 +620,34 @@ namespace ts {
|
||||
return isInvalid ? entityName : undefined;
|
||||
}
|
||||
|
||||
export function parseJsonText(fileName: string, sourceText: string): ParsedNodeResults<JsonNode> {
|
||||
initializeState(sourceText, ScriptTarget.ES2015, /*syntaxCursor*/ undefined, ScriptKind.JS);
|
||||
export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile {
|
||||
initializeState(sourceText, ScriptTarget.ES2015, /*syntaxCursor*/ undefined, ScriptKind.JSON);
|
||||
// Set source file so that errors will be reported with this file name
|
||||
sourceFile = <SourceFile>{ kind: SyntaxKind.SourceFile, text: sourceText, fileName };
|
||||
let node: JsonNode;
|
||||
sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON);
|
||||
const result = <JsonSourceFile>sourceFile;
|
||||
|
||||
// Prime the scanner.
|
||||
nextToken();
|
||||
if (token() === SyntaxKind.EndOfFileToken) {
|
||||
node = <EndOfFileToken>parseTokenNode();
|
||||
sourceFile.endOfFileToken = <EndOfFileToken>parseTokenNode();
|
||||
}
|
||||
else if (token() === SyntaxKind.OpenBraceToken ||
|
||||
lookAhead(() => token() === SyntaxKind.StringLiteral)) {
|
||||
node = parseObjectLiteralExpression();
|
||||
parseExpected(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token);
|
||||
result.jsonObject = parseObjectLiteralExpression();
|
||||
sourceFile.endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, /*reportAtCurrentPosition*/ false, Diagnostics.Unexpected_token);
|
||||
}
|
||||
else {
|
||||
parseExpected(SyntaxKind.OpenBraceToken);
|
||||
}
|
||||
|
||||
if (node) {
|
||||
node.parent = sourceFile;
|
||||
}
|
||||
const errors = parseDiagnostics;
|
||||
sourceFile.parseDiagnostics = parseDiagnostics;
|
||||
clearState();
|
||||
return { node, errors };
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLanguageVariant(scriptKind: ScriptKind) {
|
||||
// .tsx and .jsx files are treated as jsx language variant.
|
||||
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
}
|
||||
|
||||
function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
|
||||
@@ -669,7 +665,7 @@ namespace ts {
|
||||
identifierCount = 0;
|
||||
nodeCount = 0;
|
||||
|
||||
contextFlags = scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX ? NodeFlags.JavaScriptFile : NodeFlags.None;
|
||||
contextFlags = scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JSON ? NodeFlags.JavaScriptFile : NodeFlags.None;
|
||||
parseErrorBeforeNextFinishedNode = false;
|
||||
|
||||
// Initialize and prime the scanner before parsing the source elements.
|
||||
|
||||
+3
-3
@@ -307,13 +307,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
const result = parseJsonText(configFileName, cachedConfigFileText);
|
||||
reportDiagnostics(result.errors, /* compilerHost */ undefined);
|
||||
if (!result.node) {
|
||||
reportDiagnostics(result.parseDiagnostics, /* compilerHost */ undefined);
|
||||
if (!result.endOfFileToken) {
|
||||
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
return;
|
||||
}
|
||||
const cwd = sys.getCurrentDirectory();
|
||||
const configParseResult = parseJsonNodeConfigFileContent(result.node, sys, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), commandLine.options, getNormalizedAbsolutePath(configFileName, cwd));
|
||||
const configParseResult = parseJsonSourceFileConfigFileContent(result, sys, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), commandLine.options, getNormalizedAbsolutePath(configFileName, cwd));
|
||||
if (configParseResult.errors.length > 0) {
|
||||
reportDiagnostics(configParseResult.errors, /* compilerHost */ undefined);
|
||||
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
|
||||
@@ -527,8 +527,6 @@ namespace ts {
|
||||
export type AtToken = Token<SyntaxKind.AtToken>;
|
||||
export type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
|
||||
|
||||
export type JsonNode = ObjectLiteralExpression | EndOfFileToken;
|
||||
|
||||
export type Modifier
|
||||
= Token<SyntaxKind.AbstractKeyword>
|
||||
| Token<SyntaxKind.AsyncKeyword>
|
||||
@@ -2189,6 +2187,10 @@ namespace ts {
|
||||
/* @internal */ ambientModuleNames: string[];
|
||||
}
|
||||
|
||||
export interface JsonSourceFile extends SourceFile {
|
||||
jsonObject?: ObjectLiteralExpression;
|
||||
}
|
||||
|
||||
export interface ScriptReferenceHost {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getSourceFile(fileName: string): SourceFile;
|
||||
@@ -3261,7 +3263,8 @@ namespace ts {
|
||||
JS = 1,
|
||||
JSX = 2,
|
||||
TS = 3,
|
||||
TSX = 4
|
||||
TSX = 4,
|
||||
JSON = 5
|
||||
}
|
||||
|
||||
export const enum ScriptTarget {
|
||||
|
||||
@@ -1877,12 +1877,12 @@ namespace Harness {
|
||||
const data = testUnitData[i];
|
||||
if (ts.getBaseFileName(data.name).toLowerCase() === "tsconfig.json") {
|
||||
const configJson = ts.parseJsonText(data.name, data.content);
|
||||
assert.isTrue(configJson.node !== undefined);
|
||||
assert.isTrue(configJson.endOfFileToken !== undefined);
|
||||
let baseDir = ts.normalizePath(ts.getDirectoryPath(data.name));
|
||||
if (rootDir) {
|
||||
baseDir = ts.getNormalizedAbsolutePath(baseDir, rootDir);
|
||||
}
|
||||
tsConfig = ts.parseJsonNodeConfigFileContent(configJson.node, parseConfigHost, baseDir);
|
||||
tsConfig = ts.parseJsonSourceFileConfigFileContent(configJson, parseConfigHost, baseDir);
|
||||
tsConfig.options.configFilePath = data.name;
|
||||
|
||||
// delete entry from the list
|
||||
|
||||
@@ -210,30 +210,23 @@ class ProjectRunner extends RunnerBase {
|
||||
|
||||
let errors: ts.Diagnostic[];
|
||||
if (configFileName) {
|
||||
const result = ts.readConfigFileToJsonNode(configFileName, getSourceFileText);
|
||||
if (!result.node) {
|
||||
return {
|
||||
moduleKind,
|
||||
errors: result.errors
|
||||
};
|
||||
}
|
||||
|
||||
const result = ts.readConfigFileToJsonSourceFile(configFileName, getSourceFileText);
|
||||
const configParseHost: ts.ParseConfigHost = {
|
||||
useCaseSensitiveFileNames: Harness.IO.useCaseSensitiveFileNames(),
|
||||
fileExists,
|
||||
readDirectory,
|
||||
readFile
|
||||
};
|
||||
const configParseResult = ts.parseJsonNodeConfigFileContent(result.node, configParseHost, ts.getDirectoryPath(configFileName), compilerOptions);
|
||||
const configParseResult = ts.parseJsonSourceFileConfigFileContent(result, configParseHost, ts.getDirectoryPath(configFileName), compilerOptions);
|
||||
if (configParseResult.errors.length > 0) {
|
||||
return {
|
||||
moduleKind,
|
||||
errors: result.errors.concat(configParseResult.errors)
|
||||
errors: result.parseDiagnostics.concat(configParseResult.errors)
|
||||
};
|
||||
}
|
||||
inputFiles = configParseResult.fileNames;
|
||||
compilerOptions = configParseResult.options;
|
||||
errors = result.errors;
|
||||
errors = result.parseDiagnostics;
|
||||
}
|
||||
|
||||
const projectCompilerResult = compileProjectFiles(moduleKind, () => inputFiles, getSourceFileText, writeFile, compilerOptions);
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace RWC {
|
||||
readDirectory: Harness.IO.readDirectory,
|
||||
readFile: Harness.IO.readFile
|
||||
};
|
||||
const configParseResult = ts.parseJsonNodeConfigFileContent(parsedTsconfigFileContents.node, configParseHost, ts.getDirectoryPath(tsconfigFile.path));
|
||||
const configParseResult = ts.parseJsonSourceFileConfigFileContent(parsedTsconfigFileContents, configParseHost, ts.getDirectoryPath(tsconfigFile.path));
|
||||
fileNames = configParseResult.fileNames;
|
||||
opts.options = ts.extend(opts.options, configParseResult.options);
|
||||
}
|
||||
|
||||
@@ -110,21 +110,29 @@ namespace ts {
|
||||
["under a case insensitive host", caseInsensitiveBasePath, caseInsensitiveHost],
|
||||
["under a case sensitive host", caseSensitiveBasePath, caseSensitiveHost]
|
||||
], ([testName, basePath, host]) => {
|
||||
function getParseCommandLine(entry: string) {
|
||||
const {config, error} = ts.readConfigFile(entry, name => host.readFile(name));
|
||||
assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n"));
|
||||
return ts.parseJsonConfigFileContent(config, host, basePath, {}, entry);
|
||||
}
|
||||
|
||||
function getParseCommandLineJsonSourceFile(entry: string) {
|
||||
const jsonSourceFile = ts.readConfigFileToJsonSourceFile(entry, name => host.readFile(name));
|
||||
assert(jsonSourceFile.endOfFileToken && !jsonSourceFile.parseDiagnostics.length, flattenDiagnosticMessageText(jsonSourceFile.parseDiagnostics[0] && jsonSourceFile.parseDiagnostics[0].messageText, "\n"));
|
||||
return ts.parseJsonSourceFileConfigFileContent(jsonSourceFile, host, basePath, {}, entry);
|
||||
}
|
||||
|
||||
function testSuccess(name: string, entry: string, expected: CompilerOptions, expectedFiles: string[]) {
|
||||
it(name, () => {
|
||||
const {config, error} = ts.readConfigFile(entry, name => host.readFile(name));
|
||||
assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n"));
|
||||
const parsed = ts.parseJsonConfigFileContent(config, host, basePath, {}, entry);
|
||||
const parsed = getParseCommandLine(entry);
|
||||
assert(!parsed.errors.length, flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n"));
|
||||
expected.configFilePath = entry;
|
||||
assert.deepEqual(parsed.options, expected);
|
||||
assert.deepEqual(parsed.fileNames, expectedFiles);
|
||||
});
|
||||
|
||||
it(name, () => {
|
||||
const {node, errors} = ts.readConfigFileToJsonNode(entry, name => host.readFile(name));
|
||||
assert(node && !errors.length, flattenDiagnosticMessageText(errors[0] && errors[0].messageText, "\n"));
|
||||
const parsed = ts.parseJsonNodeConfigFileContent(node, host, basePath, {}, entry);
|
||||
it(name + "with jsonSourceFile", () => {
|
||||
const parsed = getParseCommandLineJsonSourceFile(entry);
|
||||
assert(!parsed.errors.length, flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n"));
|
||||
expected.configFilePath = entry;
|
||||
assert.deepEqual(parsed.options, expected);
|
||||
@@ -134,16 +142,12 @@ namespace ts {
|
||||
|
||||
function testFailure(name: string, entry: string, expectedDiagnostics: { code: number, category: DiagnosticCategory, messageText: string }[]) {
|
||||
it(name, () => {
|
||||
const {config, error} = ts.readConfigFile(entry, name => host.readFile(name));
|
||||
assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n"));
|
||||
const parsed = ts.parseJsonConfigFileContent(config, host, basePath, {}, entry);
|
||||
const parsed = getParseCommandLine(entry);
|
||||
verifyDiagnostics(parsed.errors, expectedDiagnostics);
|
||||
});
|
||||
|
||||
it(name, () => {
|
||||
const {node, errors} = ts.readConfigFileToJsonNode(entry, name => host.readFile(name));
|
||||
assert(node && !errors.length, flattenDiagnosticMessageText(errors[0] && errors[0].messageText, "\n"));
|
||||
const parsed = ts.parseJsonNodeConfigFileContent(node, host, basePath, {}, entry);
|
||||
it(name + "with jsonSourceFile", () => {
|
||||
const parsed = getParseCommandLineJsonSourceFile(entry);
|
||||
verifyDiagnostics(parsed.errors, expectedDiagnostics);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,11 +28,11 @@ namespace ts {
|
||||
|
||||
function assertCompilerOptionsWithJsonNode(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const fileText = JSON.stringify(json);
|
||||
const { node, errors } = parseJsonText(configFileName, fileText);
|
||||
assert(!errors.length);
|
||||
assert(!!node);
|
||||
const result = parseJsonText(configFileName, fileText);
|
||||
assert(!result.parseDiagnostics.length);
|
||||
assert(!!result.endOfFileToken);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost("/apath/", true, []);
|
||||
const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonNodeConfigFileContent(node, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
expectedResult.compilerOptions["configFilePath"] = configFileName;
|
||||
|
||||
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
|
||||
|
||||
@@ -40,11 +40,11 @@ namespace ts {
|
||||
|
||||
function assertTypeAcquisitionWithJsonNode(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
const fileText = JSON.stringify(json);
|
||||
const { node, errors } = parseJsonText(configFileName, fileText);
|
||||
assert(!errors.length);
|
||||
assert(!!node);
|
||||
const result = parseJsonText(configFileName, fileText);
|
||||
assert(!result.parseDiagnostics.length);
|
||||
assert(!!result.endOfFileToken);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost("/apath/", true, []);
|
||||
const { typeAcquisition: actualTypeAcquisition, errors: actualParseErrors } = parseJsonNodeConfigFileContent(node, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
const { typeAcquisition: actualTypeAcquisition, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
verifyAcquisition(actualTypeAcquisition, expectedResult);
|
||||
|
||||
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);
|
||||
|
||||
@@ -98,8 +98,13 @@ namespace ts {
|
||||
function validateMatches(expected: ts.ParsedCommandLine, json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[]) {
|
||||
{
|
||||
const jsonText = JSON.stringify(json);
|
||||
const {node} = parseJsonText(caseInsensitiveTsconfigPath, jsonText);
|
||||
const actual = ts.parseJsonNodeConfigFileContent(node, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
const result = parseJsonText(caseInsensitiveTsconfigPath, jsonText);
|
||||
const actual = ts.parseJsonSourceFileConfigFileContent(result, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
for (const error of expected.errors) {
|
||||
if (error.file) {
|
||||
error.file = result;
|
||||
}
|
||||
}
|
||||
assertParsed(actual, expected);
|
||||
}
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace ts {
|
||||
}
|
||||
{
|
||||
const parsed = ts.parseJsonText("/apath/tsconfig.json", jsonText);
|
||||
const parsedCommand = ts.parseJsonNodeConfigFileContent(parsed.node, ts.sys, "tests/cases/unittests");
|
||||
const parsedCommand = ts.parseJsonSourceFileConfigFileContent(parsed, ts.sys, "tests/cases/unittests");
|
||||
assert.isTrue(parsedCommand.errors && parsedCommand.errors.length === 1 &&
|
||||
parsedCommand.errors[0].code === ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude.code);
|
||||
}
|
||||
@@ -38,7 +38,7 @@ namespace ts {
|
||||
function getParsedCommandJsonNode(jsonText: string, configFileName: string, basePath: string, allFileList: string[]) {
|
||||
const parsed = ts.parseJsonText(configFileName, jsonText);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost(basePath, true, allFileList);
|
||||
return ts.parseJsonNodeConfigFileContent(parsed.node, host, basePath, /*existingOptions*/ undefined, configFileName);
|
||||
return ts.parseJsonSourceFileConfigFileContent(parsed, host, basePath, /*existingOptions*/ undefined, configFileName);
|
||||
}
|
||||
|
||||
function assertParseFileList(jsonText: string, configFileName: string, basePath: string, allFileList: string[], expectedFileList: string[]) {
|
||||
@@ -231,8 +231,9 @@ namespace ts {
|
||||
}
|
||||
"files": ["file1.ts"]
|
||||
}`;
|
||||
const { node, errors: diagnostics } = parseJsonText("config.json", content);
|
||||
const configJsonObject = convertToJson(node, diagnostics);
|
||||
const result = parseJsonText("config.json", content);
|
||||
const diagnostics = result.parseDiagnostics;
|
||||
const configJsonObject = convertToJson(result, diagnostics);
|
||||
const expectedResult = {
|
||||
compilerOptions: {
|
||||
allowJs: true,
|
||||
|
||||
@@ -790,18 +790,18 @@ namespace ts.server {
|
||||
return findProjectByName(projectFileName, this.externalProjects);
|
||||
}
|
||||
|
||||
private getDefaultParsedJsonNode(): EndOfFileToken {
|
||||
return <EndOfFileToken>{ kind: SyntaxKind.EndOfFileToken };
|
||||
}
|
||||
|
||||
private convertConfigFileContentToProjectOptions(configFilename: string): ConfigFileConversionResult {
|
||||
configFilename = normalizePath(configFilename);
|
||||
|
||||
const configFileContent = this.host.readFile(configFilename);
|
||||
|
||||
const { node = this.getDefaultParsedJsonNode(), errors } = parseJsonText(configFilename, configFileContent);
|
||||
const parsedCommandLine = parseJsonNodeConfigFileContent(
|
||||
node,
|
||||
const result = parseJsonText(configFilename, configFileContent);
|
||||
if (!result.endOfFileToken) {
|
||||
result.endOfFileToken = <EndOfFileToken>{ kind: SyntaxKind.EndOfFileToken };
|
||||
}
|
||||
const errors = result.parseDiagnostics;
|
||||
const parsedCommandLine = parseJsonSourceFileConfigFileContent(
|
||||
result,
|
||||
this.host,
|
||||
getDirectoryPath(configFilename),
|
||||
/*existingOptions*/ {},
|
||||
|
||||
@@ -1135,25 +1135,25 @@ namespace ts {
|
||||
|
||||
const result = parseJsonText(fileName, text);
|
||||
|
||||
if (!result.node) {
|
||||
if (!result.endOfFileToken) {
|
||||
return {
|
||||
options: {},
|
||||
typeAcquisition: {},
|
||||
files: [],
|
||||
raw: {},
|
||||
errors: realizeDiagnostics(result.errors, "\r\n")
|
||||
errors: realizeDiagnostics(result.parseDiagnostics, "\r\n")
|
||||
};
|
||||
}
|
||||
|
||||
const normalizedFileName = normalizeSlashes(fileName);
|
||||
const configFile = parseJsonNodeConfigFileContent(result.node, this.host, getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
|
||||
const configFile = parseJsonSourceFileConfigFileContent(result, this.host, getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
|
||||
|
||||
return {
|
||||
options: configFile.options,
|
||||
typeAcquisition: configFile.typeAcquisition,
|
||||
files: configFile.fileNames,
|
||||
raw: configFile.raw,
|
||||
errors: realizeDiagnostics(result.errors.concat(configFile.errors), "\r\n")
|
||||
errors: realizeDiagnostics(result.parseDiagnostics.concat(configFile.errors), "\r\n")
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user