diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index eddf40cc94b..c545cca8628 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1049,19 +1049,21 @@ namespace ts { * Convert the json syntax tree into the json value */ export function convertToObject(sourceFile: JsonSourceFile, errors: Push): any { - return convertToObjectWorker(sourceFile, errors, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); + return convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); } /** - * Convert the json syntax tree into the json value + * Convert the json syntax tree into the json value and report errors */ - function convertToObjectWorker( + /*@internal*/ + export function convertToObjectWorker( sourceFile: JsonSourceFile, errors: Push, + returnValue: boolean, knownRootOptions: CommandLineOption | undefined, jsonConversionNotifier: JsonConversionNotifier | undefined): any { if (!sourceFile.statements.length) { - return {}; + return returnValue ? {} : undefined; } return convertPropertyValueToJson(sourceFile.statements[0].expression, knownRootOptions); @@ -1076,7 +1078,7 @@ namespace ts { extraKeyDiagnosticMessage: DiagnosticMessage | undefined, parentOption: string | undefined ): any { - const result: any = {}; + const result: any = returnValue ? {} : undefined; for (const element of node.properties) { if (element.kind !== SyntaxKind.PropertyAssignment) { errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element, Diagnostics.Property_assignment_expected)); @@ -1097,7 +1099,9 @@ namespace ts { } const value = convertPropertyValueToJson(element.initializer, option); if (typeof keyText !== "undefined") { - result[keyText] = value; + if (returnValue) { + result[keyText] = value; + } // Notify key value set, if user asked for it if (jsonConversionNotifier && // Current callbacks are only on known parent option or if we are setting values in the root @@ -1128,8 +1132,8 @@ namespace ts { function convertArrayLiteralExpressionToJson( elements: NodeArray, elementOption: CommandLineOption | undefined - ): any[] { - return elements.map(element => convertPropertyValueToJson(element, elementOption)); + ): any[] | void { + return (returnValue ? elements.map : elements.forEach).call(elements, (element: Expression) => convertPropertyValueToJson(element, elementOption)); } function convertPropertyValueToJson(valueExpression: Expression, option: CommandLineOption): any { @@ -1693,7 +1697,7 @@ namespace ts { } } }; - const json = convertToObjectWorker(sourceFile, errors, getTsconfigRootOptionsMap(), optionsIterator); + const json = convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, getTsconfigRootOptionsMap(), optionsIterator); if (!typeAcquisition) { if (typingOptionstypeAcquisition) { typeAcquisition = (typingOptionstypeAcquisition.enableAutoDiscovery !== undefined) ? diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 774e9d42578..2cfc36ab911 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -662,6 +662,7 @@ namespace ts { scriptKind = ensureScriptKind(fileName, scriptKind); if (scriptKind === ScriptKind.JSON) { const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes); + convertToObjectWorker(result, result.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); result.typeReferenceDirectives = emptyArray; result.amdDependencies = emptyArray; return result; diff --git a/tests/baselines/reference/requireOfJsonFileWithErrors.errors.txt b/tests/baselines/reference/requireOfJsonFileWithErrors.errors.txt new file mode 100644 index 00000000000..bac48b2f2c0 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithErrors.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/b.json(2,5): error TS1327: String literal with double quotes expected. + + +==== tests/cases/compiler/file1.ts (0 errors) ==== + import b1 = require('./b.json'); + let x = b1.a; + import b2 = require('./b.json'); + if (x) { + let b = b2.b; + x = (b1.b === b); + } + +==== tests/cases/compiler/b.json (1 errors) ==== + { + 'a': true, + ~~~ +!!! error TS1327: String literal with double quotes expected. + "b": "hello" + } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithErrors.js b/tests/baselines/reference/requireOfJsonFileWithErrors.js new file mode 100644 index 00000000000..9f987ff3d8a --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithErrors.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/requireOfJsonFileWithErrors.ts] //// + +//// [file1.ts] +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + 'a': true, + "b": "hello" +} + +//// [b.json] +{ + 'a': true, + "b": "hello" +} +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b.json"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithErrors.symbols b/tests/baselines/reference/requireOfJsonFileWithErrors.symbols new file mode 100644 index 00000000000..43e877cbed2 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithErrors.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.a : Symbol('a', Decl(b.json, 0, 1)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>a : Symbol('a', Decl(b.json, 0, 1)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(b.json, 1, 14)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(b.json, 1, 14)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.b : Symbol("b", Decl(b.json, 1, 14)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === +{ + 'a': true, +>'a' : Symbol('a', Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithErrors.types b/tests/baselines/reference/requireOfJsonFileWithErrors.types new file mode 100644 index 00000000000..35893282bee --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithErrors.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : { 'a': boolean; "b": string; } + +let x = b1.a; +>x : boolean +>b1.a : boolean +>b1 : { 'a': boolean; "b": string; } +>a : boolean + +import b2 = require('./b.json'); +>b2 : { 'a': boolean; "b": string; } + +if (x) { +>x : boolean + + let b = b2.b; +>b : string +>b2.b : string +>b2 : { 'a': boolean; "b": string; } +>b : string + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : boolean +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : string +>b1 : { 'a': boolean; "b": string; } +>b : string +>b : string +} + +=== tests/cases/compiler/b.json === +{ +>{ 'a': true, "b": "hello"} : { 'a': boolean; "b": string; } + + 'a': true, +>'a' : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/cases/compiler/requireOfJsonFileWithErrors.ts b/tests/cases/compiler/requireOfJsonFileWithErrors.ts new file mode 100644 index 00000000000..ad853e183b5 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithErrors.ts @@ -0,0 +1,18 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true + +// @Filename: file1.ts +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + 'a': true, + "b": "hello" +} \ No newline at end of file