// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Utilities for building JS ASTs at runtime.  Contains a builder class
// and a parser that parses part of the language.

part of js_ast;


/**
 * Global template manager.  We should aim to have a fixed number of
 * templates. This implies that we do not use js('xxx') to parse text that is
 * constructed from values that depend on names in the Dart program.
 *
 * TODO(sra): Find the remaining places where js('xxx') used to parse an
 * unbounded number of expression, or institute a cache policy.
 */
TemplateManager templateManager = new TemplateManager();


/**

[js] is a singleton instace of JsBuilder.  JsBuilder is a set of conveniences
for constructing JavaScript ASTs.

[string] and [number] are used to create leaf AST nodes:

    var s = js.string('hello');    //  s = new LiteralString('"hello"')
    var n = js.number(123);        //  n = new LiteralNumber(123)

In the line above `a --> b` means Dart expression `a` evaluates to a JavaScript
AST that would pretty-print as `b`.

The [call] method constructs an Expression AST.

No argument

    js('window.alert("hello")')  -->  window.alert("hello")

The input text can contain placeholders `#` that are replaced with provided
arguments.  A single argument can be passed directly:

    js('window.alert(#)', s)   -->  window.alert("hello")

Multiple arguments are passed as a list:

    js('# + #', [s, s])  -->  "hello" + "hello"

The [statement] method constructs a Statement AST, but is otherwise like the
[call] method.  This constructs a Return AST:

    var ret = js.statement('return #;', n);  -->  return 123;

A placeholder in a Statement context must be followed by a semicolon ';'.  You
can think of a statement placeholder as being `#;` to explain why the output
still has one semicolon:

    js.statement('if (happy) #;', ret)
    -->
    if (happy)
      return 123;

If the placeholder is not followed by a semicolon, it is part of an expression.
Here the paceholder is in the position of the function in a function call:

    var vFoo = new Identifier('foo');
    js.statement('if (happy) #("Happy!")', vFoo)
    -->
    if (happy)
      foo("Happy!");

Generally, a placeholder in an expression position requires an Expression AST as
an argument and a placeholder in a statement position requires a Statement AST.
An expression will be converted to a Statement if needed by creating an
ExpessionStatement.  A String argument will be converted into a Identifier and
requires that the string is a JavaScript identifier.

    js('# + 1', vFoo)       -->  foo + 1
    js('# + 1', 'foo')      -->  foo + 1
    js('# + 1', 'foo.bar')  -->  assertion failure

Some placeholder positions are _splicing contexts_.  A function argument list is
a splicing expression context.  A placeholder in a splicing expression context
can take a single Expression (or String, converted to Identifier) or an
Iterable of Expressions (and/or Strings).

    // non-splicing argument:
    js('#(#)', ['say', s])        -->  say("hello")
    // splicing arguments:
    js('#(#)', ['say', []])       -->  say()
    js('#(#)', ['say', [s]])      -->  say("hello")
    js('#(#)', ['say', [s, n]])   -->  say("hello", 123)

A splicing context can be used to append 'lists' and add extra elements:

    js('foo(#, #, 1)', [ ['a', n], s])       -->  foo(a, 123, "hello", 1)
    js('foo(#, #, 1)', [ ['a', n], [s, n]])  -->  foo(a, 123, "hello", 123, 1)
    js('foo(#, #, 1)', [ [], [s, n]])        -->  foo("hello", 123, 1)
    js('foo(#, #, 1)', [ [], [] ])           -->  foo(1)

The generation of a compile-time optional argument expression can be chosen by
providing an empty or singleton list.

In addition to Expressions and Statements, there are Parameters, which occur
only in the parameter list of a function expression or declaration.
Placeholders in parameter positions behave like placeholders in Expression
positions, except only Parameter AST nodes are permitted.  String arguments for
parameter placeholders are converted to Parameter AST nodes.

    var pFoo = new Parameter('foo')
    js('function(#) { return #; }', [pFoo, vFoo])
    -->
    function(foo) { return foo; }

Expressions and Parameters are not compatible with each other's context:

    js('function(#) { return #; }', [vFoo, vFoo]) --> error
    js('function(#) { return #; }', [pFoo, pFoo]) --> error

The parameter context is a splicing context.  When combined with the
context-sensitive conversion of Strings, this simplifies the construction of
trampoline-like functions:

    var args = ['a', 'b'];
    js('function(#) { return f(this, #); }', [args, args])
    -->
    function(a, b) { return f(this, a, b); }

A statement placeholder in a Block is also in a splicing context.  In addition
to splicing Iterables, statement placeholders in a Block will also splice a
Block or an EmptyStatement.  This flattens nested blocks and allows blocks to be
appended.

    var b1 = js.statement('{ 1; 2; }');
    var sEmpty = new Emptystatement();
    js.statement('{ #; #; #; #; }', [sEmpty, b1, b1, sEmpty])
    -->
    { 1; 2; 1; 2; }

A placeholder in the context of an if-statement condition also accepts a Dart
bool argument, which selects the then-part or else-part of the if-statement:

    js.statement('if (#) return;', vFoo)   -->  if (foo) return;
    js.statement('if (#) return;', true)   -->  return;
    js.statement('if (#) return;', false)  -->  ;   // empty statement
    var eTrue = new LiteralBool(true);
    js.statement('if (#) return;', eTrue)  -->  if (true) return;

Combined with block splicing, if-statement condition context placeholders allows
the creation of tenplates that select code depending on variables.

    js.statement('{ 1; if (#) 2; else { 3; 4; } 5;}', true)
    --> { 1; 2; 5; }

    js.statement('{ 1; if (#) 2; else { 3; 4; } 5;}', false)
    --> { 1; 3; 4; 5; }

A placeholder following a period in a property access is in a property access
context.  This is just like an expression context, except String arguments are
converted to JavaScript property accesses.  In JavaScript, `a.b` is short-hand
for `a["b"]`:

    js('a[#]', vFoo)  -->  a[foo]
    js('a[#]', s)     -->  a.hello    (i.e. a["hello"]).
    js('a[#]', 'x')   -->  a[x]

    js('a.#', vFoo)   -->  a[foo]
    js('a.#', s)      -->  a.hello    (i.e. a["hello"])
    js('a.#', 'x')    -->  a.x        (i.e. a["x"])

(Question - should `.#` be restricted to permit only String arguments? The
template should probably be writted with `[]` if non-strings are accepted.)


Object initialiers allow placeholders in the key property name position:

    js('{#:1, #:2}',  [s, 'bye'])    -->  {hello: 1, bye: 2}


What is not implemented:

 -  Array initializers and object initializers could support splicing.  In the
    array case, we would need some way to know if an ArrayInitializer argument
    should be splice or is intended as a single value.

 -  There are no placeholders in definition contexts:

        function #(){}
        var # = 1;

*/
const JsBuilder js = const JsBuilder();


