From 5a7929aec7451fe255535f6234bd63a396cee6ed Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 18 Nov 2014 22:37:31 -0800 Subject: [PATCH] Move variable grammar checks to the grammar checker. --- src/compiler/parser.ts | 34 ++++++++++++------- .../reference/ambientErrors.errors.txt | 8 +---- .../reference/ambientErrors1.errors.txt | 7 ++++ .../initializersInDeclarations.errors.txt | 11 +----- .../missingRequiredDeclare.d.errors.txt | 7 ++-- .../parserVariableStatement1.d.errors.txt | 7 ++-- tests/cases/compiler/ambientErrors1.ts | 1 + 7 files changed, 35 insertions(+), 40 deletions(-) create mode 100644 tests/baselines/reference/ambientErrors1.errors.txt create mode 100644 tests/cases/compiler/ambientErrors1.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6ce63e1a4da..1cc5e09d680 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1005,7 +1005,6 @@ module ts { grammarErrorOnNode(node, Diagnostics.Invalid_use_of_0_in_strict_mode, name); } - function grammarErrorAtPos(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { file._parserDiagnostics.push(createFileDiagnostic(file, start, length, message, arg0, arg1, arg2)); } @@ -3292,7 +3291,6 @@ module ts { function parseVariableDeclaration(flags: NodeFlags, noIn?: boolean): VariableDeclaration { var node = createNode(SyntaxKind.VariableDeclaration); node.flags = flags; - var errorCountBeforeVariableDeclaration = file._parserDiagnostics.length; node.name = parseIdentifier(); node.type = parseTypeAnnotation(); @@ -3301,17 +3299,6 @@ module ts { var initializerFirstTokenLength = scanner.getTextPos() - initializerStart; node.initializer = parseInitializer(/*inParameter*/ false, noIn); - if (inAmbientContext && node.initializer && errorCountBeforeVariableDeclaration === file._parserDiagnostics.length) { - grammarErrorAtPos(initializerStart, initializerFirstTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); - } - if (!inAmbientContext && !node.initializer && flags & NodeFlags.Const) { - grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized); - } - if (isInStrictMode && isEvalOrArgumentsIdentifier(node.name)) { - // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code - // and its Identifier is eval or arguments - reportInvalidUseInStrictMode(node.name); - } return finishNode(node); } @@ -4147,6 +4134,7 @@ module ts { case SyntaxKind.PrefixOperator: return visitPrefixOperator(node); case SyntaxKind.SetAccessor: return visitSetAccessor(node); case SyntaxKind.TaggedTemplateExpression: return visitTaggedTemplateExpression(node); + case SyntaxKind.VariableDeclaration: return visitVariableDeclaration(node); } } @@ -4159,6 +4147,11 @@ module ts { return true; } + function grammarErrorAtPos(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + file._syntacticDiagnostics.push(createFileDiagnostic(file, start, length, message, arg0, arg1, arg2)); + return true; + } + function reportInvalidUseInStrictMode(node: Identifier): boolean { // declarationNameToString cannot be used here since it uses a backreference to 'parent' that is not yet set var name = sourceText.substring(skipTrivia(sourceText, node.pos), node.end); @@ -4479,6 +4472,21 @@ module ts { grammarErrorOnNode(node, Diagnostics.Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher); } } + + function visitVariableDeclaration(node: VariableDeclaration) { + if (inAmbientContext && node.initializer) { + var equalsPos = node.type ? skipTrivia(sourceText, node.type.end) : skipTrivia(sourceText, node.name.end); + grammarErrorAtPos(equalsPos, "=".length, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); + } + if (!inAmbientContext && !node.initializer && node.flags & NodeFlags.Const) { + grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized); + } + if (node.flags & NodeFlags.ParsedInStrictMode && isEvalOrArgumentsIdentifier(node.name)) { + // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code + // and its Identifier is eval or arguments + reportInvalidUseInStrictMode(node.name); + } + } } export function createProgram(rootNames: string[], options: CompilerOptions, host: CompilerHost): Program { diff --git a/tests/baselines/reference/ambientErrors.errors.txt b/tests/baselines/reference/ambientErrors.errors.txt index 618829c8bd9..e89586275a3 100644 --- a/tests/baselines/reference/ambientErrors.errors.txt +++ b/tests/baselines/reference/ambientErrors.errors.txt @@ -1,6 +1,4 @@ -tests/cases/conformance/ambient/ambientErrors.ts(2,15): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/ambient/ambientErrors.ts(20,24): error TS1037: A function implementation cannot be declared in an ambient context. -tests/cases/conformance/ambient/ambientErrors.ts(34,11): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/ambient/ambientErrors.ts(35,19): error TS1037: A function implementation cannot be declared in an ambient context. tests/cases/conformance/ambient/ambientErrors.ts(37,18): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/ambient/ambientErrors.ts(38,11): error TS1039: Initializers are not allowed in ambient contexts. @@ -14,11 +12,9 @@ tests/cases/conformance/ambient/ambientErrors.ts(51,16): error TS2436: Ambient e tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export assignment cannot be used in a module with other exported elements. -==== tests/cases/conformance/ambient/ambientErrors.ts (14 errors) ==== +==== tests/cases/conformance/ambient/ambientErrors.ts (12 errors) ==== // Ambient variable with an initializer declare var x = 4; - ~ -!!! error TS1039: Initializers are not allowed in ambient contexts. // Ambient functions with invalid overloads declare function fn(x: number): string; @@ -57,8 +53,6 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export // Ambient module with initializers for values, bodies for functions / classes declare module M1 { var x = 3; - ~ -!!! error TS1039: Initializers are not allowed in ambient contexts. function fn() { } ~ !!! error TS1037: A function implementation cannot be declared in an ambient context. diff --git a/tests/baselines/reference/ambientErrors1.errors.txt b/tests/baselines/reference/ambientErrors1.errors.txt new file mode 100644 index 00000000000..db7a155cc3f --- /dev/null +++ b/tests/baselines/reference/ambientErrors1.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/ambientErrors1.ts(1,15): error TS1039: Initializers are not allowed in ambient contexts. + + +==== tests/cases/compiler/ambientErrors1.ts (1 errors) ==== + declare var x = 4; + ~ +!!! error TS1039: Initializers are not allowed in ambient contexts. \ No newline at end of file diff --git a/tests/baselines/reference/initializersInDeclarations.errors.txt b/tests/baselines/reference/initializersInDeclarations.errors.txt index 94736957365..49a06cf9a29 100644 --- a/tests/baselines/reference/initializersInDeclarations.errors.txt +++ b/tests/baselines/reference/initializersInDeclarations.errors.txt @@ -1,13 +1,10 @@ tests/cases/conformance/externalModules/initializersInDeclarations.ts(5,7): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/externalModules/initializersInDeclarations.ts(6,14): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/externalModules/initializersInDeclarations.ts(7,16): error TS1037: A function implementation cannot be declared in an ambient context. -tests/cases/conformance/externalModules/initializersInDeclarations.ts(12,15): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/conformance/externalModules/initializersInDeclarations.ts(13,15): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/externalModules/initializersInDeclarations.ts(16,2): error TS1036: Statements are not allowed in ambient contexts. -tests/cases/conformance/externalModules/initializersInDeclarations.ts(18,16): error TS1039: Initializers are not allowed in ambient contexts. -==== tests/cases/conformance/externalModules/initializersInDeclarations.ts (7 errors) ==== +==== tests/cases/conformance/externalModules/initializersInDeclarations.ts (4 errors) ==== // Errors: Initializers & statements in declaration file @@ -26,11 +23,7 @@ tests/cases/conformance/externalModules/initializersInDeclarations.ts(18,16): er } declare var x = []; - ~ -!!! error TS1039: Initializers are not allowed in ambient contexts. declare var y = {}; - ~ -!!! error TS1039: Initializers are not allowed in ambient contexts. declare module M1 { while(true); @@ -38,6 +31,4 @@ tests/cases/conformance/externalModules/initializersInDeclarations.ts(18,16): er !!! error TS1036: Statements are not allowed in ambient contexts. export var v1 = () => false; - ~ -!!! error TS1039: Initializers are not allowed in ambient contexts. } \ No newline at end of file diff --git a/tests/baselines/reference/missingRequiredDeclare.d.errors.txt b/tests/baselines/reference/missingRequiredDeclare.d.errors.txt index dc713c86d89..1e52fa92fe5 100644 --- a/tests/baselines/reference/missingRequiredDeclare.d.errors.txt +++ b/tests/baselines/reference/missingRequiredDeclare.d.errors.txt @@ -1,10 +1,7 @@ tests/cases/compiler/missingRequiredDeclare.d.ts(1,1): error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. -tests/cases/compiler/missingRequiredDeclare.d.ts(1,7): error TS1039: Initializers are not allowed in ambient contexts. -==== tests/cases/compiler/missingRequiredDeclare.d.ts (2 errors) ==== +==== tests/cases/compiler/missingRequiredDeclare.d.ts (1 errors) ==== var x = 1; ~~~ -!!! error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. - ~ -!!! error TS1039: Initializers are not allowed in ambient contexts. \ No newline at end of file +!!! error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. \ No newline at end of file diff --git a/tests/baselines/reference/parserVariableStatement1.d.errors.txt b/tests/baselines/reference/parserVariableStatement1.d.errors.txt index de0bef5288c..7176e5ed69f 100644 --- a/tests/baselines/reference/parserVariableStatement1.d.errors.txt +++ b/tests/baselines/reference/parserVariableStatement1.d.errors.txt @@ -1,10 +1,7 @@ tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts(1,1): error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. -tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts(1,7): error TS1039: Initializers are not allowed in ambient contexts. -==== tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts (1 errors) ==== var v = 1; ~~~ -!!! error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. - ~ -!!! error TS1039: Initializers are not allowed in ambient contexts. \ No newline at end of file +!!! error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. \ No newline at end of file diff --git a/tests/cases/compiler/ambientErrors1.ts b/tests/cases/compiler/ambientErrors1.ts new file mode 100644 index 00000000000..ef249266498 --- /dev/null +++ b/tests/cases/compiler/ambientErrors1.ts @@ -0,0 +1 @@ +declare var x = 4; \ No newline at end of file