Skip to content

Commit bd811ce

Browse files
committed
Merge branch 'master' of https://github.com/Microsoft/TypeScript into typeParameterFixing
2 parents 9933f6c + ad98fad commit bd811ce

21 files changed

+796
-243
lines changed

src/compiler/checker.ts

Lines changed: 64 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ module ts {
447447
let declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) ? d : undefined);
448448

449449
Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined");
450-
450+
451451
// first check if usage is lexically located after the declaration
452452
let isUsedBeforeDeclaration = !isDefinedBefore(declaration, errorLocation);
453453
if (!isUsedBeforeDeclaration) {
@@ -464,7 +464,7 @@ module ts {
464464

465465
if (variableDeclaration.parent.parent.kind === SyntaxKind.VariableStatement ||
466466
variableDeclaration.parent.parent.kind === SyntaxKind.ForStatement) {
467-
// variable statement/for statement case,
467+
// variable statement/for statement case,
468468
// use site should not be inside variable declaration (initializer of declaration or binding element)
469469
isUsedBeforeDeclaration = isSameScopeDescendentOf(errorLocation, variableDeclaration, container);
470470
}
@@ -4414,7 +4414,7 @@ module ts {
44144414
}
44154415

44164416
/**
4417-
* Check if a Type was written as a tuple type literal.
4417+
* Check if a Type was written as a tuple type literal.
44184418
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
44194419
*/
44204420
function isTupleType(type: Type) : boolean {
@@ -8653,36 +8653,48 @@ module ts {
86538653
// const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration
86548654
// let x = 0; // symbol for this declaration will be 'symbol'
86558655
// }
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);
86868698
}
86878699
}
86888700
}
@@ -9099,7 +9111,7 @@ module ts {
90999111
*/
91009112
function checkElementTypeOfArrayOrString(arrayOrStringType: Type, expressionForError: Expression): Type {
91019113
Debug.assert(languageVersion < ScriptTarget.ES6);
9102-
9114+
91039115
// After we remove all types that are StringLike, we will know if there was a string constituent
91049116
// based on whether the remaining type is the same as the initial type.
91059117
let arrayType = removeTypesFromUnionType(arrayOrStringType, TypeFlags.StringLike, /*isTypeOfKind*/ true, /*allowEmptyUnionResult*/ true);
@@ -11343,16 +11355,15 @@ module ts {
1134311355
}
1134411356
}
1134511357

11346-
function checkGrammarTypeParameterList(node: FunctionLikeDeclaration, typeParameters: NodeArray<TypeParameterDeclaration>): boolean {
11358+
function checkGrammarTypeParameterList(node: FunctionLikeDeclaration, typeParameters: NodeArray<TypeParameterDeclaration>, file: SourceFile): boolean {
1134711359
if (checkGrammarForDisallowedTrailingComma(typeParameters)) {
1134811360
return true;
1134911361
}
1135011362

1135111363
if (typeParameters && typeParameters.length === 0) {
1135211364
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);
1135611367
}
1135711368
}
1135811369

@@ -11396,7 +11407,21 @@ module ts {
1139611407

1139711408
function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
1139811409
// 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;
1140011425
}
1140111426

1140211427
function checkGrammarIndexSignatureParameters(node: SignatureDeclaration): boolean {

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ module ts {
157157
Catch_clause_variable_cannot_have_an_initializer: { code: 1197, category: DiagnosticCategory.Error, key: "Catch clause variable cannot have an initializer." },
158158
An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: { code: 1198, category: DiagnosticCategory.Error, key: "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive." },
159159
Unterminated_Unicode_escape_sequence: { code: 1199, category: DiagnosticCategory.Error, key: "Unterminated Unicode escape sequence." },
160+
Line_terminator_not_permitted_before_arrow: { code: 1200, category: DiagnosticCategory.Error, key: "Line terminator not permitted before arrow." },
160161
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
161162
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
162163
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,10 @@
619619
"category": "Error",
620620
"code": 1199
621621
},
622+
"Line terminator not permitted before arrow.": {
623+
"category": "Error",
624+
"code": 1200
625+
},
622626
"Duplicate identifier '{0}'.": {
623627
"category": "Error",
624628
"code": 2300

0 commit comments

Comments
 (0)