class JsBuilder {
  const JsBuilder();

  /**
   * Parses a bit of JavaScript, and returns an expression.
   *
   * See the MiniJsParser class.
   *
   * [arguments] can be a single [Node] (e.g. an [Expression] or [Statement]) or
   * a list of [Node]s, which will be interpolated into the source at the '#'
   * signs.
   */
  Expression call(String source, [var arguments]) {
    Template template = _findExpressionTemplate(source);
    if (arguments == null) return template.instantiate([]);
    // We allow a single argument to be given directly.
    if (arguments is! List && arguments is! Map) arguments = [arguments];
    return template.instantiate(arguments);
  }

  /**
   * Parses a JavaScript Statement, otherwise just like [call].
   */
  Statement statement(String source, [var arguments]) {
    Template template = _findStatementTemplate(source);
    if (arguments == null) return template.instantiate([]);
    // We allow a single argument to be given directly.
    if (arguments is! List && arguments is! Map) arguments = [arguments];
    return template.instantiate(arguments);
  }

  /**
   * Parses JavaScript written in the `JS` foreign instruction.
   *
   * The [source] must be a JavaScript expression or a JavaScript throw
   * statement.
   */
  Template parseForeignJS(String source) {
    // TODO(sra): Parse with extra validation to forbid `#` interpolation in
    // functions, as this leads to unanticipated capture of temporaries that are
    // reused after capture.
    if (source.startsWith("throw ")) {
      return _findStatementTemplate(source);
    } else {
      return _findExpressionTemplate(source);
    }
  }

  Template _findExpressionTemplate(String source) {
    Template template = templateManager.lookupExpressionTemplate(source);
    if (template == null) {
      MiniJsParser parser = new MiniJsParser(source);
      Expression expression = parser.expression();
      template = templateManager.defineExpressionTemplate(source, expression);
    }
    return template;
  }

  Template _findStatementTemplate(String source) {
    Template template = templateManager.lookupStatementTemplate(source);
    if (template == null) {
      MiniJsParser parser = new MiniJsParser(source);
      Statement statement = parser.statement();
      template = templateManager.defineStatementTemplate(source, statement);
    }
    return template;
  }

  /**
   * Creates an Expression template without caching the result.
   */
  Template uncachedExpressionTemplate(String source) {
    MiniJsParser parser = new MiniJsParser(source);
    Expression expression = parser.expression();
    return new Template(
        source, expression, isExpression: true, forceCopy: false);
  }

  /**
   * Creates a Statement template without caching the result.
   */
  Template uncachedStatementTemplate(String source) {
    MiniJsParser parser = new MiniJsParser(source);
    Statement statement = parser.statement();
    return new Template(
        source, statement, isExpression: false, forceCopy: false);
  }

  /**
   * Create an Expression template which has [ast] as the result.  This is used
   * to wrap a generated AST in a zero-argument Template so it can be passed to
   * context that expects a template.
   */
  Template expressionTemplateYielding(Node ast) {
    return new Template.withExpressionResult(ast);
  }

  Template statementTemplateYielding(Node ast) {
    return new Template.withStatementResult(ast);
  }

  /// Creates a literal js string from [value].
  LiteralString escapedString(String value, [String quote = '"']) {
   // Start by escaping the backslashes.
    String escaped = value.replaceAll('\\', '\\\\');


    // Replace $ in template strings:
    // http://www.ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components
    var quoteReplace = quote == '`' ? r'`$' : quote;

    // http://www.ecma-international.org/ecma-262/6.0/#sec-literals-string-literals
    // > All code points may appear literally in a string literal except for the
    // > closing quote code points, U+005C (REVERSE SOLIDUS),
    // > U+000D (CARRIAGE RETURN), U+2028 (LINE SEPARATOR),
    // > U+2029 (PARAGRAPH SEPARATOR), and U+000A (LINE FEED).
    var re = new RegExp('[\n\r$quoteReplace\b\f\t\v\u2028\u2029]');
    escaped = escaped.replaceAllMapped(re, (m) {
      switch (m.group(0)) {
        case "\n" : return r"\n";
        case "\r" : return r"\r";
        case "\u2028": return r"\u2028";
        case "\u2029": return r"\u2029";
        // Quotes and $ are only replaced if they conflict with the containing
        // quote, see regex above.
        case '"': return r'\"';
        case "'": return r"\'";
        case "`": return r"\`";
        case r"$": return r"\$";
        // TODO(jmesserly): these don't need to be escaped for correctness,
        // but they are conventionally escaped.
        case "\b": return r"\b";
        case "\t": return r"\t";
        case "\f": return r"\f";
        case "\v": return r"\v";
      }
    });
    LiteralString result = new LiteralString('$quote$escaped$quote');
    // We don't escape quotes of a different style under the assumption that the
    // string is wrapped into quotes. Verify that assumption.
    assert(result.value.codeUnitAt(0) == quote.codeUnitAt(0));
    return result;
  }

  /// Creates a literal js string from [value].
  ///
  /// Note that this function only puts quotes around [value]. It does not do
  /// any escaping, so use only when you can guarantee that [value] does not
  /// contain newlines or backslashes. For escaping the string use
  /// [escapedString].
  LiteralString string(String value, [String quote = '"']) =>
      new LiteralString('$quote$value$quote');

  LiteralNumber number(num value) => new LiteralNumber('$value');

  LiteralBool boolean(bool value) => new LiteralBool(value);

  ArrayInitializer numArray(Iterable<int> list) =>
      new ArrayInitializer(list.map(number).toList());

  ArrayInitializer stringArray(Iterable<String> list) =>
      new ArrayInitializer(list.map(string).toList());

  Comment comment(String text) => new Comment(text);
  CommentExpression commentExpression(String text, Expression expression) =>
      new CommentExpression(text, expression);

