From 593dc2bc9f2efefe91b115ca2b040e8b037e0b26 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 11 Apr 2016 12:04:55 -0700 Subject: [PATCH] Report error for block scope function declaration in ES5 --- src/compiler/binder.ts | 30 +++++++++++++++++++ src/compiler/diagnosticMessages.json | 12 ++++++++ ...pedFunctionDeclarationStrictES5.errors.txt | 5 +++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 1a31030c09e..8e1b779126a 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1125,6 +1125,35 @@ namespace ts { } } + function getStrictModeBlockScopeFunctionDeclarationMessage(node: Node) { + // Provide specialized messages to help the user understand why we think they're in + // strict mode. + if (getContainingClass(node)) { + return Diagnostics.In_ES5_or_lower_function_declarations_are_not_allowed_in_block_scope_Class_definitions_are_automatically_in_strict_mode; + } + + if (file.externalModuleIndicator) { + return Diagnostics.In_ES5_or_lower_function_declarations_are_not_allowed_in_block_scope_Modules_are_automatically_in_strict_mode; + } + + return Diagnostics.In_ES5_or_lower_function_declarations_are_not_allowed_in_block_scope_in_strict_mode; + } + + function checkStrictModeFunctionDeclaration(node: FunctionDeclaration) { + if (getEmitScriptTarget(options) < ScriptTarget.ES6) { + // Report error if function is not top level function declaration + if (blockScopeContainer.kind !== SyntaxKind.SourceFile && + blockScopeContainer.kind !== SyntaxKind.ModuleDeclaration && + !isFunctionLike(blockScopeContainer)) { + // We check first if the name is inside class declaration or class expression; if so give explicit message + // otherwise report generic error message. + const errorSpan = getErrorSpanForNode(file, node); + file.bindDiagnostics.push(createFileDiagnostic(file, errorSpan.start, errorSpan.length, + getStrictModeBlockScopeFunctionDeclarationMessage(node))); + } + } + } + function checkStrictModeNumericLiteral(node: LiteralExpression) { if (inStrictMode && node.isOctalLiteral) { file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode)); @@ -1641,6 +1670,7 @@ namespace ts { checkStrictModeFunctionName(node); if (inStrictMode) { + checkStrictModeFunctionDeclaration(node); bindBlockScopedDeclaration(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); } else { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 793118d008b..e8425afc096 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -811,6 +811,18 @@ "category": "Error", "code": 1249 }, + "In ES5 or lower, function declarations are not allowed in block scope in strict mode.": { + "category": "Error", + "code": 1250 + }, + "In ES5 or lower, function declarations are not allowed in block scope. Class definitions are automatically in strict mode.": { + "category": "Error", + "code": 1251 + }, + "In ES5 or lower, function declarations are not allowed in block scope. Modules are automatically in strict mode.": { + "category": "Error", + "code": 1252 + }, "'with' statements are not allowed in an async function block.": { "category": "Error", "code": 1300 diff --git a/tests/baselines/reference/blockScopedFunctionDeclarationStrictES5.errors.txt b/tests/baselines/reference/blockScopedFunctionDeclarationStrictES5.errors.txt index d86b1e02953..e9c833b5d42 100644 --- a/tests/baselines/reference/blockScopedFunctionDeclarationStrictES5.errors.txt +++ b/tests/baselines/reference/blockScopedFunctionDeclarationStrictES5.errors.txt @@ -1,10 +1,13 @@ +tests/cases/compiler/blockScopedFunctionDeclarationStrictES5.ts(3,14): error TS1250: In ES5 or lower, function declarations are not allowed in block scope in strict mode. tests/cases/compiler/blockScopedFunctionDeclarationStrictES5.ts(6,1): error TS2304: Cannot find name 'foo'. -==== tests/cases/compiler/blockScopedFunctionDeclarationStrictES5.ts (1 errors) ==== +==== tests/cases/compiler/blockScopedFunctionDeclarationStrictES5.ts (2 errors) ==== "use strict"; if (true) { function foo() { } // Error to declare function in block scope + ~~~ +!!! error TS1250: In ES5 or lower, function declarations are not allowed in block scope in strict mode. foo(); // This call should be ok } foo(); // Error to find name foo