@@ -1767,11 +1767,35 @@ namespace ts {
1767
1767
onSetUnknownOptionKeyValueInRoot ( key : string , keyNode : PropertyName , value : CompilerOptionsValue , valueNode : Expression ) : void ;
1768
1768
}
1769
1769
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
+
1770
1794
/**
1771
1795
* Convert the json syntax tree into the json value
1772
1796
*/
1773
1797
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 ) ;
1775
1799
}
1776
1800
1777
1801
/**
@@ -1782,33 +1806,15 @@ namespace ts {
1782
1806
/*@internal */
1783
1807
export function convertToObjectWorker (
1784
1808
sourceFile : JsonSourceFile ,
1809
+ rootExpression : Expression | undefined ,
1785
1810
errors : Push < Diagnostic > ,
1786
1811
returnValue : boolean ,
1787
1812
knownRootOptions : CommandLineOption | undefined ,
1788
1813
jsonConversionNotifier : JsonConversionNotifier | undefined ) : any {
1789
- if ( ! sourceFile . statements . length ) {
1814
+ if ( ! rootExpression ) {
1790
1815
return returnValue ? { } : undefined ;
1791
1816
}
1792
1817
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
- }
1812
1818
return convertPropertyValueToJson ( rootExpression , knownRootOptions ) ;
1813
1819
1814
1820
function isRootOptionMap ( knownOptions : ESMap < string , CommandLineOption > | undefined ) {
@@ -2752,7 +2758,7 @@ namespace ts {
2752
2758
}
2753
2759
}
2754
2760
} ;
2755
- const json = convertToObjectWorker ( sourceFile , errors , /*returnValue*/ true , getTsconfigRootOptionsMap ( ) , optionsIterator ) ;
2761
+ const json = convertConfigFileToObject ( sourceFile , errors , optionsIterator ) ;
2756
2762
2757
2763
if ( ! typeAcquisition ) {
2758
2764
if ( typingOptionstypeAcquisition ) {
0 commit comments