  Call propertyCall(Expression receiver,
                      String fieldName,
                      List<Expression> arguments) {
    return new Call(new PropertyAccess.field(receiver, fieldName), arguments);
  }
}

LiteralString string(String value) => js.string(value);
LiteralNumber number(num value) => js.number(value);
ArrayInitializer numArray(Iterable<int> list) => js.numArray(list);
ArrayInitializer stringArray(Iterable<String> list) => js.stringArray(list);
Call propertyCall(Expression receiver,
                  String fieldName,
                  List<Expression> arguments) {
  return js.propertyCall(receiver, fieldName, arguments);
}

class MiniJsParserError {
  MiniJsParserError(this.parser, this.message) { }

  final MiniJsParser parser;
  final String message;

  String toString() {
    int pos = parser.lastPosition;

    // Discard lines following the line containing lastPosition.
    String src = parser.src;
    int newlinePos = src.indexOf('\n', pos);
    if (newlinePos >= pos) src = src.substring(0, newlinePos);

    // Extract the prefix of the error line before lastPosition.
    String line = src;
    int lastLineStart = line.lastIndexOf('\n');
    if (lastLineStart >= 0) line = line.substring(lastLineStart + 1);
    String prefix = line.substring(0, pos - (src.length - line.length));

    // Replace non-tabs with spaces, giving a print indent that matches the text
    // for tabbing.
    String spaces = prefix.replaceAll(new RegExp(r'[^\t]'), ' ');
    return 'Error in MiniJsParser:\n${src}\n$spaces^\n$spaces$message\n';
  }
}

/// Mini JavaScript parser for tiny snippets of code that we want to make into
/// AST nodes.  Handles:
/// * identifiers.
/// * dot access.
/// * method calls.
/// * [] access.
/// * array, string, regexp, boolean, null and numeric literals.
/// * most operators.
/// * brackets.
/// * var declarations.
/// * operator precedence.
/// * anonymous funtions and named function expressions and declarations.
/// Notable things it can't do yet include:
/// * some statements are still missing (do-while, while, switch).
///
/// It's a fairly standard recursive descent parser.
///
/// Literal strings are passed through to the final JS source code unchanged,
/// including the choice of surrounding quotes, so if you parse
/// r'var x = "foo\n\"bar\""' you will end up with
///   var x = "foo\n\"bar\"" in the final program.  \x and \u escapes are not
/// allowed in string and regexp literals because the machinery for checking
/// their correctness is rather involved.
class MiniJsParser {
  MiniJsParser(this.src)
      : lastCategory = NONE,
        lastToken = null,
        lastPosition = 0,
        position = 0 {
    getToken();
  }

  int lastCategory = NONE;
  String lastToken = null;
  int lastPosition = 0;
  int position = 0;
  bool skippedNewline = false;  // skipped newline in last getToken?
  final String src;

  final List<InterpolatedNode> interpolatedValues = <InterpolatedNode>[];
  bool get hasNamedHoles =>
      interpolatedValues.isNotEmpty && interpolatedValues.first.isNamed;
  bool get hasPositionalHoles =>
      interpolatedValues.isNotEmpty && interpolatedValues.first.isPositional;

  static const NONE = -1;
  static const ALPHA = 0;
  static const NUMERIC = 1;
  static const STRING = 2;
  static const SYMBOL = 3;
  static const ASSIGNMENT = 4;
  static const DOT = 5;
  static const LPAREN = 6;
  static const RPAREN = 7;
  static const LBRACE = 8;
  static const RBRACE = 9;
  static const LSQUARE = 10;
  static const RSQUARE = 11;
  static const COMMA = 12;
  static const QUERY = 13;
  static const COLON = 14;
  static const SEMICOLON = 15;
  static const ARROW = 16;
  static const ELLIPSIS = 17;
  static const HASH = 18;
  static const WHITESPACE = 19;
  static const OTHER = 20;

  // Make sure that ]] is two symbols.
  // TODO(jmesserly): => and ... are not single char tokens, should we change
  // their numbers? It shouldn't matter because this is only called on values
  // from the [CATEGORIES] table.
  bool singleCharCategory(int category) => category > DOT;

  static String categoryToString(int cat) {
    switch (cat) {
      case NONE: return "NONE";
      case ALPHA: return "ALPHA";
      case NUMERIC: return "NUMERIC";
      case SYMBOL: return "SYMBOL";
      case ASSIGNMENT: return "ASSIGNMENT";
      case DOT: return "DOT";
      case LPAREN: return "LPAREN";
      case RPAREN: return "RPAREN";
      case LBRACE: return "LBRACE";
      case RBRACE: return "RBRACE";
      case LSQUARE: return "LSQUARE";
      case RSQUARE: return "RSQUARE";
      case STRING: return "STRING";
      case COMMA: return "COMMA";
      case QUERY: return "QUERY";
      case COLON: return "COLON";
      case SEMICOLON: return "SEMICOLON";
      case ARROW: return "ARROW";
      case ELLIPSIS: return "ELLIPSIS";
      case HASH: return "HASH";
      case WHITESPACE: return "WHITESPACE";
      case OTHER: return "OTHER";
    }
    return "Unknown: $cat";
  }

  static const CATEGORIES = const <int>[
      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 0-7
      OTHER, WHITESPACE, WHITESPACE, OTHER, OTHER, WHITESPACE,      // 8-13
      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 14-21
      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 22-29
      OTHER, OTHER, WHITESPACE,                                     // 30-32
      SYMBOL, OTHER, HASH, ALPHA, SYMBOL, SYMBOL, OTHER,            // !"#$%&´
      LPAREN, RPAREN, SYMBOL, SYMBOL, COMMA, SYMBOL, DOT, SYMBOL,   // ()*+,-./
      NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC,                  // 01234
      NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC,                  // 56789
      COLON, SEMICOLON, SYMBOL, SYMBOL, SYMBOL, QUERY, OTHER,       // :;<=>?@
      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // ABCDEFGH
      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // IJKLMNOP
      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // QRSTUVWX
      ALPHA, ALPHA, LSQUARE, OTHER, RSQUARE, SYMBOL, ALPHA, OTHER,  // YZ[\]^_'
      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // abcdefgh
      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // ijklmnop
      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // qrstuvwx
      ALPHA, ALPHA, LBRACE, SYMBOL, RBRACE, SYMBOL];                // yz{|}~

