// 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.
library;

import 'characters.dart' as char_codes;
import 'nodes.dart';
import 'template.dart';

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

/// [js] is a singleton instance 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 ';'.
/// One 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 placeholder is in the position of the function in a
/// function call:
///
///     var vFoo = new VariableUse('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 ExpressionStatement. A String argument will be converted into a
/// VariableUse 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 VariableUse)
/// 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 templates 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 written with `[]` if non-strings are accepted.)
///
///
/// Object initializers 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.
const JsBuilder js = 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);
    arguments ??= [];
    // We allow a single argument to be given directly.
    if (arguments is! List && arguments is! Map) arguments = [arguments];
    return template.instantiate(arguments) as Expression;
  }

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

  /// 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 = 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 = MiniJsParser(source);
      Statement statement = parser.statement();
      template = templateManager.defineStatementTemplate(source, statement);
    }
    return template;
  }

  /// Creates an Expression template for the given [source].
  ///
  /// The returned template is cached.
  Template expressionTemplateFor(String source) {
    return _findExpressionTemplate(source);
  }

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

  /// Creates a Statement template without caching the result.
  Template uncachedStatementTemplate(String source) {
    MiniJsParser parser = MiniJsParser(source);
    Statement statement = parser.statement();
    return 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(Expression ast) {
    return Template.withExpressionResult(ast);
  }

  Template statementTemplateYielding(Statement ast) {
    return Template.withStatementResult(ast);
  }

  /// Creates a literal js string from [value].
  LiteralString string(String value) => LiteralString(value);

  StringConcatenation concatenateStrings(Iterable<Literal> parts) {
    return StringConcatenation(List.of(parts, growable: false));
  }

  Iterable<Literal> joinLiterals(
    Iterable<Literal> items,
    Literal separator,
  ) sync* {
    bool first = true;
    for (final item in items) {
      if (!first) yield separator;
      yield item;
      first = false;
    }
  }

  LiteralString quoteName(Name name) {
    return LiteralStringFromName(name);
  }

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

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

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

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

  Comment comment(String text) => Comment(text);

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

  ObjectInitializer objectLiteral(Map<String, Expression> map) {
    List<Property> properties = [];
    map.forEach((name, value) {
      properties.add(Property(string(name), value));
    });
    return ObjectInitializer(properties);
  }
}

LiteralString string(String value) => js.string(value);

/// Returns a LiteralString which has contents determined by [Name].
///
/// This is used to force a Name to be a string literal regardless of
/// context. It is not necessary for properties.
LiteralString quoteName(Name name) => js.quoteName(name);

Iterable<Literal> joinLiterals(Iterable<Literal> list, Literal separator) {
  return js.joinLiterals(list, separator);
}

StringConcatenation concatenateStrings(Iterable<Literal> parts) {
  return js.concatenateStrings(parts);
}

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,
  Expression fieldName,
  List<Expression> arguments,
) {
  return js.propertyCall(receiver, fieldName, arguments);
}

ObjectInitializer objectLiteral(Map<String, Expression> map) {
  return js.objectLiteral(map);
}

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

  final MiniJsParser parser;
  final String message;

  @override
  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(RegExp(r'[^\t]'), ' ');
    return 'Error in MiniJsParser:\n$src\n$spaces^\n$spaces$message\n';
  }
}

enum _Category {
  none,
  alpha,
  numeric,
  string,
  symbol,
  assignment,
  dot,
  lparen,
  rparen,
  lbrace,
  rbrace,
  lsquare,
  rsquare,
  comma,
  query,
  colon,
  semicolon,
  arrow,
  hash,
  whitespace,
  other;

