| Index: lib/src/js/builder.dart
|
| diff --git a/lib/src/js/builder.dart b/lib/src/js/builder.dart
|
| index a01336ff88afe0499c01892f760a44c149c6d9b3..9643f7847cd89ce2572f71b4429468434baddfea 100644
|
| --- a/lib/src/js/builder.dart
|
| +++ b/lib/src/js/builder.dart
|
| @@ -811,6 +811,22 @@ class MiniJsParser {
|
| return expression;
|
| }
|
|
|
| + InterpolatedIdentifier parseInterpolatedIdentifier() {
|
| + var id = new InterpolatedIdentifier(parseHash());
|
| + interpolatedValues.add(id);
|
| + return id;
|
| + }
|
| +
|
| + Identifier parseIdentifier() {
|
| + if (acceptCategory(HASH)) {
|
| + return parseInterpolatedIdentifier();
|
| + } else {
|
| + var id = new Identifier(lastToken);
|
| + expectCategory(ALPHA);
|
| + return id;
|
| + }
|
| + }
|
| +
|
| /**
|
| * CoverParenthesizedExpressionAndArrowParameterList[Yield] :
|
| * ( Expression )
|
| @@ -1136,43 +1152,88 @@ class MiniJsParser {
|
| }
|
|
|
| /** Parse a variable declaration list, with `var` or `let` [keyword] */
|
| - VariableDeclarationList parseVariableDeclarationList(String keyword) {
|
| - // Supports one form for interpolated variable declaration:
|
| - // let # = ...
|
| - if (acceptCategory(HASH)) {
|
| - var name = new InterpolatedIdentifier(parseHash());
|
| - interpolatedValues.add(name);
|
| + VariableDeclarationList parseVariableDeclarationList(String keyword) {
|
| + var initialization = [];
|
|
|
| - Expression initializer = acceptString("=") ? parseAssignment() : null;
|
| - return new VariableDeclarationList(keyword,
|
| - [new VariableInitialization(name, initializer)]);
|
| + do {
|
| + var declarator = parseVariableBinding();
|
| + var initializer = acceptString("=") ? parseAssignment() : null;
|
| + initialization.add(new VariableInitialization(declarator, initializer));
|
| + } while (acceptCategory(COMMA));
|
| +
|
| + return new VariableDeclarationList(keyword, initialization);
|
| + }
|
| +
|
| + VariableBinding parseVariableBinding() {
|
| + switch (lastCategory) {
|
| + case ALPHA:
|
| + case HASH:
|
| + return parseIdentifier();
|
| + case LBRACE:
|
| + case LSQUARE:
|
| + return parseBindingPattern();
|
| + default:
|
| + error('Unexpected token $lastToken: ${categoryToString(lastCategory)}');
|
| + return null;
|
| }
|
| + }
|
|
|
| - String firstVariable = lastToken;
|
| - expectCategory(ALPHA);
|
| - return finishVariableDeclarationList(keyword, firstVariable);
|
| + /// Note: this doesn't deal with general-case destructuring yet, it just
|
| + /// supports it in variable initialization.
|
| + /// See ES6 spec:
|
| + /// http://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-binding-patterns
|
| + /// http://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-assignment
|
| + /// TODO(ochafik): Support destructuring in LeftHandSideExpression.
|
| + BindingPattern parseBindingPattern() {
|
| + if (acceptCategory(LBRACE)) {
|
| + return parseObjectBindingPattern();
|
| + } else {
|
| + expectCategory(LSQUARE);
|
| + return parseArrayBindingPattern();
|
| + }
|
| }
|
|
|
| - VariableDeclarationList finishVariableDeclarationList(
|
| - String keyword, String firstVariable) {
|
| - var initialization = [];
|
| + ArrayBindingPattern parseArrayBindingPattern() {
|
| + var variables = <DestructuredVariable>[];
|
| + do {
|
| + var name;
|
| + var structure;
|
| + var defaultValue;
|
| +
|
| + var declarator = parseVariableBinding();
|
| + if (declarator is Identifier) name = declarator;
|
| + else if (declarator is BindingPattern) structure = declarator;
|
| + else error("Unexpected LHS: $declarator");
|
|
|
| - void declare(String variable) {
|
| - Expression initializer = null;
|
| if (acceptString("=")) {
|
| - initializer = parseAssignment();
|
| + defaultValue = parseExpression();
|
| }
|
| - var declaration = new Identifier(variable);
|
| - initialization.add(new VariableInitialization(declaration, initializer));
|
| - }
|
| + variables.add(new DestructuredVariable(
|
| + name: name, structure: structure, defaultValue: defaultValue));
|
| + } while (acceptCategory(COMMA));
|
|
|
| - declare(firstVariable);
|
| - while (acceptCategory(COMMA)) {
|
| - String variable = lastToken;
|
| - expectCategory(ALPHA);
|
| - declare(variable);
|
| - }
|
| - return new VariableDeclarationList(keyword, initialization);
|
| + expectCategory(RSQUARE);
|
| + return new ArrayBindingPattern(variables);
|
| + }
|
| +
|
| + ObjectBindingPattern parseObjectBindingPattern() {
|
| + var variables = <DestructuredVariable>[];
|
| + do {
|
| + var name = parseIdentifier();
|
| + var structure;
|
| + var defaultValue;
|
| +
|
| + if (acceptCategory(COLON)) {
|
| + structure = parseBindingPattern();
|
| + } else if (acceptString("=")) {
|
| + defaultValue = parseExpression();
|
| + }
|
| + variables.add(new DestructuredVariable(
|
| + name: name, structure: structure, defaultValue: defaultValue));
|
| + } while (acceptCategory(COMMA));
|
| +
|
| + expectCategory(RBRACE);
|
| + return new ObjectBindingPattern(variables);
|
| }
|
|
|
| Expression parseVarDeclarationOrExpression() {
|
| @@ -1395,7 +1456,7 @@ class MiniJsParser {
|
| iterableExpression,
|
| body);
|
| }
|
| - var declarations = finishVariableDeclarationList(keyword, identifier);
|
| + var declarations = parseVariableDeclarationList(keyword);
|
| expectCategory(SEMICOLON);
|
| return finishFor(declarations);
|
| }
|
| @@ -1499,18 +1560,10 @@ class MiniJsParser {
|
| }
|
|
|
| ClassExpression parseClass() {
|
| - Identifier name;
|
| - if (acceptCategory(HASH)) {
|
| - var interpolatedName = new InterpolatedIdentifier(parseHash());
|
| - interpolatedValues.add(interpolatedName);
|
| - name = interpolatedName;
|
| - } else {
|
| - name = new Identifier(lastToken);
|
| - expectCategory(ALPHA);
|
| - }
|
| + Identifier name = parseIdentifier();
|
| Expression heritage = null;
|
| if (acceptString('extends')) {
|
| - heritage = parseLeftHandSide();
|
| + heritage = parseConditional();
|
| }
|
| expectCategory(LBRACE);
|
| var methods = new List<Method>();
|
|
|