From e0e88adfc51d8b5ddad783adcdeabd8e4b642b51 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 15 Dec 2014 18:10:35 -0800 Subject: [PATCH] Move grammar checking: variableDeclaration, variableStatements; there are still erros from incomplete grammar migration --- src/compiler/checker.ts | 89 +++++++++++++++++-- src/compiler/parser.ts | 6 +- .../initializersInDeclarations.errors.txt | 2 +- .../invalidModuleWithVarStatements.errors.txt | 6 +- .../reference/letDeclarations-es5.errors.txt | 4 +- tests/baselines/reference/varBlock.errors.txt | 12 +-- ...ariableDeclarationInStrictMode1.errors.txt | 2 +- 7 files changed, 97 insertions(+), 24 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 154908778a9..a58b8f052aa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8000,7 +8000,10 @@ module ts { // Grammar checking // TODO (yuisu) : Revisit this check once move all grammar checking if (node.kind === SyntaxKind.BindingElement) { - checkGrammarBindingElement(node); + checkGrammarEvalOrArgumentsInStrictMode(node, node.name); + } + else if (node.kind === SyntaxKind.VariableDeclaration) { + checkGrammarVariableDeclaration(node); } checkSourceElement(node.type); @@ -8059,6 +8062,9 @@ module ts { } function checkVariableStatement(node: VariableStatement) { + // Grammar checking + checkGrammarModifiers(node) || checkGrammarVariableDeclarations(node, node.declarations) || checkGrammarForDisallowedLetOrConstStatement(node); + forEach(node.declarations, checkSourceElement); } @@ -8091,7 +8097,6 @@ module ts { } function checkForInStatement(node: ForInStatement) { - // TypeScript 1.0 spec (April 2014): 5.4 // In a 'for-in' statement of the form // for (var VarDecl in Expr) Statement @@ -10132,12 +10137,6 @@ module ts { checkGrammarForOmittedArgument(node, arguments); } - function checkGrammarBindingElement(node: BindingElement) { - // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code - // and its Identifier is eval or arguments - checkGrammarEvalOrArgumentsInStrictMode(node, node.name); - } - function checkGrammarHeritageClause(node: HeritageClause): boolean { var types = node.types; if (checkGrammarForDisallowedTrailingComma(types)) { @@ -10387,6 +10386,80 @@ module ts { } } + function checkGrammarVariableDeclaration(node: VariableDeclaration) { + if (isInAmbientContext(node)) { + if (isBindingPattern(node.name)) { + return grammarErrorOnNode(node, Diagnostics.Destructuring_declarations_are_not_allowed_in_ambient_contexts); + } + if (node.initializer) { + // Error on equals token which immediate precedes the initializer + return grammarErrorAtPos(getSourceFileOfNode(node), node.initializer.pos - 1, 1, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); + } + } + else { + if (!node.initializer) { + if (isBindingPattern(node.name) && !isBindingPattern(node.parent)) { + return grammarErrorOnNode(node, Diagnostics.A_destructuring_declaration_must_have_an_initializer); + } + if (isConst(node)) { + return grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized); + } + } + } + // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code + // and its Identifier is eval or arguments + return checkGrammarEvalOrArgumentsInStrictMode(node, node.name); + } + + function checkGrammarVariableDeclarations(variableStatement: VariableStatement, declarations: NodeArray): boolean { + if (declarations) { + if (checkGrammarForDisallowedTrailingComma(declarations)) { + return true; + } + + if (!declarations.length) { + return grammarErrorAtPos(getSourceFileOfNode(variableStatement), declarations.pos, declarations.end - declarations.pos, Diagnostics.Variable_declaration_list_cannot_be_empty); + } + + var decl = declarations[0]; + if (compilerOptions.target < ScriptTarget.ES6) { + if (isLet(decl)) { + return grammarErrorOnFirstToken(decl, Diagnostics.let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); + } + else if (isConst(decl)) { + return grammarErrorOnFirstToken(decl, Diagnostics.const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); + } + } + } + } + + function allowLetAndConstDeclarations(parent: Node): boolean { + switch (parent.kind) { + case SyntaxKind.IfStatement: + case SyntaxKind.DoStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.WithStatement: + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + return false; + case SyntaxKind.LabeledStatement: + return allowLetAndConstDeclarations(parent.parent); + } + + return true; + } + + function checkGrammarForDisallowedLetOrConstStatement(node: VariableStatement) { + if (!allowLetAndConstDeclarations(node.parent)) { + if (isLet(node)) { + return grammarErrorOnNode(node, Diagnostics.let_declarations_can_only_be_declared_inside_a_block); + } + else if (isConst(node)) { + return grammarErrorOnNode(node, Diagnostics.const_declarations_can_only_be_declared_inside_a_block); + } + } + } + function isIntegerLiteral(expression: Expression): boolean { if (expression.kind === SyntaxKind.PrefixUnaryExpression) { var unaryExpression = expression; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6feeedc159c..7f73c275327 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4673,8 +4673,8 @@ module ts { //case SyntaxKind.TaggedTemplateExpression: return checkTaggedTemplateExpression(node); //case SyntaxKind.ThrowStatement: return checkThrowStatement(node); //case SyntaxKind.TypeReference: return checkTypeReference(node); - case SyntaxKind.VariableDeclaration: return checkVariableDeclaration(node); - case SyntaxKind.VariableStatement: return checkVariableStatement(node); + //case SyntaxKind.VariableDeclaration: return checkVariableDeclaration(node); + //case SyntaxKind.VariableStatement: return checkVariableStatement(node); //case SyntaxKind.WithStatement: return checkWithStatement(node); //case SyntaxKind.YieldExpression: return checkYieldExpression(node); } @@ -5333,7 +5333,7 @@ module ts { case SyntaxKind.ModuleDeclaration: //case SyntaxKind.EnumDeclaration: case SyntaxKind.ExportAssignment: - case SyntaxKind.VariableStatement: + //case SyntaxKind.VariableStatement: case SyntaxKind.FunctionDeclaration: case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.ImportDeclaration: diff --git a/tests/baselines/reference/initializersInDeclarations.errors.txt b/tests/baselines/reference/initializersInDeclarations.errors.txt index 5ab9ae5d2bc..ad92cc79281 100644 --- a/tests/baselines/reference/initializersInDeclarations.errors.txt +++ b/tests/baselines/reference/initializersInDeclarations.errors.txt @@ -1,9 +1,9 @@ tests/cases/conformance/externalModules/initializersInDeclarations.ts(5,9): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/externalModules/initializersInDeclarations.ts(6,16): 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(16,2): error TS1036: Statements are not allowed in ambient contexts. 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. diff --git a/tests/baselines/reference/invalidModuleWithVarStatements.errors.txt b/tests/baselines/reference/invalidModuleWithVarStatements.errors.txt index ad8d457670a..e0ba35c3385 100644 --- a/tests/baselines/reference/invalidModuleWithVarStatements.errors.txt +++ b/tests/baselines/reference/invalidModuleWithVarStatements.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts(4,5): error TS1044: 'public' modifier cannot appear on a module element. tests/cases/conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts(8,5): error TS1044: 'public' modifier cannot appear on a module element. -tests/cases/conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts(12,5): error TS1044: 'static' modifier cannot appear on a module element. tests/cases/conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts(16,5): error TS1044: 'static' modifier cannot appear on a module element. -tests/cases/conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts(20,5): error TS1044: 'private' modifier cannot appear on a module element. tests/cases/conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts(25,5): error TS1044: 'private' modifier cannot appear on a module element. +tests/cases/conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts(4,5): error TS1044: 'public' modifier cannot appear on a module element. +tests/cases/conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts(12,5): error TS1044: 'static' modifier cannot appear on a module element. +tests/cases/conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts(20,5): error TS1044: 'private' modifier cannot appear on a module element. ==== tests/cases/conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts (6 errors) ==== diff --git a/tests/baselines/reference/letDeclarations-es5.errors.txt b/tests/baselines/reference/letDeclarations-es5.errors.txt index 34bd93dba3c..19551e9fad5 100644 --- a/tests/baselines/reference/letDeclarations-es5.errors.txt +++ b/tests/baselines/reference/letDeclarations-es5.errors.txt @@ -1,11 +1,11 @@ +tests/cases/compiler/letDeclarations-es5.ts(10,9): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(12,9): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. tests/cases/compiler/letDeclarations-es5.ts(2,5): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. tests/cases/compiler/letDeclarations-es5.ts(3,5): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. tests/cases/compiler/letDeclarations-es5.ts(4,5): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. tests/cases/compiler/letDeclarations-es5.ts(6,5): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. tests/cases/compiler/letDeclarations-es5.ts(7,5): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. tests/cases/compiler/letDeclarations-es5.ts(8,5): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/letDeclarations-es5.ts(10,9): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/letDeclarations-es5.ts(12,9): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. ==== tests/cases/compiler/letDeclarations-es5.ts (8 errors) ==== diff --git a/tests/baselines/reference/varBlock.errors.txt b/tests/baselines/reference/varBlock.errors.txt index 0d9b5f6b1b4..6746a760a44 100644 --- a/tests/baselines/reference/varBlock.errors.txt +++ b/tests/baselines/reference/varBlock.errors.txt @@ -1,4 +1,6 @@ tests/cases/compiler/varBlock.ts(8,16): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(11,22): error TS2369: A parameter property is only allowed in a constructor implementation. +tests/cases/compiler/varBlock.ts(11,22): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. tests/cases/compiler/varBlock.ts(15,15): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/compiler/varBlock.ts(21,16): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/compiler/varBlock.ts(22,20): error TS1039: Initializers are not allowed in ambient contexts. @@ -14,10 +16,8 @@ tests/cases/compiler/varBlock.ts(33,25): error TS1039: Initializers are not allo tests/cases/compiler/varBlock.ts(34,19): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/compiler/varBlock.ts(35,25): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/compiler/varBlock.ts(35,35): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(11,22): error TS2369: A parameter property is only allowed in a constructor implementation. -tests/cases/compiler/varBlock.ts(11,22): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. tests/cases/compiler/varBlock.ts(39,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'. +tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allowed in ambient contexts. ==== tests/cases/compiler/varBlock.ts (20 errors) ==== @@ -96,7 +96,7 @@ tests/cases/compiler/varBlock.ts(39,13): error TS2403: Subsequent variable decla declare var c; declare var c = 10; - ~ -!!! error TS1039: Initializers are not allowed in ambient contexts. ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'. \ No newline at end of file +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'. + ~ +!!! error TS1039: Initializers are not allowed in ambient contexts. \ No newline at end of file diff --git a/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt b/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt index aa2ccdbed9f..328e080fbaa 100644 --- a/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt +++ b/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/variableDeclarationInStrictMode1.ts(2,5): error TS1100: Invalid use of 'eval' in strict mode. lib.d.ts(29,18): error TS2300: Duplicate identifier 'eval'. +tests/cases/compiler/variableDeclarationInStrictMode1.ts(2,5): error TS1100: Invalid use of 'eval' in strict mode. tests/cases/compiler/variableDeclarationInStrictMode1.ts(2,5): error TS2300: Duplicate identifier 'eval'.