Initial parser support for destructuring patterns
This commit is contained in:
parent
23c9b01024
commit
86f290fbb9
6 changed files with 141 additions and 26 deletions
|
@ -289,7 +289,6 @@ module ts {
|
|||
}
|
||||
declareSymbol(blockScopeContainer.locals, undefined, node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
}
|
||||
|
||||
bindChildren(node, SymbolFlags.BlockScopedVariable, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
|
||||
|
@ -303,11 +302,17 @@ module ts {
|
|||
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
if (node.flags & NodeFlags.BlockScoped) {
|
||||
bindBlockScopedVariableDeclaration(<Declaration>node);
|
||||
case SyntaxKind.PatternDeclaration:
|
||||
if ((<Declaration>node).name) {
|
||||
if (node.flags & NodeFlags.BlockScoped) {
|
||||
bindBlockScopedVariableDeclaration(<Declaration>node);
|
||||
}
|
||||
else {
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false);
|
||||
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Property:
|
||||
|
@ -377,7 +382,6 @@ module ts {
|
|||
bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((<SourceFile>node).filename) + '"', /*isBlockScopeContainer*/ true);
|
||||
break;
|
||||
}
|
||||
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.TryBlock:
|
||||
case SyntaxKind.CatchBlock:
|
||||
|
@ -385,9 +389,8 @@ module ts {
|
|||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
bindChildren(node, 0 , true);
|
||||
bindChildren(node, 0, /*isBlockScopeContainer*/ true);
|
||||
break;
|
||||
|
||||
default:
|
||||
var saveParent = parent;
|
||||
parent = node;
|
||||
|
|
|
@ -4255,7 +4255,10 @@ module ts {
|
|||
case SyntaxKind.BinaryExpression:
|
||||
return isAssignedInBinaryExpression(<BinaryExpression>node);
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.PatternDeclaration:
|
||||
return isAssignedInVariableDeclaration(<VariableDeclaration>node);
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
case SyntaxKind.ArrayLiteral:
|
||||
case SyntaxKind.ObjectLiteral:
|
||||
case SyntaxKind.PropertyAccess:
|
||||
|
@ -8034,6 +8037,9 @@ module ts {
|
|||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.Property:
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
case SyntaxKind.PatternDeclaration:
|
||||
case SyntaxKind.ArrayLiteral:
|
||||
case SyntaxKind.ObjectLiteral:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
|
|
|
@ -122,6 +122,8 @@ module ts {
|
|||
let_declarations_can_only_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "'let' declarations can only be declared inside a block." },
|
||||
Invalid_template_literal_expected: { code: 1158, category: DiagnosticCategory.Error, key: "Invalid template literal; expected '}'" },
|
||||
Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1159, category: DiagnosticCategory.Error, key: "Tagged templates are only available when targeting ECMAScript 6 and higher." },
|
||||
Property_destructuring_pattern_expected: { code: 1160, category: DiagnosticCategory.Error, key: "Property destructuring pattern expected." },
|
||||
Array_element_destructuring_pattern_expected: { code: 1161, category: DiagnosticCategory.Error, key: "Array element destructuring pattern expected." },
|
||||
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
|
||||
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." },
|
||||
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
|
||||
|
|
|
@ -479,6 +479,14 @@
|
|||
"category": "Error",
|
||||
"code": 1159
|
||||
},
|
||||
"Property destructuring pattern expected.": {
|
||||
"category": "Error",
|
||||
"code": 1160
|
||||
},
|
||||
"Array element destructuring pattern expected.": {
|
||||
"category": "Error",
|
||||
"code": 1161
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
|
|
|
@ -229,6 +229,14 @@ module ts {
|
|||
return children((<UnionTypeNode>node).types);
|
||||
case SyntaxKind.ParenType:
|
||||
return child((<ParenTypeNode>node).type);
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
return children((<BindingPattern>node).declarations);
|
||||
case SyntaxKind.PatternDeclaration:
|
||||
return child((<PatternDeclaration>node).propertyName) ||
|
||||
child((<PatternDeclaration>node).name) ||
|
||||
child((<PatternDeclaration>node).pattern) ||
|
||||
child((<PatternDeclaration>node).initializer);
|
||||
case SyntaxKind.ArrayLiteral:
|
||||
return children((<ArrayLiteral>node).elements);
|
||||
case SyntaxKind.ObjectLiteral:
|
||||
|
@ -506,6 +514,7 @@ module ts {
|
|||
case SyntaxKind.Property:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.PatternDeclaration:
|
||||
return (<VariableDeclaration>parent).initializer === node;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
|
@ -663,24 +672,26 @@ module ts {
|
|||
}
|
||||
|
||||
enum ParsingContext {
|
||||
SourceElements, // Elements in source file
|
||||
ModuleElements, // Elements in module declaration
|
||||
BlockStatements, // Statements in block
|
||||
SwitchClauses, // Clauses in switch statement
|
||||
SwitchClauseStatements, // Statements in switch clause
|
||||
TypeMembers, // Members in interface or type literal
|
||||
ClassMembers, // Members in class declaration
|
||||
EnumMembers, // Members in enum declaration
|
||||
BaseTypeReferences, // Type references in extends or implements clause
|
||||
VariableDeclarations, // Variable declarations in variable statement
|
||||
ArgumentExpressions, // Expressions in argument list
|
||||
ObjectLiteralMembers, // Members in object literal
|
||||
ArrayLiteralMembers, // Members in array literal
|
||||
Parameters, // Parameters in parameter list
|
||||
TypeParameters, // Type parameters in type parameter list
|
||||
TypeArguments, // Type arguments in type argument list
|
||||
TupleElementTypes, // Element types in tuple element type list
|
||||
Count // Number of parsing contexts
|
||||
SourceElements, // Elements in source file
|
||||
ModuleElements, // Elements in module declaration
|
||||
BlockStatements, // Statements in block
|
||||
SwitchClauses, // Clauses in switch statement
|
||||
SwitchClauseStatements, // Statements in switch clause
|
||||
TypeMembers, // Members in interface or type literal
|
||||
ClassMembers, // Members in class declaration
|
||||
EnumMembers, // Members in enum declaration
|
||||
BaseTypeReferences, // Type references in extends or implements clause
|
||||
VariableDeclarations, // Variable declarations in variable statement
|
||||
ObjectBindingDeclarations, // Binding elements in object binding list
|
||||
ArrayBindingDeclarations, // Binding elements in array binding list
|
||||
ArgumentExpressions, // Expressions in argument list
|
||||
ObjectLiteralMembers, // Members in object literal
|
||||
ArrayLiteralMembers, // Members in array literal
|
||||
Parameters, // Parameters in parameter list
|
||||
TypeParameters, // Type parameters in type parameter list
|
||||
TypeArguments, // Type arguments in type argument list
|
||||
TupleElementTypes, // Element types in tuple element type list
|
||||
Count // Number of parsing contexts
|
||||
}
|
||||
|
||||
enum Tristate {
|
||||
|
@ -701,6 +712,8 @@ module ts {
|
|||
case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected;
|
||||
case ParsingContext.BaseTypeReferences: return Diagnostics.Type_reference_expected;
|
||||
case ParsingContext.VariableDeclarations: return Diagnostics.Variable_declaration_expected;
|
||||
case ParsingContext.ObjectBindingDeclarations: return Diagnostics.Property_destructuring_pattern_expected;
|
||||
case ParsingContext.ArrayBindingDeclarations: return Diagnostics.Array_element_destructuring_pattern_expected;
|
||||
case ParsingContext.ArgumentExpressions: return Diagnostics.Argument_expression_expected;
|
||||
case ParsingContext.ObjectLiteralMembers: return Diagnostics.Property_assignment_expected;
|
||||
case ParsingContext.ArrayLiteralMembers: return Diagnostics.Expression_or_comma_expected;
|
||||
|
@ -1174,6 +1187,9 @@ module ts {
|
|||
case ParsingContext.BaseTypeReferences:
|
||||
return isIdentifier() && ((token !== SyntaxKind.ExtendsKeyword && token !== SyntaxKind.ImplementsKeyword) || !lookAhead(() => (nextToken(), isIdentifier())));
|
||||
case ParsingContext.VariableDeclarations:
|
||||
case ParsingContext.ObjectBindingDeclarations:
|
||||
case ParsingContext.ArrayBindingDeclarations:
|
||||
return isIdentifierOrPattern();
|
||||
case ParsingContext.TypeParameters:
|
||||
return isIdentifier();
|
||||
case ParsingContext.ArgumentExpressions:
|
||||
|
@ -1205,6 +1221,7 @@ module ts {
|
|||
case ParsingContext.ClassMembers:
|
||||
case ParsingContext.EnumMembers:
|
||||
case ParsingContext.ObjectLiteralMembers:
|
||||
case ParsingContext.ObjectBindingDeclarations:
|
||||
return token === SyntaxKind.CloseBraceToken;
|
||||
case ParsingContext.SwitchClauseStatements:
|
||||
return token === SyntaxKind.CloseBraceToken || token === SyntaxKind.CaseKeyword || token === SyntaxKind.DefaultKeyword;
|
||||
|
@ -1220,6 +1237,7 @@ module ts {
|
|||
return token === SyntaxKind.CloseParenToken || token === SyntaxKind.SemicolonToken;
|
||||
case ParsingContext.ArrayLiteralMembers:
|
||||
case ParsingContext.TupleElementTypes:
|
||||
case ParsingContext.ArrayBindingDeclarations:
|
||||
return token === SyntaxKind.CloseBracketToken;
|
||||
case ParsingContext.Parameters:
|
||||
// Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
|
||||
|
@ -3356,11 +3374,68 @@ module ts {
|
|||
|
||||
// DECLARATIONS
|
||||
|
||||
function parseBindingDeclaration(flags: NodeFlags, context: ParsingContext): PatternDeclaration {
|
||||
var node = <PatternDeclaration>createNode(SyntaxKind.PatternDeclaration);
|
||||
node.flags = flags;
|
||||
if (context === ParsingContext.ObjectBindingDeclarations) {
|
||||
var id = parseIdentifier();
|
||||
if (parseOptional(SyntaxKind.ColonToken)) {
|
||||
node.propertyName = id;
|
||||
parseIdentifierOrPatternOfNode(node, flags);
|
||||
}
|
||||
else {
|
||||
node.name = id;
|
||||
}
|
||||
}
|
||||
else {
|
||||
parseIdentifierOrPatternOfNode(node, flags);
|
||||
}
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseBindingList(flags: NodeFlags, context: ParsingContext): NodeArray<PatternDeclaration> {
|
||||
return parseDelimitedList(context, () => parseBindingDeclaration(flags, context), /*allowTrailingComma*/ true);
|
||||
}
|
||||
|
||||
function parseObjectBindingPattern(flags: NodeFlags): BindingPattern {
|
||||
var node = <BindingPattern>createNode(SyntaxKind.ObjectBindingPattern);
|
||||
node.flags = flags;
|
||||
parseExpected(SyntaxKind.OpenBraceToken);
|
||||
node.declarations = parseBindingList(flags, ParsingContext.ObjectBindingDeclarations);
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseArrayBindingPattern(flags: NodeFlags): BindingPattern {
|
||||
var node = <BindingPattern>createNode(SyntaxKind.ArrayBindingPattern);
|
||||
node.flags = flags;
|
||||
parseExpected(SyntaxKind.OpenBracketToken);
|
||||
node.declarations = parseBindingList(flags, ParsingContext.ArrayBindingDeclarations);
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function isIdentifierOrPattern() {
|
||||
return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken || isIdentifier();
|
||||
}
|
||||
|
||||
function parseIdentifierOrPatternOfNode(node: NameOrPatternNode, flags: NodeFlags) {
|
||||
if (token === SyntaxKind.OpenBracketToken) {
|
||||
node.pattern = parseArrayBindingPattern(flags);
|
||||
}
|
||||
else if (token === SyntaxKind.OpenBraceToken) {
|
||||
node.pattern = parseObjectBindingPattern(flags);
|
||||
}
|
||||
else {
|
||||
node.name = parseIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
function parseVariableDeclaration(flags: NodeFlags, noIn?: boolean): VariableDeclaration {
|
||||
var node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration);
|
||||
node.flags = flags;
|
||||
var errorCountBeforeVariableDeclaration = file.syntacticErrors.length;
|
||||
node.name = parseIdentifier();
|
||||
parseIdentifierOrPatternOfNode(node, flags);
|
||||
node.type = parseTypeAnnotation();
|
||||
|
||||
// Issue any initializer-related errors on the equals token
|
||||
|
|
|
@ -162,6 +162,10 @@ module ts {
|
|||
TupleType,
|
||||
UnionType,
|
||||
ParenType,
|
||||
// Binding patterns
|
||||
ObjectBindingPattern,
|
||||
ArrayBindingPattern,
|
||||
PatternDeclaration,
|
||||
// Expression
|
||||
ArrayLiteral,
|
||||
ObjectLiteral,
|
||||
|
@ -313,10 +317,27 @@ module ts {
|
|||
export interface SignatureDeclaration extends Declaration, ParsedSignature { }
|
||||
|
||||
export interface VariableDeclaration extends Declaration {
|
||||
pattern?: BindingPattern;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
}
|
||||
|
||||
export interface BindingPattern extends Node {
|
||||
declarations: PatternDeclaration[];
|
||||
}
|
||||
|
||||
export interface PatternDeclaration extends Declaration {
|
||||
propertyName?: Identifier; // Binding property name
|
||||
name?: Identifier; // Declared variable name (pattern = undefined)
|
||||
pattern?: BindingPattern; // Nested binding pattern (name = undefined)
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
||||
export interface NameOrPatternNode extends Node {
|
||||
name?: Identifier;
|
||||
pattern?: BindingPattern;
|
||||
}
|
||||
|
||||
export interface PropertyDeclaration extends VariableDeclaration { }
|
||||
|
||||
export interface ParameterDeclaration extends VariableDeclaration { }
|
||||
|
|
Loading…
Reference in a new issue