  static const _asciiTable = <_Category>[
    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, // yx{|}~
  ];
}

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

  _Category _lastCategory = _Category.none;
  String lastToken = '';
  int lastPosition = 0;
  int position = 0;
  bool skippedNewline = false; // skipped newline in last getToken?
  final String src;

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

  // Make sure that ]] is two symbols.
  bool _singleCharCategory(_Category category) =>
      category.index >= _Category.dot.index;

  // 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,
    '=': 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,
    '**': 4,
  };
  static final UNARY_OPERATORS = {
    '++',
    '--',
    '+',
    '-',
    '~',
    '!',
    'typeof',
    'void',
    'delete',
    'await',
  };

  static final OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS = {
    'typeof',
    'void',
    'delete',
    'in',
    'instanceof',
    'await',
  };

  static _Category _category(int code) {
    if (code >= _Category._asciiTable.length) return _Category.other;
    return _Category._asciiTable[code];
  }

  String getRegExp(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 == char_codes.$LF) error('Unterminated literal');
      if (currentCode == char_codes.$BACKSLASH) {
        if (++position >= src.length) error('Unterminated literal');
        int escaped = src.codeUnitAt(position);
        if (escaped == char_codes.$x ||
            escaped == char_codes.$X ||
            escaped == char_codes.$u ||
            escaped == char_codes.$U ||
            _category(escaped) == _Category.numeric) {
          error('Numeric and hex escapes are not supported in RegExp literals');
        }
      }
    } while (currentCode != delimiter);
    position++;
    return src.substring(lastPosition, position);
  }

  String getString(int startPosition, int quote) {
    assert(src.codeUnitAt(startPosition) == quote);
    position = startPosition + 1;
    final value = StringBuffer();
    while (true) {
      if (position >= src.length) error('Unterminated literal');
      int code = src.codeUnitAt(position++);
      if (code == quote) break;
      if (code == char_codes.$LF) error('Unterminated literal');
      if (code == char_codes.$BACKSLASH) {
        if (position >= src.length) error('Unterminated literal');
        code = src.codeUnitAt(position++);
        if (code == char_codes.$f) {
          value.writeCharCode(12);
        } else if (code == char_codes.$n) {
          value.writeCharCode(10);
        } else if (code == char_codes.$r) {
          value.writeCharCode(13);
        } else if (code == char_codes.$t) {
          value.writeCharCode(8);
        } else if (code == char_codes.$BACKSLASH ||
            code == char_codes.$SQ ||
            code == char_codes.$DQ) {
          value.writeCharCode(code);
        } else if (code == char_codes.$x || code == char_codes.$X) {
          error('Hex escapes not supported in string literals');
        } else if (code == char_codes.$u || code == char_codes.$U) {
          error('Unicode escapes not supported in string literals');
        } else if (char_codes.$0 <= code && code <= char_codes.$9) {
          error('Numeric escapes not supported in string literals');
        } else {
          error('Unknown escape U+${code.toRadixString(16).padLeft(4, '0')}');
        }
        continue;
      }
      value.writeCharCode(code);
    }
    return value.toString();
  }

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

    if (position == src.length) {
      _lastCategory = _Category.none;
      lastToken = '';
      lastPosition = position;
      return;
    }
    int code = src.codeUnitAt(position);
    lastPosition = position;
    if (code == char_codes.$SQ || code == char_codes.$DQ) {
      // String literal.
      _lastCategory = _Category.string;
      lastToken = getString(position, code);
    } else if (code == char_codes.$0 &&
        position + 2 < src.length &&
        src.codeUnitAt(position + 1) == char_codes.$x) {
      // Hex literal.
      for (position += 2; position < src.length; position++) {
        final cat = _category(src.codeUnitAt(position));
        if (cat != _Category.numeric && cat != _Category.alpha) break;
      }
      _lastCategory = _Category.numeric;
      lastToken = src.substring(lastPosition, position);
      if (int.tryParse(lastToken) == null) {
        error('Unparseable number');
      }
    } else if (code == char_codes.$SLASH) {
      // Tokens that start with / are special due to regexp literals.
      _lastCategory = _Category.symbol;
      position++;
      if (position < src.length && src.codeUnitAt(position) == char_codes.$EQ) {
        position++;
      }
      lastToken = src.substring(lastPosition, position);
    } else {
      // All other tokens handled here.
      final cat = _category(src.codeUnitAt(position));
      _Category 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 !! and ~~ parse as two tokens and != parses as one, while =/
        // parses as a an equals token followed by a regexp literal start.
        newCat =
            (code == char_codes.$BANG ||
                code == char_codes.$SLASH ||
                code == char_codes.$TILDE)
            ? _Category.none
            : _category(code);
      } while (!_singleCharCategory(cat) &&
          (cat == newCat ||
              (cat == _Category.alpha &&
                  newCat == _Category.numeric) || // eg. level42.
              (cat == _Category.numeric &&
                  newCat == _Category.dot))); // eg. 3.1415
      _lastCategory = cat;
      lastToken = src.substring(lastPosition, position);
      if (cat == _Category.numeric) {
        if (double.tryParse(lastToken) == null) {
          error('Unparseable number');
        }
      } else if (cat == _Category.symbol) {
        if (lastToken == '=>') {
          _lastCategory = _Category.arrow;
        } else {
          int? binaryPrecedence = BINARY_PRECEDENCE[lastToken];
          if (binaryPrecedence == null &&
              !UNARY_OPERATORS.contains(lastToken)) {
            error('Unknown operator');
          }
          if (isAssignment(lastToken)) _lastCategory = _Category.assignment;
        }
      } else if (cat == _Category.alpha) {
        if (OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS.contains(lastToken)) {
          _lastCategory = _Category.symbol;
        }
      }
    }
  }

  void _expectCategory(_Category cat) {
    if (cat != _lastCategory) error('Expected $cat');
    getToken();
  }

  bool _acceptCategory(_Category 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 (_Category.rbrace == _lastCategory) return true;
    if (_Category.none == _lastCategory) return true; // end of input
    if (skippedNewline) {
      error('No automatic semicolon insertion at preceding newline');
    }
    return _acceptCategory(_Category.semicolon);
  }

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

  Never error(String message) {
    throw MiniJsParserError(this, message);
  }

  /// Returns either the name for the hole, or its integer position.
  Object parseHash() {
    String holeName = lastToken;
    if (_acceptCategory(_Category.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(_Category.alpha)) {
      if (last == 'true') {
        return LiteralBool(true);
      } else if (last == 'false') {
        return LiteralBool(false);
      } else if (last == 'null') {
        return LiteralNull();
      } else if (last == 'function') {
        return parseFunctionExpression();
      } else if (last == 'this') {
        return This();
      } else {
        return VariableUse(last);
      }
    } else if (_acceptCategory(_Category.lparen)) {
      return parseExpressionOrArrowFunction();
    } else if (_acceptCategory(_Category.string)) {
      return LiteralString(last);
    } else if (_acceptCategory(_Category.numeric)) {
      return LiteralNumber(last);
    } else if (_acceptCategory(_Category.lbrace)) {
      return parseObjectInitializer();
    } else if (_acceptCategory(_Category.lsquare)) {
      var values = <Expression>[];
      while (true) {
        if (_acceptCategory(_Category.comma)) {
          values.add(ArrayHole());
          continue;
        }
        if (_acceptCategory(_Category.rsquare)) break;
        values.add(parseAssignment());
        if (_acceptCategory(_Category.rsquare)) break;
        _expectCategory(_Category.comma);
      }
      return ArrayInitializer(values);
    } else if (last.startsWith('/')) {
      String regexp = getRegExp(lastPosition);
      getToken();
      String flags = lastToken;
      if (!_acceptCategory(_Category.alpha)) flags = '';
      Expression expression = RegExpLiteral(regexp + flags);
      return expression;
    } else if (_acceptCategory(_Category.hash)) {
      var nameOrPosition = parseHash();
      InterpolatedExpression expression = InterpolatedExpression(
        nameOrPosition,
      );
      interpolatedValues.add(expression);
      return expression;
    } else {
      error('Expected primary expression');
    }
  }

  Expression parseFunctionExpression() {
    if (_lastCategory == _Category.alpha || _lastCategory == _Category.hash) {
      Declaration name = parseVariableDeclaration();
      return NamedFunction(name, parseFun());
    }
    return parseFun();
  }

  Fun parseFun() {
    List<Parameter> params = [];
    _expectCategory(_Category.lparen);
    if (!_acceptCategory(_Category.rparen)) {
      for (;;) {
        if (_acceptCategory(_Category.hash)) {
          var nameOrPosition = parseHash();
          InterpolatedParameter parameter = InterpolatedParameter(
            nameOrPosition,
          );
          interpolatedValues.add(parameter);
          params.add(parameter);
        } else {
          String argumentName = lastToken;
          _expectCategory(_Category.alpha);
          params.add(Parameter(argumentName));
        }
        if (_acceptCategory(_Category.comma)) continue;
        _expectCategory(_Category.rparen);
        break;
      }
    }
    AsyncModifier asyncModifier;
    if (acceptString('async')) {
      if (acceptString('*')) {
        asyncModifier = AsyncModifier.asyncStar;
      } else {
        asyncModifier = AsyncModifier.async;
      }
    } else if (acceptString('sync')) {
      if (!acceptString('*')) error('Only sync* is valid - sync is implied');
      asyncModifier = AsyncModifier.syncStar;
    } else {
      asyncModifier = AsyncModifier.sync;
    }
    _expectCategory(_Category.lbrace);
    Block block = parseBlock();
    return Fun(params, block, asyncModifier: asyncModifier);
  }

  Expression parseObjectInitializer() {
    List<Property> properties = [];
    for (;;) {
      if (_acceptCategory(_Category.rbrace)) break;
      properties.add(parseMethodDefinitionOrProperty());
      if (_acceptCategory(_Category.rbrace)) break;
      _expectCategory(_Category.comma);
    }
    return ObjectInitializer(properties);
  }

  Property parseMethodDefinitionOrProperty() {
    // Limited subset: keys are identifiers, no 'get' or 'set' properties.
    Literal propertyName;
    String identifier = lastToken;
    if (_acceptCategory(_Category.alpha)) {
      propertyName = LiteralString(identifier);
    } else if (_acceptCategory(_Category.string)) {
      propertyName = LiteralString(identifier);
    } else if (_acceptCategory(_Category.symbol)) {
      // e.g. void
      propertyName = LiteralString(identifier);
    } else if (_acceptCategory(_Category.hash)) {
      var nameOrPosition = parseHash();
      InterpolatedLiteral interpolatedLiteral = InterpolatedLiteral(
        nameOrPosition,
      );
      interpolatedValues.add(interpolatedLiteral);
      propertyName = interpolatedLiteral;
    } else {
      error('Expected property name');
    }
    if (_acceptCategory(_Category.colon)) {
      Expression value = parseAssignment();
      return Property(propertyName, value);
    } else {
      final fun = parseFun();
      return MethodDefinition(propertyName, fun);
    }
  }

  Expression parseMember() {
    Expression receiver = parsePrimary();
    while (true) {
      if (_acceptCategory(_Category.dot)) {
        receiver = getDotRhs(receiver);
      } else if (_acceptCategory(_Category.lsquare)) {
        Expression inBraces = parseExpression();
        _expectCategory(_Category.rsquare);
        receiver = PropertyAccess(receiver, inBraces);
      } else {
        break;
      }
    }
    return receiver;
  }

  Expression parseCall() {
    bool constructor = acceptString('new');
    Expression receiver = parseMember();
    while (true) {
      if (_acceptCategory(_Category.lparen)) {
        final arguments = <Expression>[];
        if (!_acceptCategory(_Category.rparen)) {
          while (true) {
            Expression argument = parseAssignment();
            arguments.add(argument);
            if (_acceptCategory(_Category.rparen)) break;
            _expectCategory(_Category.comma);
          }
        }
        receiver = constructor
            ? New(receiver, arguments)
            : Call(receiver, arguments);
        constructor = false;
      } else if (!constructor && _acceptCategory(_Category.lsquare)) {
        Expression inBraces = parseExpression();
        _expectCategory(_Category.rsquare);
        receiver = PropertyAccess(receiver, inBraces);
      } else if (!constructor && _acceptCategory(_Category.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(_Category.hash)) {
      var nameOrPosition = parseHash();
      InterpolatedSelector property = InterpolatedSelector(nameOrPosition);
      interpolatedValues.add(property);
      return 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(_Category.symbol)) {
      if (!OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS.contains(identifier)) {
        error('Expected alphanumeric identifier');
      }
    } else {
      _expectCategory(_Category.alpha);
    }
    return PropertyAccess.field(receiver, identifier);
  }

  Expression parsePostfix() {
    Expression expression = parseCall();
    String operator = lastToken;
    // JavaScript grammar is:
    //     LeftHandSideExpression [no LineTerminator here] ++
    if (_lastCategory == _Category.symbol &&
        !skippedNewline &&
        (acceptString('++') || acceptString('--'))) {
      return 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 == _Category.symbol &&
        UNARY_OPERATORS.contains(operator) &&
        (acceptString('++') || acceptString('--') || acceptString('await'))) {
      if (operator == 'await') return Await(parsePostfix());
      return Prefix(operator, parsePostfix());
    }
    return parsePostfix();
  }

  Expression parseUnaryLow() {
    String operator = lastToken;
    if (_lastCategory == _Category.symbol &&
        UNARY_OPERATORS.contains(operator) &&
        operator != '++' &&
        operator != '--') {
      _expectCategory(_Category.symbol);
      if (operator == 'await') return Await(parsePostfix());
      return Prefix(operator, parseUnaryLow());
    }
    return parseUnaryHigh();
  }

  Expression parseBinary(int maxPrecedence) {
    Expression lhs = parseUnaryLow();
    Expression? rhs; // This is null first time around.
    late int minPrecedence;
    late String lastSymbol;

    while (true) {
      final symbol = lastToken;
      if (_lastCategory != _Category.symbol) break;
      final symbolPrecedence = BINARY_PRECEDENCE[symbol];
      if (symbolPrecedence == null) break;
      if (symbolPrecedence > maxPrecedence) break;

      _expectCategory(_Category.symbol);
      if (rhs == null || symbolPrecedence >= minPrecedence) {
        if (rhs != null) lhs = Binary(lastSymbol, lhs, rhs);
        minPrecedence = symbolPrecedence;
        rhs = parseUnaryLow();
        lastSymbol = symbol;
      } else {
        Expression higher = parseBinary(symbolPrecedence);
        rhs = Binary(symbol, rhs, higher);
      }
    }

    if (rhs == null) return lhs;
    return Binary(lastSymbol, lhs, rhs);
  }

  Expression parseConditional() {
    Expression lhs = parseBinary(HIGHEST_PARSE_BINARY_PRECEDENCE);
    if (!_acceptCategory(_Category.query)) return lhs;
    Expression ifTrue = parseAssignment();
    _expectCategory(_Category.colon);
    Expression ifFalse = parseAssignment();
    return Conditional(lhs, ifTrue, ifFalse);
  }

  Expression parseAssignment() {
    Expression lhs = parseConditional();
    String assignmentOperator = lastToken;
    if (_acceptCategory(_Category.assignment)) {
      Expression rhs = parseAssignment();
      if (assignmentOperator == '=') {
        return Assignment(lhs, rhs);
      } else {
        // Handle +=, -=, etc.
        String operator = assignmentOperator.substring(
          0,
          assignmentOperator.length - 1,
        );
        return Assignment.compound(lhs, operator, rhs);
      }
    }
    return lhs;
  }

  Expression parseExpression() {
    Expression expression = parseAssignment();
    while (_acceptCategory(_Category.comma)) {
      Expression right = parseAssignment();
      expression = Binary(',', expression, right);
    }
    return expression;
  }

  Expression parseExpressionOrArrowFunction() {
    if (_acceptCategory(_Category.rparen)) {
      _expectCategory(_Category.arrow);
      return parseArrowFunctionBody([]);
    }
    List<Expression> expressions = [parseAssignment()];
    while (_acceptCategory(_Category.comma)) {
      expressions.add(parseAssignment());
    }
    _expectCategory(_Category.rparen);
    if (_acceptCategory(_Category.arrow)) {
      var params = <Parameter>[];
      for (Expression e in expressions) {
        if (e is VariableUse) {
          params.add(Parameter(e.name));
        } else if (e is InterpolatedExpression) {
          params.add(InterpolatedParameter(e.nameOrPosition));
        } else {
          error('Expected arrow function parameter list');
        }
      }
      return parseArrowFunctionBody(params);
    }
    return expressions.reduce(
      (Expression value, Expression element) => Binary(',', value, element),
    );
  }

  Expression parseArrowFunctionBody(List<Parameter> params) {
    Node body;
    if (_acceptCategory(_Category.lbrace)) {
      body = parseBlock();
    } else {
      body = parseAssignment();
    }
    return ArrowFunction(params, body);
  }

  VariableDeclarationList parseVariableDeclarationList() {
    Declaration firstVariable = parseVariableDeclaration();
    return finishVariableDeclarationList(firstVariable);
  }

  VariableDeclarationList finishVariableDeclarationList(
    Declaration firstVariable,
  ) {
    var initialization = <VariableInitialization>[];

    void declare(Declaration declaration) {
      Expression? initializer;
      if (acceptString('=')) {
        initializer = parseAssignment();
      }
      initialization.add(VariableInitialization(declaration, initializer));
    }

    declare(firstVariable);
    while (_acceptCategory(_Category.comma)) {
      Declaration variable = parseVariableDeclaration();
      declare(variable);
    }
    return VariableDeclarationList(initialization);
  }

  Expression parseVarDeclarationOrExpression() {
    if (acceptString('var')) {
      return parseVariableDeclarationList();
    } else {
      return parseExpression();
    }
  }

  Expression expression() {
    Expression expression = parseVarDeclarationOrExpression();
    if (_lastCategory != _Category.none || position != src.length) {
      error('Unparsed junk: $_lastCategory');
    }
    return expression;
  }

  Statement statement() {
    Statement statement = parseStatement();
    if (_lastCategory != _Category.none || position != src.length) {
      error('Unparsed junk: $_lastCategory');
    }
    // TODO(sra): interpolated capture here?
    return statement;
  }

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

    while (!_acceptCategory(_Category.rbrace)) {
      Statement statement = parseStatement();
      statements.add(statement);
    }
    return Block(statements);
  }

  Statement parseStatement() {
    if (_acceptCategory(_Category.lbrace)) return parseBlock();

    if (_acceptCategory(_Category.semicolon)) return EmptyStatement();

    if (_lastCategory == _Category.alpha) {
      if (acceptString('return')) return parseReturn();

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

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

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

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

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

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

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

      if (acceptString('var')) {
        Expression declarations = parseVariableDeclarationList();
        expectSemicolon();
        return 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 == _Category.hash;

    Expression expression = parseExpression();

    if (expression is VariableUse && _acceptCategory(_Category.colon)) {
      return 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 = InterpolatedStatement(
          expression.nameOrPosition,
        );
        interpolatedValues[interpolatedValues.length - 1] = statement;
        return statement;
      }
    }

    return ExpressionStatement(expression);
  }

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

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

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

  Statement parseBreakOrContinue(Statement Function(String?) constructor) {
    var identifier = lastToken;
    if (!skippedNewline && _acceptCategory(_Category.alpha)) {
      expectSemicolon();
      return constructor(identifier);
    }
    expectSemicolon();
    return constructor(null);
  }

  Statement parseIfThenElse() {
    _expectCategory(_Category.lparen);
    Expression condition = parseExpression();
    _expectCategory(_Category.rparen);
    Statement thenStatement = parseStatement();
    if (acceptString('else')) {
      // Resolves dangling else by binding 'else' to closest 'if'.
      Statement elseStatement = parseStatement();
      return If(condition, thenStatement, elseStatement);
    } else {
      return 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
    //
    Statement finishFor(Expression? init) {
      Expression? condition;
      if (!_acceptCategory(_Category.semicolon)) {
        condition = parseExpression();
        _expectCategory(_Category.semicolon);
      }
      Expression? update;
      if (!_acceptCategory(_Category.rparen)) {
        update = parseExpression();
        _expectCategory(_Category.rparen);
      }
      Statement body = parseStatement();
      return For(init, condition, update, body);
    }

    _expectCategory(_Category.lparen);
    if (_acceptCategory(_Category.semicolon)) {
      return finishFor(null);
    }

    if (acceptString('var')) {
      Declaration declaration = parseVariableDeclaration();
      if (acceptString('in')) {
        Expression objectExpression = parseExpression();
        _expectCategory(_Category.rparen);
        Statement body = parseStatement();
        return ForIn(
          VariableDeclarationList([VariableInitialization(declaration, null)]),
          objectExpression,
          body,
        );
      }
      Expression declarations = finishVariableDeclarationList(declaration);
      _expectCategory(_Category.semicolon);
      return finishFor(declarations);
    }

    Expression init = parseExpression();
    _expectCategory(_Category.semicolon);
    return finishFor(init);
  }

  Declaration parseVariableDeclaration() {
    if (_acceptCategory(_Category.hash)) {
      var nameOrPosition = parseHash();
      InterpolatedDeclaration declaration = InterpolatedDeclaration(
        nameOrPosition,
      );
      interpolatedValues.add(declaration);
      return declaration;
    } else {
      String token = lastToken;
      _expectCategory(_Category.alpha);
      return VariableDeclaration(token);
    }
  }

  Statement parseFunctionDeclaration() {
    Declaration name = parseVariableDeclaration();
    Fun fun = parseFun();
    return FunctionDeclaration(name, fun);
  }

  Statement parseTry() {
    _expectCategory(_Category.lbrace);
    Block body = parseBlock();
    Catch? catchPart;
    if (acceptString('catch')) catchPart = parseCatch();
    Block? finallyPart;
    if (acceptString('finally')) {
      _expectCategory(_Category.lbrace);
      finallyPart = parseBlock();
    } else {
      if (catchPart == null) error("expected 'finally'");
    }
    return Try(body, catchPart, finallyPart);
  }

  SwitchClause parseSwitchClause() {
    Expression? expression;
    if (acceptString('case')) {
      expression = parseExpression();
      _expectCategory(_Category.colon);
    } else {
      if (!acceptString('default')) {
        error('expected case or default');
      }
      _expectCategory(_Category.colon);
    }
    List<Statement> statements = [];
    while (_lastCategory != _Category.rbrace &&
        lastToken != 'case' &&
        lastToken != 'default') {
      statements.add(parseStatement());
    }
    return expression == null
        ? Default(Block(statements))
        : Case(expression, Block(statements));
  }

  Statement parseWhile() {
    _expectCategory(_Category.lparen);
    Expression condition = parseExpression();
    _expectCategory(_Category.rparen);
    Statement body = parseStatement();
    return While(condition, body);
  }

  Statement parseDo() {
    Statement body = parseStatement();
    if (lastToken != 'while') error('Missing while after do body.');
    getToken();
    _expectCategory(_Category.lparen);
    Expression condition = parseExpression();
    _expectCategory(_Category.rparen);
    expectSemicolon();
    return Do(body, condition);
  }

  Statement parseSwitch() {
    _expectCategory(_Category.lparen);
    Expression key = parseExpression();
    _expectCategory(_Category.rparen);
    _expectCategory(_Category.lbrace);
    List<SwitchClause> clauses = [];
    while (_lastCategory != _Category.rbrace) {
      clauses.add(parseSwitchClause());
    }
    _expectCategory(_Category.rbrace);
    return Switch(key, clauses);
  }

  Catch parseCatch() {
    _expectCategory(_Category.lparen);
    Declaration errorName = parseVariableDeclaration();
    _expectCategory(_Category.rparen);
    _expectCategory(_Category.lbrace);
    Block body = parseBlock();
    return Catch(errorName, body);
  }
}
