diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 825f2c632e7..08378374c9b 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1056,11 +1056,11 @@ namespace ts { errors: Push, knownRootOptions: Map | undefined, jsonConversionNotifier: JsonConversionNotifier | undefined): any { - if (!sourceFile.jsonObject) { + if (!sourceFile.statements.length) { return {}; } - return convertObjectLiteralExpressionToJson(sourceFile.jsonObject, knownRootOptions, + return convertObjectLiteralExpressionToJson(sourceFile.statements[0].expression, knownRootOptions, /*extraKeyDiagnosticMessage*/ undefined, /*parentOption*/ undefined); function convertObjectLiteralExpressionToJson( @@ -2092,8 +2092,8 @@ namespace ts { }); function createDiagnostic(message: DiagnosticMessage, spec: string): Diagnostic { - if (jsonSourceFile && jsonSourceFile.jsonObject) { - for (const property of getPropertyAssignment(jsonSourceFile.jsonObject, specKey)) { + if (jsonSourceFile && jsonSourceFile.statements.length) { + for (const property of getPropertyAssignment(jsonSourceFile.statements[0].expression, specKey)) { if (isArrayLiteralExpression(property.initializer)) { for (const element of property.initializer.elements) { if (isStringLiteral(element) && element.text === spec) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 813a77d71a6..9eaab774a1b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -260,7 +260,6 @@ namespace ts { return visitNodes(cbNode, cbNodes, (node).statements); case SyntaxKind.SourceFile: return visitNodes(cbNode, cbNodes, (node).statements) || - visitNode(cbNode, (node).jsonObject) || visitNode(cbNode, (node).endOfFileToken); case SyntaxKind.VariableStatement: return visitNodes(cbNode, cbNodes, node.decorators) || @@ -663,7 +662,6 @@ namespace ts { scriptKind = ensureScriptKind(fileName, scriptKind); if (scriptKind === ScriptKind.JSON) { const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes); - result.statements = emptyArray; result.typeReferenceDirectives = emptyArray; result.amdDependencies = emptyArray; return result; @@ -693,22 +691,30 @@ namespace ts { initializeState(sourceText, languageVersion, syntaxCursor, ScriptKind.JSON); // Set source file so that errors will be reported with this file name sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false); - const result = sourceFile; + const result = sourceFile as JsonSourceFile; // Prime the scanner. nextToken(); + const pos = getNodePos(); if (token() === SyntaxKind.EndOfFileToken) { sourceFile.endOfFileToken = parseTokenNode(); } else if (token() === SyntaxKind.OpenBraceToken || lookAhead(() => token() === SyntaxKind.StringLiteral)) { - result.jsonObject = parseObjectLiteralExpression(); + const statement = createNode(SyntaxKind.ExpressionStatement) as JsonObjectLiteralExpressionStatement; + statement.expression = parseObjectLiteralExpression(); + finishNode(statement); + sourceFile.statements = createNodeArray([statement], pos); sourceFile.endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token); } else { parseExpected(SyntaxKind.OpenBraceToken); } + if (!sourceFile.statements) { + sourceFile.statements = createNodeArray([], pos, pos); + } + if (setParentNodes) { fixupParentReferences(sourceFile); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 0f2cb34ec21..b2ea3467916 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2333,8 +2333,8 @@ namespace ts { function getCompilerOptionsObjectLiteralSyntax() { if (_compilerOptionsObjectLiteralSyntax === undefined) { _compilerOptionsObjectLiteralSyntax = null; // tslint:disable-line:no-null-keyword - if (options.configFile && options.configFile.jsonObject) { - for (const prop of getPropertyAssignment(options.configFile.jsonObject, "compilerOptions")) { + if (options.configFile && options.configFile.statements.length) { + for (const prop of getPropertyAssignment(options.configFile.statements[0].expression, "compilerOptions")) { if (isObjectLiteralExpression(prop.initializer)) { _compilerOptionsObjectLiteralSyntax = prop.initializer; break; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0e1f08a69d8..d550bf9704f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2576,10 +2576,14 @@ namespace ts { } export interface JsonSourceFile extends SourceFile { - jsonObject?: ObjectLiteralExpression; + statements: NodeArray; extendedSourceFiles?: string[]; } + export interface JsonObjectLiteralExpressionStatement extends ExpressionStatement { + expression: ObjectLiteralExpression; + } + export interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; getSourceFile(fileName: string): SourceFile | undefined; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ee3bd07d280..29ed483e632 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1631,9 +1631,12 @@ declare namespace ts { sourceFiles: ReadonlyArray; } interface JsonSourceFile extends SourceFile { - jsonObject?: ObjectLiteralExpression; + statements: NodeArray; extendedSourceFiles?: string[]; } + interface JsonObjectLiteralExpressionStatement extends ExpressionStatement { + expression: ObjectLiteralExpression; + } interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; getSourceFile(fileName: string): SourceFile | undefined; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 0075da06668..430cfb9c444 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1631,9 +1631,12 @@ declare namespace ts { sourceFiles: ReadonlyArray; } interface JsonSourceFile extends SourceFile { - jsonObject?: ObjectLiteralExpression; + statements: NodeArray; extendedSourceFiles?: string[]; } + interface JsonObjectLiteralExpressionStatement extends ExpressionStatement { + expression: ObjectLiteralExpression; + } interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; getSourceFile(fileName: string): SourceFile | undefined; diff --git a/tests/baselines/reference/requireOfJsonFile.js b/tests/baselines/reference/requireOfJsonFile.js index b3b37406830..6b9ca773707 100644 --- a/tests/baselines/reference/requireOfJsonFile.js +++ b/tests/baselines/reference/requireOfJsonFile.js @@ -16,6 +16,10 @@ if (x) { } //// [b.js] +{ + "a": true, + "b": "hello" +}; //// [file1.js] "use strict"; exports.__esModule = true;