  // This must be a >= the highest precedence number handled by parseBinary.
  static var HIGHEST_PARSE_BINARY_PRECEDENCE = 16;
  static bool isAssignment(String symbol) => BINARY_PRECEDENCE[symbol] == 17;

  // From https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence
  static final BINARY_PRECEDENCE = {
      '+=': 17, '-=': 17, '*=': 17, '/=': 17, '%=': 17, '^=': 17, '|=': 17,
      '&=': 17, '<<=': 17, '>>=': 17, '>>>=': 17, '=': 17,
      '||': 14,
      '&&': 13,
      '|': 12,
      '^': 11,
      '&': 10,
      '!=': 9, '==': 9, '!==': 9, '===': 9,
      '<': 8, '<=': 8, '>=': 8, '>': 8, 'in': 8, 'instanceof': 8,
      '<<': 7, '>>': 7, '>>>': 7,
      '+': 6, '-': 6,
      '*': 5, '/': 5, '%': 5
  };
  static final UNARY_OPERATORS =
      ['++', '--', '+', '-', '~', '!', 'typeof', 'void', 'delete', 'await']
        .toSet();

  static final ARROW_TOKEN = '=>';
  static final ELLIPSIS_TOKEN = '...';

  static final OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS =
      ['typeof', 'void', 'delete', 'in', 'instanceof', 'await'].toSet();

  static int category(int code) {
    if (code >= CATEGORIES.length) return OTHER;
    return CATEGORIES[code];
  }

  String getDelimited(int startPosition) {
    position = startPosition;
    int delimiter = src.codeUnitAt(startPosition);
    int currentCode;
    do {
      position++;
      if (position >= src.length) error("Unterminated literal");
      currentCode = src.codeUnitAt(position);
      if (currentCode == charCodes.$LF) error("Unterminated literal");
      if (currentCode == charCodes.$BACKSLASH) {
        if (++position >= src.length) error("Unterminated literal");
        int escaped = src.codeUnitAt(position);
        if (escaped == charCodes.$x || escaped == charCodes.$X ||
            escaped == charCodes.$u || escaped == charCodes.$U ||
            category(escaped) == NUMERIC) {
          error('Numeric and hex escapes are not allowed in literals');
        }
      }
    } while (currentCode != delimiter);
    position++;
    return src.substring(lastPosition, position);
  }

  void getToken() {
    skippedNewline = false;
    for (;;) {
      if (position >= src.length) break;
      int code = src.codeUnitAt(position);
      //  Skip '//' and '/*' style comments.
      if (code == charCodes.$SLASH &&
          position + 1 < src.length) {
        if (src.codeUnitAt(position + 1) == charCodes.$SLASH) {
          int nextPosition = src.indexOf('\n', position);
          if (nextPosition == -1) nextPosition = src.length;
          position = nextPosition;
          continue;
        } else if (src.codeUnitAt(position + 1) == charCodes.$STAR) {
          int nextPosition = src.indexOf('*/', position + 2);
          if (nextPosition == -1) error('Unterminated comment');
          position = nextPosition + 2;
          continue;
        }
      }
      if (category(code) != WHITESPACE) break;
      if (code == charCodes.$LF) skippedNewline = true;
      ++position;
    }

    if (position == src.length) {
      lastCategory = NONE;
      lastToken = null;
      lastPosition = position;
      return;
    }
    int code = src.codeUnitAt(position);
    lastPosition = position;
    if (code == charCodes.$SQ || code == charCodes.$DQ) {
      // String literal.
      lastCategory = STRING;
      lastToken = getDelimited(position);
    } else if (code == charCodes.$0 &&
               position + 2 < src.length &&
               src.codeUnitAt(position + 1) == charCodes.$x) {
      // Hex literal.
      for (position += 2; position < src.length; position++) {
        int cat = category(src.codeUnitAt(position));
        if (cat != NUMERIC && cat != ALPHA) break;
      }
      lastCategory = NUMERIC;
      lastToken = src.substring(lastPosition, position);
      int.parse(lastToken, onError: (_) {
        error("Unparseable number");
      });
    } else if (code == charCodes.$SLASH) {
      // Tokens that start with / are special due to regexp literals.
      lastCategory = SYMBOL;
      position++;
      if (position < src.length && src.codeUnitAt(position) == charCodes.$EQ) {
        position++;
      }
      lastToken = src.substring(lastPosition, position);
    } else {
      // All other tokens handled here.
      int cat = category(src.codeUnitAt(position));
      int newCat;
      do {
        position++;
        if (position == src.length) break;
        int code = src.codeUnitAt(position);
        // Special code to disallow ! and / in non-first position in token, so
        // that !! parses as two tokens and != parses as one, while =/ parses
        // as a an equals token followed by a regexp literal start.
        newCat = (code == charCodes.$BANG || code == charCodes.$SLASH)
            ?  NONE
            : category(code);
      } while (!singleCharCategory(cat) &&
               (cat == newCat ||
                (cat == ALPHA && newCat == NUMERIC) ||    // eg. level42.
                (cat == NUMERIC && newCat == DOT)));      // eg. 3.1415
      lastCategory = cat;
      lastToken = src.substring(lastPosition, position);
      if (cat == NUMERIC) {
        double.parse(lastToken, (_) {
          error("Unparseable number");
        });
      } else if (cat == DOT && lastToken.length > 1) {
        if (lastToken == ELLIPSIS_TOKEN) {
          lastCategory = ELLIPSIS;
        } else {
          error("Unknown operator");
        }
      } else if (cat == SYMBOL) {
        if (lastToken == ARROW_TOKEN) {
          lastCategory = ARROW;
        } else {
          int binaryPrecendence = BINARY_PRECEDENCE[lastToken];
          if (binaryPrecendence == null && !UNARY_OPERATORS.contains(lastToken)) {
            error("Unknown operator");
          }
          if (isAssignment(lastToken)) lastCategory = ASSIGNMENT;
        }
      } else if (cat == ALPHA) {
        if (OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS.contains(lastToken)) {
          lastCategory = SYMBOL;
        }
      }
    }
  }

  void expectCategory(int cat) {
    if (cat != lastCategory) error("Expected ${categoryToString(cat)}");
    getToken();
  }

  bool acceptCategory(int cat) {
    if (cat == lastCategory) {
      getToken();
      return true;
    }
    return false;
  }

  void expectSemicolon() {
    if (acceptSemicolon()) return;
    error('Expected SEMICOLON');
  }

