Skip to content

Commit b6a2f39

Browse files
committed
Move tsconfig root checking out of common JSON checking function
1 parent 98e8d8d commit b6a2f39

File tree

2 files changed

+29
-23
lines changed

2 files changed

+29
-23
lines changed

src/compiler/commandLineParser.ts

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,11 +1767,35 @@ namespace ts {
17671767
onSetUnknownOptionKeyValueInRoot(key: string, keyNode: PropertyName, value: CompilerOptionsValue, valueNode: Expression): void;
17681768
}
17691769

1770+
function convertConfigFileToObject(sourceFile: JsonSourceFile, errors: Push<Diagnostic>, optionsIterator: JsonConversionNotifier): any {
1771+
const rootExpression: Expression | undefined = sourceFile.statements[0]?.expression;
1772+
const knownRootOptions = getTsconfigRootOptionsMap();
1773+
if (rootExpression && rootExpression.kind !== SyntaxKind.ObjectLiteralExpression) {
1774+
errors.push(createDiagnosticForNodeInSourceFile(
1775+
sourceFile,
1776+
rootExpression,
1777+
Diagnostics.The_root_value_of_a_0_file_must_be_an_object,
1778+
getBaseFileName(sourceFile.fileName) === "jsconfig.json" ? "jsconfig.json" : "tsconfig.json"
1779+
));
1780+
// Last-ditch error recovery. Somewhat useful because the JSON parser will recover from some parse errors by
1781+
// synthesizing a top-level array literal expression. There's a reasonable chance the first element of that
1782+
// array is a well-formed configuration object, made into an array element by stray characters.
1783+
if (isArrayLiteralExpression(rootExpression)) {
1784+
const firstObject = find(rootExpression.elements, isObjectLiteralExpression);
1785+
if (firstObject) {
1786+
return convertToObjectWorker(sourceFile, firstObject, errors, /*returnValue*/ true, knownRootOptions, optionsIterator);
1787+
}
1788+
}
1789+
return {};
1790+
}
1791+
return convertToObjectWorker(sourceFile, rootExpression, errors, /*returnValue*/ true, knownRootOptions, optionsIterator);
1792+
}
1793+
17701794
/**
17711795
* Convert the json syntax tree into the json value
17721796
*/
17731797
export function convertToObject(sourceFile: JsonSourceFile, errors: Push<Diagnostic>): any {
1774-
return convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
1798+
return convertToObjectWorker(sourceFile, sourceFile.statements[0]?.expression, errors, /*returnValue*/ true, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
17751799
}
17761800

17771801
/**
@@ -1782,33 +1806,15 @@ namespace ts {
17821806
/*@internal*/
17831807
export function convertToObjectWorker(
17841808
sourceFile: JsonSourceFile,
1809+
rootExpression: Expression | undefined,
17851810
errors: Push<Diagnostic>,
17861811
returnValue: boolean,
17871812
knownRootOptions: CommandLineOption | undefined,
17881813
jsonConversionNotifier: JsonConversionNotifier | undefined): any {
1789-
if (!sourceFile.statements.length) {
1814+
if (!rootExpression) {
17901815
return returnValue ? {} : undefined;
17911816
}
17921817

1793-
const rootExpression: Expression = sourceFile.statements[0].expression;
1794-
if (rootExpression.kind !== SyntaxKind.ObjectLiteralExpression) {
1795-
errors.push(createDiagnosticForNodeInSourceFile(
1796-
sourceFile,
1797-
rootExpression,
1798-
Diagnostics.The_root_value_of_a_0_file_must_be_an_object,
1799-
getBaseFileName(sourceFile.fileName) === "jsconfig.json" ? "jsconfig.json" : "tsconfig.json"
1800-
));
1801-
// Last-ditch error recovery. Somewhat useful because the JSON parser will recover from some parse errors by
1802-
// synthesizing a top-level array literal expression. There's a reasonable chance the first element of that
1803-
// array is a well-formed configuration object, made into an array element by stray characters.
1804-
if (isArrayLiteralExpression(rootExpression)) {
1805-
const firstObject = find(rootExpression.elements, isObjectLiteralExpression);
1806-
if (firstObject) {
1807-
return convertPropertyValueToJson(firstObject, knownRootOptions);
1808-
}
1809-
}
1810-
return returnValue ? {} : undefined;
1811-
}
18121818
return convertPropertyValueToJson(rootExpression, knownRootOptions);
18131819

18141820
function isRootOptionMap(knownOptions: ESMap<string, CommandLineOption> | undefined) {
@@ -2752,7 +2758,7 @@ namespace ts {
27522758
}
27532759
}
27542760
};
2755-
const json = convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, getTsconfigRootOptionsMap(), optionsIterator);
2761+
const json = convertConfigFileToObject(sourceFile, errors, optionsIterator);
27562762

27572763
if (!typeAcquisition) {
27582764
if (typingOptionstypeAcquisition) {

src/compiler/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ namespace ts {
819819
scriptKind = ensureScriptKind(fileName, scriptKind);
820820
if (scriptKind === ScriptKind.JSON) {
821821
const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes);
822-
convertToObjectWorker(result, result.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
822+
convertToObjectWorker(result, result.statements[0]?.expression, result.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
823823
result.referencedFiles = emptyArray;
824824
result.typeReferenceDirectives = emptyArray;
825825
result.libReferenceDirectives = emptyArray;

0 commit comments

Comments
 (0)