mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
consider binding elements as always initialized with doing shadow check
This commit is contained in:
+38
-27
@@ -8609,36 +8609,47 @@ module ts {
|
||||
// const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration
|
||||
// var x = 0; // symbol for this declaration will be 'symbol'
|
||||
// }
|
||||
if (node.initializer && (getCombinedNodeFlags(node) & NodeFlags.BlockScoped) === 0) {
|
||||
var symbol = getSymbolOfNode(node);
|
||||
if (symbol.flags & SymbolFlags.FunctionScopedVariable) {
|
||||
var localDeclarationSymbol = resolveName(node, (<Identifier>node.name).text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined);
|
||||
if (localDeclarationSymbol &&
|
||||
localDeclarationSymbol !== symbol &&
|
||||
localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) {
|
||||
if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.BlockScoped) {
|
||||
|
||||
var varDeclList = getAncestor(localDeclarationSymbol.valueDeclaration, SyntaxKind.VariableDeclarationList);
|
||||
var container =
|
||||
varDeclList.parent.kind === SyntaxKind.VariableStatement &&
|
||||
varDeclList.parent.parent;
|
||||
// skip block-scoped variables and parameters
|
||||
if ((getCombinedNodeFlags(node) & NodeFlags.BlockScoped) !== 0 || isParameterDeclaration(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// names of block-scoped and function scoped variables can collide only
|
||||
// if block scoped variable is defined in the function\module\source file scope (because of variable hoisting)
|
||||
var namesShareScope =
|
||||
container &&
|
||||
(container.kind === SyntaxKind.Block && isFunctionLike(container.parent) ||
|
||||
(container.kind === SyntaxKind.ModuleBlock && container.kind === SyntaxKind.ModuleDeclaration) ||
|
||||
container.kind === SyntaxKind.SourceFile);
|
||||
// skip variable declarations that don't have initializers
|
||||
// NOTE: in ES6 spec initializer is required in variable declarations where name is binding pattern
|
||||
// so we'll always treat binding elements as initialized
|
||||
if (node.kind === SyntaxKind.VariableDeclaration && !node.initializer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// here we know that function scoped variable is shadowed by block scoped one
|
||||
// if they are defined in the same scope - binder has already reported redeclaration error
|
||||
// otherwise if variable has an initializer - show error that initialization will fail
|
||||
// since LHS will be block scoped name instead of function scoped
|
||||
if (!namesShareScope) {
|
||||
var name = symbolToString(localDeclarationSymbol);
|
||||
error(node, Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name);
|
||||
}
|
||||
var symbol = getSymbolOfNode(node);
|
||||
if (symbol.flags & SymbolFlags.FunctionScopedVariable) {
|
||||
var localDeclarationSymbol = resolveName(node, (<Identifier>node.name).text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined);
|
||||
if (localDeclarationSymbol &&
|
||||
localDeclarationSymbol !== symbol &&
|
||||
localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) {
|
||||
if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.BlockScoped) {
|
||||
|
||||
var varDeclList = getAncestor(localDeclarationSymbol.valueDeclaration, SyntaxKind.VariableDeclarationList);
|
||||
var container =
|
||||
varDeclList.parent.kind === SyntaxKind.VariableStatement &&
|
||||
varDeclList.parent.parent;
|
||||
|
||||
// names of block-scoped and function scoped variables can collide only
|
||||
// if block scoped variable is defined in the function\module\source file scope (because of variable hoisting)
|
||||
var namesShareScope =
|
||||
container &&
|
||||
(container.kind === SyntaxKind.Block && isFunctionLike(container.parent) ||
|
||||
(container.kind === SyntaxKind.ModuleBlock && container.kind === SyntaxKind.ModuleDeclaration) ||
|
||||
container.kind === SyntaxKind.SourceFile);
|
||||
|
||||
// here we know that function scoped variable is shadowed by block scoped one
|
||||
// if they are defined in the same scope - binder has already reported redeclaration error
|
||||
// otherwise if variable has an initializer - show error that initialization will fail
|
||||
// since LHS will be block scoped name instead of function scoped
|
||||
if (!namesShareScope) {
|
||||
var name = symbolToString(localDeclarationSymbol);
|
||||
error(node, Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user