  bool acceptSemicolon() {
    // Accept semicolon or automatically inserted semicolon before close brace.
    // Miniparser forbids other kinds of semicolon insertion.
    if (RBRACE == lastCategory) return true;
    if (NONE == lastCategory) return true;  // end of input
    if (skippedNewline) {
      error('No automatic semicolon insertion at preceding newline');
    }
    return acceptCategory(SEMICOLON);
  }

  bool acceptString(String string) {
    if (lastToken == string) {
      getToken();
      return true;
    }
    return false;
  }

  void error(message) {
    throw new MiniJsParserError(this, message);
  }

  /// Returns either the name for the hole, or its integer position.
  parseHash() {
    String holeName = lastToken;
    if (acceptCategory(ALPHA)) {
      // Named hole. Example: 'function #funName() { ... }'
      if (hasPositionalHoles) {
        error('Holes must all be positional or named. $holeName');
      }
      return holeName;
    } else {
      if (hasNamedHoles) {
        error('Holes must all be positional or named. $holeName');
      }
      int position = interpolatedValues.length;
      return position;
    }
  }

  Expression parsePrimary() {
    String last = lastToken;
    if (acceptCategory(ALPHA)) {
      if (last == "true") {
        return new LiteralBool(true);
      } else if (last == "false") {
        return new LiteralBool(false);
      } else if (last == "null") {
        return new LiteralNull();
      } else if (last == "function") {
        return parseFunctionExpression();
      } else if (last == "this") {
        return new This();
      } else if (last == "super") {
        return new Super();
      } else if (last == "class") {
        return parseClass();
      } else {
        return new Identifier(last);
      }
    } else if (acceptCategory(LPAREN)) {
      return parseExpressionOrArrowFunction();
    } else if (acceptCategory(STRING)) {
      return new LiteralString(last);
    } else if (acceptCategory(NUMERIC)) {
      return new LiteralNumber(last);
    } else if (acceptCategory(LBRACE)) {
      return parseObjectInitializer();
    } else if (acceptCategory(LSQUARE)) {
      var values = <Expression>[];

      while (true) {
        if (acceptCategory(COMMA)) {
          values.add(new ArrayHole());
          continue;
        }
        if (acceptCategory(RSQUARE)) break;
        values.add(parseAssignment());
        if (acceptCategory(RSQUARE)) break;
        expectCategory(COMMA);
      }
      return new ArrayInitializer(values);
    } else if (last != null && last.startsWith("/")) {
      String regexp = getDelimited(lastPosition);
      getToken();
      String flags = lastToken;
      if (!acceptCategory(ALPHA)) flags = "";
      Expression expression = new RegExpLiteral(regexp + flags);
      return expression;
    } else if (acceptCategory(HASH)) {
      return parseInterpolatedExpression();
    } else {
      error("Expected primary expression");
      return null;
    }
  }

  InterpolatedExpression parseInterpolatedExpression() {
    var expression = new InterpolatedExpression(parseHash());
    interpolatedValues.add(expression);
    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 )
   *     ( )
   *     ( ... BindingIdentifier )
   *     ( Expression , ... BindingIdentifier )
   */
  Expression parseExpressionOrArrowFunction() {
    if (acceptCategory(RPAREN)) {
      expectCategory(ARROW);
      return parseArrowFunctionBody(<Parameter>[]);
    }
    if (acceptCategory(ELLIPSIS)) {
      var params = <Parameter>[new RestParameter(parseParameter())];
      expectCategory(RPAREN);
      expectCategory(ARROW);
      return parseArrowFunctionBody(params);
    }
    Expression expression = parseAssignment();
    while (acceptCategory(COMMA)) {
      if (acceptCategory(ELLIPSIS)) {
        var params = <Parameter>[];
        _expressionToParameterList(expression, params);
        params.add(new RestParameter(parseParameter()));
        expectCategory(RPAREN);
        expectCategory(ARROW);
        return parseArrowFunctionBody(params);
      }
      Expression right = parseAssignment();
      expression = new Binary(',', expression, right);
    }
    expectCategory(RPAREN);
    if (acceptCategory(ARROW)) {
      var params = <Parameter>[];
      _expressionToParameterList(expression, params);
      return parseArrowFunctionBody(params);
    }
    return expression;
  }

  /**
   * Converts a parenthesized expression into a list of parameters, issuing an
   * error if the conversion fails.
   */
  void _expressionToParameterList(Expression node, List<Parameter> params) {
    if (node is Identifier) {
      params.add(node);
    } else if (node is Binary && node.op == ',') {
      // TODO(jmesserly): this will allow illegal parens, such as
      // `((a, b), (c, d))`. Fixing it on the left side needs an explicit
      // ParenthesizedExpression node, so we can distinguish
      // `((a, b), c)` from `(a, b, c)`.
      _expressionToParameterList(node.left, params);
      _expressionToParameterList(node.right, params);
    } else if (node is InterpolatedExpression) {
      params.add(new InterpolatedParameter(node.nameOrPosition));
    } else {
      error("Expected arrow function parameter list");
    }
  }

  Expression parseArrowFunctionBody(List<Parameter> params) {
    Node body;
    if (acceptCategory(LBRACE)) {
      body = parseBlock();
    } else {
      body = parseAssignment();
    }
    return new ArrowFun(params, body);
  }

  Expression parseFunctionExpression() {
    String last = lastToken;
    if (acceptCategory(ALPHA)) {
      String functionName = last;
      return new NamedFunction(new Identifier(functionName),
          parseFun());
    }
    return parseFun();
  }

  Expression parseFun() {
    List<Parameter> params = <Parameter>[];

    expectCategory(LPAREN);
    if (!acceptCategory(RPAREN)) {
      for (;;) {
        if (acceptCategory(ELLIPSIS)) {
          params.add(new RestParameter(parseParameter()));
          expectCategory(RPAREN);
          break;
        }

        params.add(parseParameter());
        if (!acceptCategory(COMMA)) {
          expectCategory(RPAREN);
          break;
        }
      }
    }
    AsyncModifier asyncModifier;
    if (acceptString('async')) {
      if (acceptString('*')) {
        asyncModifier = const AsyncModifier.asyncStar();
      } else {
        asyncModifier = const AsyncModifier.async();
      }
    } else if (acceptString('sync')) {
      if (!acceptString('*')) error("Only sync* is valid - sync is implied");
      asyncModifier = const AsyncModifier.syncStar();
    } else {
      asyncModifier = const AsyncModifier.sync();
    }
    expectCategory(LBRACE);
    Block block = parseBlock();
    return new Fun(params, block, asyncModifier: asyncModifier);
  }

