Skip to content

Commit 05c9966

Browse files
committed
Addressing CR feedback:
New SyntaxKind.BindingElement Introduced new VariableLikeDeclaration and BindingElement types Cleaned up VariableDeclaration, ParameterDeclaration, PropertyDeclaration types Node kind of binding element is always SyntaxKind.BindingElement Changed CheckVariableDeclaration to CheckVariableLikeDeclaration Reorganized CheckVariableLikeDeclaration
1 parent 4118ffc commit 05c9966

File tree

7 files changed

+231
-156
lines changed

7 files changed

+231
-156
lines changed

src/compiler/binder.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -389,18 +389,14 @@ module ts {
389389
break;
390390
case SyntaxKind.Parameter:
391391
if (isBindingPattern((<Declaration>node).name)) {
392-
if (isBindingPattern(parent)) {
393-
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
394-
}
395-
else {
396-
bindAnonymousDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(<Declaration>node), /*isBlockScopeContainer*/ false);
397-
}
392+
bindAnonymousDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(<Declaration>node), /*isBlockScopeContainer*/ false);
398393
}
399394
else {
400395
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
401396
}
402397
break;
403398
case SyntaxKind.VariableDeclaration:
399+
case SyntaxKind.BindingElement:
404400
if (isBindingPattern((<Declaration>node).name)) {
405401
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
406402
}

src/compiler/checker.ts

+133-95
Large diffs are not rendered by default.

src/compiler/emitter.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ module ts {
440440
handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning));
441441
}
442442

443-
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableOrParameterDeclaration, type: TypeNode | StringLiteralExpression, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
443+
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode | StringLiteralExpression, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
444444
writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
445445
write(": ");
446446
if (type) {
@@ -996,7 +996,7 @@ module ts {
996996
}
997997
}
998998

