@@ -447,7 +447,7 @@ module ts {
447
447
let declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) ? d : undefined);
448
448
449
449
Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined");
450
-
450
+
451
451
// first check if usage is lexically located after the declaration
452
452
let isUsedBeforeDeclaration = !isDefinedBefore(declaration, errorLocation);
453
453
if (!isUsedBeforeDeclaration) {
@@ -464,7 +464,7 @@ module ts {
464
464
465
465
if (variableDeclaration.parent.parent.kind === SyntaxKind.VariableStatement ||
466
466
variableDeclaration.parent.parent.kind === SyntaxKind.ForStatement) {
467
- // variable statement/for statement case,
467
+ // variable statement/for statement case,
468
468
// use site should not be inside variable declaration (initializer of declaration or binding element)
469
469
isUsedBeforeDeclaration = isSameScopeDescendentOf(errorLocation, variableDeclaration, container);
470
470
}
@@ -4414,7 +4414,7 @@ module ts {
4414
4414
}
4415
4415
4416
4416
/**
4417
- * Check if a Type was written as a tuple type literal.
4417
+ * Check if a Type was written as a tuple type literal.
4418
4418
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
4419
4419
*/
4420
4420
function isTupleType(type: Type) : boolean {
@@ -8653,36 +8653,48 @@ module ts {
8653
8653
// const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration
8654
8654
// let x = 0; // symbol for this declaration will be 'symbol'
8655
8655
// }
8656
- if (node.initializer && (getCombinedNodeFlags(node) & NodeFlags.BlockScoped) === 0) {
8657
- let symbol = getSymbolOfNode(node);
8658
- if (symbol.flags & SymbolFlags.FunctionScopedVariable) {
8659
- let localDeclarationSymbol = resolveName(node, (<Identifier>node.name).text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined);
8660
- if (localDeclarationSymbol &&
8661
- localDeclarationSymbol !== symbol &&
8662
- localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) {
8663
- if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.BlockScoped) {
8664
-
8665
- let varDeclList = getAncestor(localDeclarationSymbol.valueDeclaration, SyntaxKind.VariableDeclarationList);
8666
- let container =
8667
- varDeclList.parent.kind === SyntaxKind.VariableStatement &&
8668
- varDeclList.parent.parent;
8669
-
8670
- // names of block-scoped and function scoped variables can collide only
8671
- // if block scoped variable is defined in the function\module\source file scope (because of variable hoisting)
8672
- let namesShareScope =
8673
- container &&
8674
- (container.kind === SyntaxKind.Block && isFunctionLike(container.parent) ||
8675
- (container.kind === SyntaxKind.ModuleBlock && container.kind === SyntaxKind.ModuleDeclaration) ||
8676
- container.kind === SyntaxKind.SourceFile);
8677
-
8678
- // here we know that function scoped variable is shadowed by block scoped one
8679
- // if they are defined in the same scope - binder has already reported redeclaration error
8680
- // otherwise if variable has an initializer - show error that initialization will fail
8681
- // since LHS will be block scoped name instead of function scoped
8682
- if (!namesShareScope) {
8683
- let name = symbolToString(localDeclarationSymbol);
8684
- error(node, Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name);
8685
- }
8656
+
8657
+ // skip block-scoped variables and parameters
8658
+ if ((getCombinedNodeFlags(node) & NodeFlags.BlockScoped) !== 0 || isParameterDeclaration(node)) {
8659
+ return;
8660
+ }
8661
+
8662
+ // skip variable declarations that don't have initializers
8663
+ // NOTE: in ES6 spec initializer is required in variable declarations where name is binding pattern
8664
+ // so we'll always treat binding elements as initialized
8665
+ if (node.kind === SyntaxKind.VariableDeclaration && !node.initializer) {
8666
+ return;
8667
+ }
8668
+
8669
+ var symbol = getSymbolOfNode(node);
8670
+ if (symbol.flags & SymbolFlags.FunctionScopedVariable) {
8671
+ let localDeclarationSymbol = resolveName(node, (<Identifier>node.name).text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined);
8672
+ if (localDeclarationSymbol &&
8673
+ localDeclarationSymbol !== symbol &&
8674
+ localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) {
8675
+ if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.BlockScoped) {
8676
+ let varDeclList = getAncestor(localDeclarationSymbol.valueDeclaration, SyntaxKind.VariableDeclarationList);
8677
+ let container =
8678
+ varDeclList.parent.kind === SyntaxKind.VariableStatement && varDeclList.parent.parent
8679
+ ? varDeclList.parent.parent
8680
+ : undefined;
8681
+
8682
+ // names of block-scoped and function scoped variables can collide only
8683
+ // if block scoped variable is defined in the function\module\source file scope (because of variable hoisting)
8684
+ let namesShareScope =
8685
+ container &&
8686
+ (container.kind === SyntaxKind.Block && isFunctionLike(container.parent) ||
8687
+ container.kind === SyntaxKind.ModuleBlock ||
8688
+ container.kind === SyntaxKind.ModuleDeclaration ||
8689
+ container.kind === SyntaxKind.SourceFile);
8690
+
8691
+ // here we know that function scoped variable is shadowed by block scoped one
8692
+ // if they are defined in the same scope - binder has already reported redeclaration error
8693
+ // otherwise if variable has an initializer - show error that initialization will fail
8694
+ // since LHS will be block scoped name instead of function scoped
8695
+ if (!namesShareScope) {
8696
+ let name = symbolToString(localDeclarationSymbol);
8697
+ error(node, Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name);
8686
8698
}
8687
8699
}
8688
8700
}
@@ -9099,7 +9111,7 @@ module ts {
9099
9111
*/
9100
9112
function checkElementTypeOfArrayOrString(arrayOrStringType: Type, expressionForError: Expression): Type {
9101
9113
Debug.assert(languageVersion < ScriptTarget.ES6);
9102
-
9114
+
9103
9115
// After we remove all types that are StringLike, we will know if there was a string constituent
9104
9116
// based on whether the remaining type is the same as the initial type.
9105
9117
let arrayType = removeTypesFromUnionType(arrayOrStringType, TypeFlags.StringLike, /*isTypeOfKind*/ true, /*allowEmptyUnionResult*/ true);
@@ -11343,16 +11355,15 @@ module ts {
11343
11355
}
11344
11356
}
11345
11357
11346
- function checkGrammarTypeParameterList(node: FunctionLikeDeclaration, typeParameters: NodeArray<TypeParameterDeclaration>): boolean {
11358
+ function checkGrammarTypeParameterList(node: FunctionLikeDeclaration, typeParameters: NodeArray<TypeParameterDeclaration>, file: SourceFile ): boolean {
11347
11359
if (checkGrammarForDisallowedTrailingComma(typeParameters)) {
11348
11360
return true;
11349
11361
}
11350
11362
11351
11363
if (typeParameters && typeParameters.length === 0) {
11352
11364
let start = typeParameters.pos - "<".length;
11353
- let sourceFile = getSourceFileOfNode(node);
11354
- let end = skipTrivia(sourceFile.text, typeParameters.end) + ">".length;
11355
- return grammarErrorAtPos(sourceFile, start, end - start, Diagnostics.Type_parameter_list_cannot_be_empty);
11365
+ let end = skipTrivia(file.text, typeParameters.end) + ">".length;
11366
+ return grammarErrorAtPos(file, start, end - start, Diagnostics.Type_parameter_list_cannot_be_empty);
11356
11367
}
11357
11368
}
11358
11369
@@ -11396,7 +11407,21 @@ module ts {
11396
11407
11397
11408
function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
11398
11409
// Prevent cascading error by short-circuit
11399
- return checkGrammarModifiers(node) || checkGrammarTypeParameterList(node, node.typeParameters) || checkGrammarParameterList(node.parameters);
11410
+ let file = getSourceFileOfNode(node);
11411
+ return checkGrammarModifiers(node) || checkGrammarTypeParameterList(node, node.typeParameters, file) ||
11412
+ checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file);
11413
+ }
11414
+
11415
+ function checkGrammarArrowFunction(node: FunctionLikeDeclaration, file: SourceFile): boolean {
11416
+ if (node.kind === SyntaxKind.ArrowFunction) {
11417
+ let arrowFunction = <ArrowFunction>node;
11418
+ let startLine = getLineAndCharacterOfPosition(file, arrowFunction.equalsGreaterThanToken.pos).line;
11419
+ let endLine = getLineAndCharacterOfPosition(file, arrowFunction.equalsGreaterThanToken.end).line;
11420
+ if (startLine !== endLine) {
11421
+ return grammarErrorOnNode(arrowFunction.equalsGreaterThanToken, Diagnostics.Line_terminator_not_permitted_before_arrow);
11422
+ }
11423
+ }
11424
+ return false;
11400
11425
}
11401
11426
11402
11427
function checkGrammarIndexSignatureParameters(node: SignatureDeclaration): boolean {
0 commit comments