  /** Parse parameter name or interpolated parameter. */
  Identifier parseParameter() {
    if (acceptCategory(HASH)) {
      var nameOrPosition = parseHash();
      var parameter = new InterpolatedParameter(nameOrPosition);
      interpolatedValues.add(parameter);
      return parameter;
    } else {
      // TODO(jmesserly): validate this is not a keyword
      String argumentName = lastToken;
      expectCategory(ALPHA);
      return new Identifier(argumentName);
    }
  }

  Expression parseObjectInitializer() {
    List<Property> properties = <Property>[];
    for (;;) {
      if (acceptCategory(RBRACE)) break;
      // Limited subset of ES6 object initializers.
      //
      // PropertyDefinition :
      //     PropertyName : AssignmentExpression
      //     MethodDefinition
      properties.add(parseMethodOrProperty());

      if (acceptCategory(RBRACE)) break;
      expectCategory(COMMA);
    }
    return new ObjectInitializer(properties);
  }

  Expression parseMember() {
    Expression receiver = parsePrimary();
    while (true) {
      if (acceptCategory(DOT)) {
        receiver = getDotRhs(receiver);
      } else if (acceptCategory(LSQUARE)) {
        Expression inBraces = parseExpression();
        expectCategory(RSQUARE);
        receiver = new PropertyAccess(receiver, inBraces);
      } else {
        break;
      }
    }
    return receiver;
  }

  Expression parseCall() {
    bool constructor = acceptString("new");
    Expression receiver = parseMember();
    while (true) {
      if (acceptCategory(LPAREN)) {
        final arguments = <Expression>[];
        if (!acceptCategory(RPAREN)) {
          while (true) {
            if (acceptCategory(ELLIPSIS)) {
              arguments.add(new Spread(parseAssignment()));
              expectCategory(RPAREN);
              break;
            }
            arguments.add(parseAssignment());
            if (acceptCategory(RPAREN)) break;
            expectCategory(COMMA);
          }
        }
        receiver = constructor ?
               new New(receiver, arguments) :
               new Call(receiver, arguments);
        constructor = false;
      } else if (!constructor && acceptCategory(LSQUARE)) {
        Expression inBraces = parseExpression();
        expectCategory(RSQUARE);
        receiver = new PropertyAccess(receiver, inBraces);
      } else if (!constructor && acceptCategory(DOT)) {
        receiver = getDotRhs(receiver);
      } else {
        // JS allows new without (), but we don't.
        if (constructor) error("Parentheses are required for new");
        break;
      }
    }
    return receiver;
  }

  Expression getDotRhs(Expression receiver) {
    if (acceptCategory(HASH)) {
      var nameOrPosition = parseHash();
      InterpolatedSelector property = new InterpolatedSelector(nameOrPosition);
      interpolatedValues.add(property);
      return new PropertyAccess(receiver, property);
    }
    String identifier = lastToken;
    // In ES5 keywords like delete and continue are allowed as property
    // names, and the IndexedDB API uses that, so we need to allow it here.
    if (acceptCategory(SYMBOL)) {
      if (!OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS.contains(identifier)) {
        error("Expected alphanumeric identifier");
      }
    } else {
      expectCategory(ALPHA);
    }
    return new PropertyAccess.field(receiver, identifier);
  }

  Expression parsePostfix() {
    Expression expression = parseCall();
    String operator = lastToken;
    // JavaScript grammar is:
    //     LeftHandSideExpression [no LineTerminator here] ++
    if (lastCategory == SYMBOL &&
        !skippedNewline &&
        (acceptString("++") || acceptString("--"))) {
      return new Postfix(operator, expression);
    }
    // If we don't accept '++' or '--' due to skippedNewline a newline, no other
    // part of the parser will accept the token and we will get an error at the
    // whole expression level.
    return expression;
  }

  Expression parseUnaryHigh() {
    String operator = lastToken;
    if (lastCategory == SYMBOL && UNARY_OPERATORS.contains(operator) &&
        (acceptString("++") || acceptString("--") || acceptString('await'))) {
      if (operator == "await") return new Await(parsePostfix());
      return new Prefix(operator, parsePostfix());
    }
    return parsePostfix();
  }

  Expression parseUnaryLow() {
    String operator = lastToken;
    if (lastCategory == SYMBOL && UNARY_OPERATORS.contains(operator) &&
        operator != "++" && operator != "--") {
      expectCategory(SYMBOL);
      if (operator == "await") return new Await(parsePostfix());
      return new Prefix(operator, parseUnaryLow());
    }
    return parseUnaryHigh();
  }

  Expression parseBinary(int maxPrecedence) {
    Expression lhs = parseUnaryLow();
    int minPrecedence;
    String lastSymbol;
    Expression rhs;  // This is null first time around.
    while (true) {
      String symbol = lastToken;
      if (lastCategory != SYMBOL ||
          !BINARY_PRECEDENCE.containsKey(symbol) ||
          BINARY_PRECEDENCE[symbol] > maxPrecedence) {
        break;
      }
      expectCategory(SYMBOL);
      if (rhs == null || BINARY_PRECEDENCE[symbol] >= minPrecedence) {
        if (rhs != null) lhs = new Binary(lastSymbol, lhs, rhs);
        minPrecedence = BINARY_PRECEDENCE[symbol];
        rhs = parseUnaryLow();
        lastSymbol = symbol;
      } else {
        Expression higher = parseBinary(BINARY_PRECEDENCE[symbol]);
        rhs = new Binary(symbol, rhs, higher);
      }
    }
    if (rhs == null) return lhs;
    return new Binary(lastSymbol, lhs, rhs);
  }

  Expression parseConditional() {
    Expression lhs = parseBinary(HIGHEST_PARSE_BINARY_PRECEDENCE);
    if (!acceptCategory(QUERY)) return lhs;
    Expression ifTrue = parseAssignment();
    expectCategory(COLON);
    Expression ifFalse = parseAssignment();
    return new Conditional(lhs, ifTrue, ifFalse);
  }

  Expression parseLeftHandSide() => parseConditional();

