mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
show error if block scoped variable declared in the loop is captured in closure
This commit is contained in:
@@ -4905,10 +4905,55 @@ module ts {
|
||||
|
||||
checkCollisionWithCapturedSuperVariable(node, node);
|
||||
checkCollisionWithCapturedThisVariable(node, node);
|
||||
checkBlockScopedBindingCapturedInLoop(node, symbol);
|
||||
|
||||
return getNarrowedTypeOfSymbol(getExportSymbolOfValueSymbolIfExported(symbol), node);
|
||||
}
|
||||
|
||||
function isNameScopeBoundary(n: Node): boolean {
|
||||
return isAnyFunction(n) || n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.SourceFile;
|
||||
}
|
||||
|
||||
function checkBlockScopedBindingCapturedInLoop(node: Identifier, symbol: Symbol): void {
|
||||
if (languageVersion >= ScriptTarget.ES6 || (symbol.flags & SymbolFlags.BlockScopedVariable) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// - check if binding is used in some function
|
||||
// (stop the walk when reaching container of binding declaration)
|
||||
// - if first check succeeded - check if variable is declared inside the loop
|
||||
|
||||
// var decl -> var decl list -> parent
|
||||
var container = (<VariableDeclaration>symbol.valueDeclaration).parent.parent;
|
||||
if (container.kind === SyntaxKind.VariableStatement) {
|
||||
container = container.parent;
|
||||
}
|
||||
|
||||
var inFunction = false;
|
||||
var current = node.parent;
|
||||
while (current && current !== container) {
|
||||
if (isAnyFunction(current)) {
|
||||
inFunction = true;
|
||||
break;
|
||||
}
|
||||
current = current.parent;
|
||||
}
|
||||
|
||||
if (!inFunction) {
|
||||
return;
|
||||
}
|
||||
|
||||
var current: Node = container;
|
||||
while (current && !isNameScopeBoundary(current)) {
|
||||
if (isIterationStatement(current, /*lookInLabeledStatements*/ false)) {
|
||||
getNodeLinks(current).flags |= NodeCheckFlags.BlockScopedBindingCapturedInLoop;
|
||||
grammarErrorOnFirstToken(current, Diagnostics.Code_in_the_loop_captures_block_scoped_variable_0_in_closure_This_is_natively_supported_in_ECMAScript_6_or_higher, declarationNameToString(node));
|
||||
break;
|
||||
}
|
||||
current = current.parent;
|
||||
}
|
||||
}
|
||||
|
||||
function captureLexicalThis(node: Node, container: Node): void {
|
||||
var classNode = container.parent && container.parent.kind === SyntaxKind.ClassDeclaration ? container.parent : undefined;
|
||||
getNodeLinks(node).flags |= NodeCheckFlags.LexicalThis;
|
||||
|
||||
@@ -382,6 +382,7 @@ module ts {
|
||||
Property_0_does_not_exist_on_const_enum_1: { code: 4088, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on 'const' enum '{1}'." },
|
||||
let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: { code: 4089, category: DiagnosticCategory.Error, key: "'let' is not allowed to be used as a name in 'let' or 'const' declarations." },
|
||||
Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: { code: 4090, category: DiagnosticCategory.Error, key: "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'." },
|
||||
Code_in_the_loop_captures_block_scoped_variable_0_in_closure_This_is_natively_supported_in_ECMAScript_6_or_higher: { code: 4091, category: DiagnosticCategory.Error, key: "Code in the loop captures block-scoped variable '{0}' in closure. This is natively supported in ECMAScript 6 or higher." },
|
||||
The_current_host_does_not_support_the_0_option: { code: 5001, category: DiagnosticCategory.Error, key: "The current host does not support the '{0}' option." },
|
||||
Cannot_find_the_common_subdirectory_path_for_the_input_files: { code: 5009, category: DiagnosticCategory.Error, key: "Cannot find the common subdirectory path for the input files." },
|
||||
Cannot_read_file_0_Colon_1: { code: 5012, category: DiagnosticCategory.Error, key: "Cannot read file '{0}': {1}" },
|
||||
|
||||
@@ -1521,6 +1521,10 @@
|
||||
"category": "Error",
|
||||
"code": 4090
|
||||
},
|
||||
"Code in the loop captures block-scoped variable '{0}' in closure. This is natively supported in ECMAScript 6 or higher.": {
|
||||
"category": "Error",
|
||||
"code": 4091
|
||||
},
|
||||
"The current host does not support the '{0}' option.": {
|
||||
"category": "Error",
|
||||
"code": 5001
|
||||
|
||||
@@ -1262,6 +1262,7 @@ module ts {
|
||||
|
||||
// Values for enum members have been computed, and any errors have been reported for them.
|
||||
EnumValuesComputed = 0x00000080,
|
||||
BlockScopedBindingCapturedInLoop = 0x00000100,
|
||||
}
|
||||
|
||||
export interface NodeLinks {
|
||||
|
||||
Reference in New Issue
Block a user