999-
function emitTypeOfVariableDeclarationFromTypeLiteral(node: VariableOrParameterDeclaration) {
999+
function emitTypeOfVariableDeclarationFromTypeLiteral(node: VariableLikeDeclaration) {
10001000
// if this is property of type literal,
10011001
// or is parameter of method/call/construct/index signature of type literal
10021002
// emit only if type is specified
@@ -2149,6 +2149,7 @@ module ts {
21492149
switch (parent.kind) {
21502150
case SyntaxKind.Parameter:
21512151
case SyntaxKind.VariableDeclaration:
2152+
case SyntaxKind.BindingElement:
21522153
case SyntaxKind.Property:
21532154
case SyntaxKind.PropertyAssignment:
21542155
case SyntaxKind.ShorthandPropertyAssignment:
@@ -2761,10 +2762,10 @@ module ts {
27612762
emitEnd(node.name);
27622763
}
27632764

2764-
function emitDestructuring(root: BinaryExpression | BindingElement, value?: Expression) {
2765+
function emitDestructuring(root: BinaryExpression | VariableDeclaration | ParameterDeclaration, value?: Expression) {
27652766
var emitCount = 0;
27662767
// An exported declaration is actually emitted as an assignment (to a property on the module object), so
2767-
// temporary variables in an exported declaration need to have real declarations elsewhere.
2768+
// temporary variables in an exported declaration need to have real declarations elsewhere
27682769
var isDeclaration = (root.kind === SyntaxKind.VariableDeclaration && !(root.flags & NodeFlags.Export)) || root.kind === SyntaxKind.Parameter;
27692770
if (root.kind === SyntaxKind.BinaryExpression) {
27702771
emitAssignmentExpression(<BinaryExpression>root);
@@ -2777,8 +2778,8 @@ module ts {
27772778
if (emitCount++) {
27782779
write(", ");
27792780
}
2780-
if (name.parent && name.parent.kind === SyntaxKind.VariableDeclaration) {
2781-
emitModuleMemberName(<VariableDeclaration>name.parent);
2781+
if (name.parent && (name.parent.kind === SyntaxKind.VariableDeclaration || name.parent.kind === SyntaxKind.BindingElement)) {
2782+
emitModuleMemberName(<Declaration>name.parent);
27822783
}
27832784
else {
27842785
emit(name);

src/compiler/parser.ts

+38-32
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ module ts {
102102
// This list is a work in progress. Add missing node kinds to improve their error
103103
// spans.
104104
case SyntaxKind.VariableDeclaration:
105+
case SyntaxKind.BindingElement:
105106
case SyntaxKind.ClassDeclaration:
106107
case SyntaxKind.InterfaceDeclaration:
107108
case SyntaxKind.ModuleDeclaration:
@@ -216,13 +217,14 @@ module ts {
216217
case SyntaxKind.PropertyAssignment:
217218
case SyntaxKind.ShorthandPropertyAssignment:
218219
case SyntaxKind.VariableDeclaration:
220+
case SyntaxKind.BindingElement:
219221
return children(node.modifiers) ||
220-
child((<VariableDeclaration>node).propertyName) ||
221-
child((<VariableDeclaration>node).dotDotDotToken) ||
222-
child((<VariableDeclaration>node).name) ||
223-
child((<VariableDeclaration>node).questionToken) ||
224-
child((<VariableDeclaration>node).type) ||
225-
child((<VariableDeclaration>node).initializer);
222+
child((<VariableLikeDeclaration>node).propertyName) ||
223+
child((<VariableLikeDeclaration>node).dotDotDotToken) ||
224+
child((<VariableLikeDeclaration>node).name) ||
225+
child((<VariableLikeDeclaration>node).questionToken) ||
226+
child((<VariableLikeDeclaration>node).type) ||
227+
child((<VariableLikeDeclaration>node).initializer);
226228
case SyntaxKind.FunctionType:
227229
case SyntaxKind.ConstructorType:
228230
case SyntaxKind.CallSignature:
@@ -580,7 +582,8 @@ module ts {
580582
case SyntaxKind.Property:
581583
case SyntaxKind.EnumMember:
582584
case SyntaxKind.PropertyAssignment:
583-
return (<VariableDeclaration>parent).initializer === node;
585+
case SyntaxKind.BindingElement:
586+
return (<VariableLikeDeclaration>parent).initializer === node;
584587
case SyntaxKind.ExpressionStatement:
585588
case SyntaxKind.IfStatement:
586589
case SyntaxKind.DoStatement:
@@ -679,6 +682,7 @@ module ts {
679682
case SyntaxKind.TypeParameter:
680683
case SyntaxKind.Parameter:
681684
case SyntaxKind.VariableDeclaration:
685+
case SyntaxKind.BindingElement:
682686
case SyntaxKind.Property:
683687
case SyntaxKind.PropertyAssignment:
684688
case SyntaxKind.ShorthandPropertyAssignment:
@@ -1892,12 +1896,7 @@ module ts {
18921896
// [+GeneratorParameter]BindingIdentifier[Yield]Initializer[In]opt
18931897
// [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt
18941898

1895-
var savedYieldContext = inYieldContext();
1896-
if (inGeneratorParameterContext()) {
1897-
setYieldContext(true);
1898-
}
1899-
node.name = parseIdentifierOrPattern(SyntaxKind.Parameter);
1900-
setYieldContext(savedYieldContext);
1899+
node.name = inGeneratorParameterContext() ? doInYieldContext(parseIdentifierOrPattern) : parseIdentifierOrPattern();
19011900

19021901
if (getFullWidth(node.name) === 0 && node.flags === 0 && isModifier(token)) {
19031902
// in cases like
@@ -1913,9 +1912,7 @@ module ts {
19131912

19141913
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
19151914
node.type = parseParameterType();
1916-
node.initializer = inGeneratorParameterContext()
1917-
? doOutsideOfYieldContext(parseParameterInitializer)
1918-
: parseParameterInitializer();
1915+
node.initializer = inGeneratorParameterContext() ? doOutsideOfYieldContext(parseParameterInitializer) : parseParameterInitializer();
19191916

19201917
// Do not check for initializers in an ambient context for parameters. This is not
19211918
// a grammar error because the grammar allows arbitrary call signatures in
@@ -3691,11 +3688,11 @@ module ts {
36913688

36923689
// DECLARATIONS
36933690

3694-
function parseBindingElement(kind: SyntaxKind, context: ParsingContext): BindingElement {
3691+
function parseBindingElement(context: ParsingContext): BindingElement {
36953692
if (context === ParsingContext.ArrayBindingElements && token === SyntaxKind.CommaToken) {
36963693
return <BindingElement>createNode(SyntaxKind.OmittedExpression);
36973694
}
3698-
var node = <BindingElement>createNode(kind);
3695+
var node = <BindingElement>createNode(SyntaxKind.BindingElement);
36993696
if (context === ParsingContext.ObjectBindingElements) {
37003697
// TODO(andersh): Handle computed properties
37013698
var id = parsePropertyName();
@@ -3705,32 +3702,32 @@ module ts {
37053702
else {
37063703
parseExpected(SyntaxKind.ColonToken);
37073704
node.propertyName = <Identifier>id;
3708-
node.name = parseIdentifierOrPattern(kind);
3705+
node.name = parseIdentifierOrPattern();
37093706
}
37103707
}
37113708
else {
3712-
node.name = parseIdentifierOrPattern(kind);
3709+
node.name = parseIdentifierOrPattern();
37133710
}
37143711
node.initializer = parseInitializer(/*inParameter*/ false);
37153712
return finishNode(node);
37163713
}
37173714

3718-
function parseBindingList(kind: SyntaxKind, context: ParsingContext): NodeArray<BindingElement> {
3719-
return parseDelimitedList(context, () => parseBindingElement(kind, context));
3715+
function parseBindingList(context: ParsingContext): NodeArray<BindingElement> {
3716+
return parseDelimitedList(context, () => parseBindingElement(context));
37203717
}
37213718

3722-
function parseObjectBindingPattern(kind: SyntaxKind): BindingPattern {
3719+
function parseObjectBindingPattern(): BindingPattern {
37233720
var node = <BindingPattern>createNode(SyntaxKind.ObjectBindingPattern);
37243721
parseExpected(SyntaxKind.OpenBraceToken);
3725-
node.elements = parseBindingList(kind, ParsingContext.ObjectBindingElements);
3722+
node.elements = parseBindingList(ParsingContext.ObjectBindingElements);
37263723
parseExpected(SyntaxKind.CloseBraceToken);
37273724
return finishNode(node);
37283725
}
37293726

3730-
function parseArrayBindingPattern(kind: SyntaxKind): BindingPattern {
3727+
function parseArrayBindingPattern(): BindingPattern {
37313728
var node = <BindingPattern>createNode(SyntaxKind.ArrayBindingPattern);
37323729
parseExpected(SyntaxKind.OpenBracketToken);
3733-
node.elements = parseBindingList(kind, ParsingContext.ArrayBindingElements);
3730+
node.elements = parseBindingList(ParsingContext.ArrayBindingElements);
37343731
parseExpected(SyntaxKind.CloseBracketToken);
37353732
return finishNode(node);
37363733
}
@@ -3739,19 +3736,19 @@ module ts {
37393736
return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken || isIdentifier();
37403737
}
37413738

3742-
function parseIdentifierOrPattern(kind: SyntaxKind): Identifier | BindingPattern {
3739+
function parseIdentifierOrPattern(): Identifier | BindingPattern {
37433740
if (token === SyntaxKind.OpenBracketToken) {
3744-
return parseArrayBindingPattern(kind);
3741+
return parseArrayBindingPattern();
37453742
}
37463743
if (token === SyntaxKind.OpenBraceToken) {
3747-
return parseObjectBindingPattern(kind);
3744+
return parseObjectBindingPattern();
37483745
}
37493746
return parseIdentifier();
37503747
}
37513748

37523749
function parseVariableDeclaration(): VariableDeclaration {
37533750
var node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration);
3754-
node.name = parseIdentifierOrPattern(SyntaxKind.VariableDeclaration);
3751+
node.name = parseIdentifierOrPattern();
37553752
node.type = parseTypeAnnotation();
37563753
node.initializer = parseInitializer(/*inParameter*/ false);
37573754
return finishNode(node);
@@ -4492,6 +4489,7 @@ module ts {
44924489

44934490
case SyntaxKind.EnumDeclaration: return checkEnumDeclaration(<EnumDeclaration>node);
44944491
case SyntaxKind.BinaryExpression: return checkBinaryExpression(<BinaryExpression>node);
4492+
case SyntaxKind.BindingElement: return checkBindingElement(<BindingElement>node);
44954493
case SyntaxKind.CatchClause: return checkCatchClause(<CatchClause>node);
44964494
case SyntaxKind.ClassDeclaration: return checkClassDeclaration(<ClassDeclaration>node);
44974495
case SyntaxKind.ComputedPropertyName: return checkComputedPropertyName(<ComputedPropertyName>node);
@@ -5594,14 +5592,22 @@ module ts {
55945592
return checkTypeArguments(node.typeArguments);
55955593
}
55965594

5595+
function checkBindingElement(node: BindingElement) {
5596+
if (node.parserContextFlags & ParserContextFlags.StrictMode && isEvalOrArgumentsIdentifier(node.name)) {
5597+
// It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
5598+
// and its Identifier is eval or arguments
5599+
return reportInvalidUseInStrictMode(<Identifier>node.name);
5600+
}
5601+
}
5602+
55975603
function checkVariableDeclaration(node: VariableDeclaration) {
55985604
if (inAmbientContext) {
55995605
if (isBindingPattern(node.name)) {
56005606
return grammarErrorOnNode(node, Diagnostics.Destructuring_declarations_are_not_allowed_in_ambient_contexts);
56015607
}
56025608
if (node.initializer) {
5603-
var equalsPos = node.type ? skipTrivia(sourceText, node.type.end) : skipTrivia(sourceText, node.name.end);
5604-
return grammarErrorAtPos(equalsPos, "=".length, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
5609+
// Error on equals token which immediate precedes the initializer
5610+
return grammarErrorAtPos(node.initializer.pos - 1, 1, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
56055611
}
56065612
}
56075613
else {

0 commit comments

Comments
 (0)