  Expression parseAssignment() {
    Expression lhs = parseLeftHandSide();
    String assignmentOperator = lastToken;
    if (acceptCategory(ASSIGNMENT)) {
      Expression rhs = parseAssignment();
      if (assignmentOperator == "=") {
        return new Assignment(lhs, rhs);
      } else  {
        // Handle +=, -=, etc.
        String operator =
            assignmentOperator.substring(0, assignmentOperator.length - 1);
        return new Assignment.compound(lhs, operator, rhs);
      }
    }
    return lhs;
  }

  Expression parseExpression() {
    Expression expression = parseAssignment();
    while (acceptCategory(COMMA)) {
      Expression right = parseAssignment();
      expression = new Binary(',', expression, right);
    }
    return expression;
  }

  /** Parse a variable declaration list, with `var` or `let` [keyword] */
  VariableDeclarationList parseVariableDeclarationList(
      String keyword, [String firstIdentifier])  {
    var initialization = <VariableInitialization>[];

    do {
      var declarator;
      if (firstIdentifier != null) {
        declarator = new Identifier(firstIdentifier);
        firstIdentifier = null;
      } else {
        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;
    }
  }

  /// 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();
    }
  }

  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");

      if (acceptString("=")) {
        defaultValue = parseExpression();
      }
      variables.add(new DestructuredVariable(
          name: name, structure: structure, defaultValue: defaultValue));
    } while (acceptCategory(COMMA));

    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() {
    var keyword = acceptVarLetOrConst();
    if (keyword != null) {
      return parseVariableDeclarationList(keyword);
    } else {
      return parseExpression();
    }
  }

  /** Accepts a `var` or `let` keyword. If neither is found, returns null. */
  String acceptVarLetOrConst() {
    if (acceptString('var')) return 'var';
    if (acceptString('let')) return 'let';
    if (acceptString('const')) return 'const';
    return null;
  }

  Expression expression() {
    Expression expression = parseVarDeclarationOrExpression();
    if (lastCategory != NONE || position != src.length) {
      error("Unparsed junk: ${categoryToString(lastCategory)}");
    }
    return expression;
  }

  Statement statement() {
    Statement statement = parseStatement();
    if (lastCategory != NONE || position != src.length) {
      error("Unparsed junk: ${categoryToString(lastCategory)}");
    }
    // TODO(sra): interpolated capture here?
    return statement;
  }

  Block parseBlock() {
    List<Statement> statements = <Statement>[];

    while (!acceptCategory(RBRACE)) {
      Statement statement = parseStatement();
      statements.add(statement);
    }
    return new Block(statements);
  }

  Statement parseStatement() {
    if (acceptCategory(LBRACE)) return parseBlock();

    if (acceptCategory(SEMICOLON)) return new EmptyStatement();

    if (lastCategory == ALPHA) {
      if (acceptString('return')) return parseReturn();

      if (acceptString('throw')) return parseThrow();

      if (acceptString('break')) {
        return parseBreakOrContinue((label) => new Break(label));
      }

      if (acceptString('continue')) {
        return parseBreakOrContinue((label) => new Continue(label));
      }

      if (acceptString('if')) return parseIfThenElse();

      if (acceptString('for')) return parseFor();

      if (acceptString('function')) return parseFunctionDeclaration();

      if (acceptString('class')) return new ClassDeclaration(parseClass());

      if (acceptString('try')) return parseTry();

      var keyword = acceptVarLetOrConst();
      if (keyword != null) {
        Expression declarations = parseVariableDeclarationList(keyword);
        expectSemicolon();
        return new ExpressionStatement(declarations);
      }

      if (acceptString('while')) return parseWhile();

      if (acceptString('do')) return parseDo();

      if (acceptString('switch')) return parseSwitch();

      if (lastToken == 'case') error("Case outside switch.");

      if (lastToken == 'default') error("Default outside switch.");

      if (lastToken == 'yield') return parseYield();

      if (lastToken == 'with') {
        error('Not implemented in mini parser');
      }

    }

    bool checkForInterpolatedStatement = lastCategory == HASH;

    Expression expression = parseExpression();

    if (expression is Identifier && acceptCategory(COLON)) {
      return new LabeledStatement(expression.name, parseStatement());
    }

    expectSemicolon();

    if (checkForInterpolatedStatement) {
      // 'Promote' the interpolated expression `#;` to an interpolated
      // statement.
      if (expression is InterpolatedExpression) {
        assert(identical(interpolatedValues.last, expression));
        InterpolatedStatement statement =
            new InterpolatedStatement(expression.nameOrPosition);
        interpolatedValues[interpolatedValues.length - 1] = statement;
        return statement;
      }
    }

    return new ExpressionStatement(expression);
  }

  Statement parseReturn() {
    if (acceptSemicolon()) return new Return();
    Expression expression = parseExpression();
    expectSemicolon();
    return new Return(expression);
  }

  Statement parseYield() {
    bool hasStar = acceptString('*');
    Expression expression = parseExpression();
    expectSemicolon();
    return new DartYield(expression, hasStar);
  }

  Statement parseThrow() {
    if (skippedNewline) error('throw expression must be on same line');
    Expression expression = parseExpression();
    expectSemicolon();
    return new Throw(expression);
  }

  Statement parseBreakOrContinue(constructor) {
    var identifier = lastToken;
    if (!skippedNewline && acceptCategory(ALPHA)) {
      expectSemicolon();
      return constructor(identifier);
    }
    expectSemicolon();
    return constructor(null);
  }

  Statement parseIfThenElse() {
    expectCategory(LPAREN);
    Expression condition = parseExpression();
    expectCategory(RPAREN);
    Statement thenStatement = parseStatement();
    if (acceptString('else')) {
      // Resolves dangling else by binding 'else' to closest 'if'.
      Statement elseStatement = parseStatement();
      return new If(condition, thenStatement, elseStatement);
    } else {
      return new If.noElse(condition, thenStatement);
    }
  }

  Statement parseFor() {
    // For-init-condition-increment style loops are fully supported.
    //
    // Only one for-in variant is currently implemented:
    //
    //     for (var variable in Expression) Statement
    //
    // One variant of ES6 for-of is also implemented:
    //
    //     for (let variable of Expression) Statement
    //
    Statement finishFor(Expression init) {
      Expression condition = null;
      if (!acceptCategory(SEMICOLON)) {
        condition = parseExpression();
        expectCategory(SEMICOLON);
      }
      Expression update = null;
      if (!acceptCategory(RPAREN)) {
        update = parseExpression();
        expectCategory(RPAREN);
      }
      Statement body = parseStatement();
      return new For(init, condition, update, body);
    }

    expectCategory(LPAREN);
    if (acceptCategory(SEMICOLON)) {
      return finishFor(null);
    }

    var keyword = acceptVarLetOrConst();
    if (keyword != null) {
      String identifier = lastToken;
      expectCategory(ALPHA);

      if (acceptString('in')) {
        Expression objectExpression = parseExpression();
        expectCategory(RPAREN);
        Statement body = parseStatement();
        return new ForIn(
            _createVariableDeclarationList(keyword, identifier),
            objectExpression,
            body);
      } else if (acceptString('of')) {
        Expression iterableExpression = parseAssignment();
        expectCategory(RPAREN);
        Statement body = parseStatement();
        return new ForOf(
            _createVariableDeclarationList(keyword, identifier),
            iterableExpression,
            body);
      }
      var declarations = parseVariableDeclarationList(keyword, identifier);
      expectCategory(SEMICOLON);
      return finishFor(declarations);
    }

    Expression init = parseExpression();
    expectCategory(SEMICOLON);
    return finishFor(init);
  }

  static VariableDeclarationList _createVariableDeclarationList(
      String keyword, String identifier) {
    return new VariableDeclarationList(keyword, [
        new VariableInitialization(
            new Identifier(identifier), null)]);
  }

  Statement parseFunctionDeclaration() {
    String name = lastToken;
    expectCategory(ALPHA);
    Expression fun = parseFun();
    return new FunctionDeclaration(new Identifier(name), fun);
  }

  Statement parseTry() {
    expectCategory(LBRACE);
    Block body = parseBlock();
    Catch catchPart = null;
    if (acceptString('catch')) catchPart = parseCatch();
    Block finallyPart = null;
    if (acceptString('finally')) {
      expectCategory(LBRACE);
      finallyPart = parseBlock();
    } else {
      if (catchPart == null) error("expected 'finally'");
    }
    return new Try(body, catchPart, finallyPart);
  }

  SwitchClause parseSwitchClause() {
    Expression expression = null;
    if (acceptString('case')) {
      expression = parseExpression();
      expectCategory(COLON);
    } else {
      if (!acceptString('default')) {
        error('expected case or default');
      }
      expectCategory(COLON);
    }
    var statements = <Statement>[];
    while (lastCategory != RBRACE &&
           lastToken != 'case' &&
           lastToken != 'default') {
      statements.add(parseStatement());
    }
    return expression == null
        ? new Default(new Block(statements))
        : new Case(expression, new Block(statements));
  }

  Statement parseWhile() {
    expectCategory(LPAREN);
    Expression condition = parseExpression();
    expectCategory(RPAREN);
    Statement body = parseStatement();
    return new While(condition, body);
  }

  Statement parseDo() {
    Statement body = parseStatement();
    if (lastToken != "while") error("Missing while after do body.");
    getToken();
    expectCategory(LPAREN);
    Expression condition = parseExpression();
    expectCategory(RPAREN);
    expectSemicolon();
    return new Do(body, condition);
  }

  Statement parseSwitch() {
    expectCategory(LPAREN);
    Expression key = parseExpression();
    expectCategory(RPAREN);
    expectCategory(LBRACE);
    List<SwitchClause> clauses = new List<SwitchClause>();
    while(lastCategory != RBRACE) {
      clauses.add(parseSwitchClause());
    }
    expectCategory(RBRACE);
    return new Switch(key, clauses);
  }

  Catch parseCatch() {
    expectCategory(LPAREN);
    String identifier = lastToken;
    expectCategory(ALPHA);
    expectCategory(RPAREN);
    expectCategory(LBRACE);
    Block body = parseBlock();
    return new Catch(new Identifier(identifier), body);
  }

  ClassExpression parseClass() {
    Identifier name = parseIdentifier();
    Expression heritage = null;
    if (acceptString('extends')) {
      heritage = parseConditional();
    }
    expectCategory(LBRACE);
    var methods = new List<Method>();
    while (lastCategory != RBRACE) {
      methods.add(parseMethodOrProperty(onlyMethods: true));
    }
    expectCategory(RBRACE);
    return new ClassExpression(name, heritage, methods);
  }

  /**
   * Parses a [Method] or a [Property].
   *
   * Most of the complexity is from supporting interpolation. Several forms
   * are supported:
   *
   * - getter/setter names: `get #() { ... }`
   * - method names: `#() { ... }`
   * - property names: `#: ...`
   * - entire methods: `#`
   */
  Property parseMethodOrProperty({bool onlyMethods: false}) {
    bool isStatic = acceptString('static');

    bool isGetter = lastToken == 'get';
    bool isSetter = lastToken == 'set';
    Expression name = null;
    if (isGetter || isSetter) {
      var token = lastToken;
      getToken();
      if (lastCategory == COLON) {
        // That wasn't a accessor but the 'get' or 'set' property: retropedal.
        isGetter = isSetter = false;
        name = new LiteralString('"$token"');
      }
    }
    if (acceptCategory(HASH)) {
      if (lastCategory != LPAREN && (onlyMethods || lastCategory != COLON)) {
        // Interpolated method
        var member = new InterpolatedMethod(parseHash());
        interpolatedValues.add(member);
        return member;
      }
      name = parseInterpolatedExpression();
    } else {
      name ??= parsePropertyName();
    }

    if (!onlyMethods && acceptCategory(COLON)) {
      Expression value = parseAssignment();
      return new Property(name, value);
    } else {
      var fun = parseFun();
      return new Method(name, fun,
          isGetter: isGetter, isSetter: isSetter, isStatic: isStatic);
    }
  }

  Expression parsePropertyName() {
    String identifier = lastToken;
    if (acceptCategory(STRING)) {
      return new LiteralString(identifier);
    } else if (acceptCategory(ALPHA) || acceptCategory(SYMBOL)) {
      // ALPHA or a SYMBOL, e.g. void
      return new LiteralString('"$identifier"');
    } else if (acceptCategory(LSQUARE)) {
      var expr = parseAssignment();
      expectCategory(RSQUARE);
      return expr;
    } else if (acceptCategory(HASH)) {
      return parseInterpolatedExpression();
    } else {
      error('Expected property name');
      return null;
    }
  }
}
