// Copyright (c) 2014, 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.

library dart_printer_test;

import 'dart:mirrors';
import 'package:expect/expect.dart';
import 'package:compiler/src/constants/values.dart';
import 'package:compiler/src/dart_backend/backend_ast_nodes.dart';
import 'package:compiler/src/dart_backend/backend_ast_to_frontend_ast.dart'
    show TreePrinter;
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/diagnostics/messages.dart';
import 'package:compiler/src/diagnostics/spannable.dart' show Spannable;
import 'package:compiler/src/parser/listener.dart';
import 'package:compiler/src/parser/parser.dart';
import 'package:compiler/src/scanner/scanner.dart';
import 'package:compiler/src/tokens/token.dart';
import 'package:compiler/src/tokens/token_constants.dart';
import 'package:compiler/src/io/source_file.dart';
import 'package:compiler/src/string_validator.dart';
import 'package:compiler/src/tree/tree.dart' show DartString;
import 'package:compiler/src/tree/tree.dart' as tree;
import '../options_helper.dart';

/// For debugging the [AstBuilder] stack. Prints information about [x].
void show(x) {
  StringBuffer buf = new StringBuffer();
  Unparser unparser = new Unparser(buf);
  void unparse(x) {
    if (x is Expression)
      unparser.writeExpression(x);
    else if (x is TypeAnnotation)
      unparser.writeType(x);
    else if (x is Statement)
      unparser.writeStatement(x);
    else if (x is List) {
      buf.write('[');
      bool first = true;
      for (var y in x) {
        if (first)
          first = false;
        else
          buf.write(', ');
        unparse(y);
      }
      buf.write(']');
    }
  }
  unparse(x);
  print("${x.runtimeType}: ${buf.toString()}");
}

class PrintDiagnosticListener implements DiagnosticReporter {
  void log(message) {
    print(message);
  }

  void internalError(Spannable spannable, message) {
    print(message);
  }

  SourceSpan spanFromSpannable(Spannable node) {
    return new SourceSpan(null, 0, 0);
  }

  void reportFatalError(Spannable node, MessageKind errorCode,
                        [Map arguments = const {}]) {
    print(errorCode);
    throw new Error();
  }

  void reportError(Spannable node, MessageKind errorCode,
                   [Map arguments = const {}]) {
    print(errorCode);
  }

  void reportWarning(Spannable node, MessageKind errorCode,
                     [Map arguments = const {}]) {
    print(errorCode);
  }

  void reportHint(Spannable node, MessageKind errorCode,
                  [Map arguments = const {}]) {
    print(errorCode);
  }

  void reportInfo(Spannable node, MessageKind errorCode,
                  [Map arguments = const {}]) {
    print(errorCode);
  }

  withCurrentElement(element, f()) {
    f();
  }
}

class AstBuilder extends Listener {
  final List stack = [];
  final StringValidator stringValidator
         = new StringValidator(new PrintDiagnosticListener());

  String asName(e) {
    if (e is Identifier)
      return e.name;
    else if (e == null)
      return null;
    else
      throw 'Expression is not a name: ${e.runtimeType}';
  }

  TypeAnnotation asType(x) {
    if (x is TypeAnnotation)
      return x;
    if (x is Identifier)
      return new TypeAnnotation(x.name);
    if (x == null)
      return null;
    else
      throw "Not a type: ${x.runtimeType}";
  }

  Parameter asParameter(x) {
    if (x is Parameter)
      return x;
    if (x is Identifier)
      return new Parameter(x.name);
    else
      throw "Not a parameter: ${x.runtimeType}";
  }

  void push(node) {
    stack.add(node);
  }
  dynamic peek() {
    return stack.last;
  }
  dynamic pop([coerce(x) = null]) {
    var x = stack.removeLast();
    if (coerce != null)
      return coerce(x);
    else
      return x;
  }
  List popList(int count, [List result, coerce(x) = null]) {
    if (result == null)
      result = <Node>[];
    for (int i=0; i<count; i++) {
      var x = stack[stack.length-count+i];
      if (coerce != null) {
        x = coerce(x);
      }
      result.add(x);
    }
    stack.removeRange(stack.length-count, stack.length);
    return result;
  }
  popTypeAnnotation() {
    List<TypeAnnotation> args = pop();
    if (args == null)
      return null;
    String name = pop(asName);
    return new TypeAnnotation(name, args);
  }

  // EXPRESSIONS
  endCascade() {
    throw "Cascade not supported yet";
  }
  endIdentifierList(int count) {
    push(popList(count, <Identifier>[]));
  }
  endTypeList(int count) {
    push(popList(count, <TypeAnnotation>[], asType));
  }
  beginLiteralString(Token token) {
    String source = token.value;
    tree.StringQuoting quoting = StringValidator.quotingFromString(source);
    push(quoting);
    push(token); // collect token at the end
  }
  handleStringPart(Token token) {
    push(token); // collect token at the end
  }
  endLiteralString(int interpCount) {
    List parts = popList(2 * interpCount + 1, []);
    tree.StringQuoting quoting = pop();
    List<Expression> members = <Expression>[];
    for (var i=0; i<parts.length; i++) {
      var part = parts[i];
      if (part is Expression) {
        members.add(part);
      } else {
        assert(part is Token);
        DartString str = stringValidator.validateInterpolationPart(
            part as Token,
            quoting,
            isFirst: i == 0,
            isLast: i == parts.length - 1);
        members.add(new Literal(new StringConstantValue(str)));
      }
    }
    push(new StringConcat(members));
  }
  handleStringJuxtaposition(int litCount) {
    push(new StringConcat(popList(litCount, <Expression>[])));
  }
  endArguments(int count, begin, end) {
    push(popList(count, <Argument>[]));
  }
  handleNoArguments(token) {
    push(null);
  }
  handleNoTypeArguments(token) {
    push(<TypeAnnotation>[]);
  }
  endTypeArguments(int count, t, y) {
    List<TypeAnnotation> args = <TypeAnnotation>[];
    for (var i=0; i<count; i++) {
      args.add(popTypeAnnotation());
    }
    push(args.reversed.toList(growable:false));
  }
  handleVoidKeyword(token) {
    push(new Identifier("void"));
    push(<TypeAnnotation>[]); // prepare for popTypeAnnotation
  }
  handleQualified(Token period) {
    String last = pop(asName);
    String first = pop(asName);
    push(new Identifier('$first.$last'));
  }
  endSend(t) {
    List<Argument> arguments = pop();
    pop(); // typeArguments
    if (arguments == null)
      return; // not a function call
    Expression selector = pop();
    push(new CallFunction(selector, arguments));
  }
  endThrowExpression(t, tt) {
    push(new Throw(pop()));
  }
  handleAssignmentExpression(Token token) {
    Expression right = pop();
    Expression left = pop();
    push(new Assignment(left, token.value, right));
  }
  handleBinaryExpression(Token token) {
    Expression right = pop();
    Receiver left = pop();
    String tokenString = token.stringValue;
    if (tokenString == '.') {
      if (right is CallFunction) {
        String name = (right.callee as Identifier).name;
        push(new CallMethod(left, name, right.arguments));
      } else {
        push(new FieldExpression(left, (right as Identifier).name));
      }
    } else {
      push(new BinaryOperator(left, tokenString, right));
    }
  }
  handleConditionalExpression(question, colon) {
    Expression elseExpression = pop();
    Expression thenExpression = pop();
    Expression condition = pop();
    push(new Conditional(condition, thenExpression, elseExpression));
  }
  handleIdentifier(Token t) {
    push(new Identifier(t.value));
  }
  handleOperator(t) {
    push(new Identifier(t.value));
  }
  handleIndexedExpression(open, close) {
    Expression index = pop();
    Receiver object = pop();
    push(new IndexExpression(object, index));
  }
  handleIsOperator(operathor, not, endToken) {
    TypeAnnotation type = popTypeAnnotation();
    Expression exp = pop();
    TypeOperator r = new TypeOperator(exp, 'is', type);
    if (not != null) {
      push(new UnaryOperator('!', r));
    } else {
      push(r);
    }
  }
  handleAsOperator(operathor, endToken) {
    TypeAnnotation type = popTypeAnnotation();
    Expression exp = pop();
    push(new TypeOperator(exp, 'as', type));
  }
  handleLiteralBool(Token t) {
    bool value = t.value == 'true';
    push(new Literal(
        value ? new TrueConstantValue() : new FalseConstantValue()));
  }
  handleLiteralDouble(t) {
    push(new Literal(new DoubleConstantValue(double.parse(t.value))));
  }
  handleLiteralInt(Token t) {
    push(new Literal(new IntConstantValue(int.parse(t.value))));
  }
  handleLiteralNull(t) {
    push(new Literal(new NullConstantValue()));
  }
  endLiteralSymbol(Token hash, int idCount) {
    List<Identifier> ids = popList(idCount, <Identifier>[]);
    push(new LiteralSymbol(ids.map((id) => id.name).join('.')));
  }
  handleLiteralList(int count, begin, constKeyword, end) {
    List<Expression> exps = popList(count, <Expression>[]);
    List<TypeAnnotation> types = pop();
    assert(types.length <= 1);
    push(new LiteralList(exps,
      isConst: constKeyword != null,
      typeArgument: types.length == 0 ? null : types[0]
    ));
  }
  handleLiteralMap(int count, begin, constKeyword, end) {
    List<LiteralMapEntry> entries = popList(count, <LiteralMapEntry>[]);
    List<TypeAnnotation> types = pop();
    assert(types.length == 0 || types.length == 2);
    push(new LiteralMap(entries,
        isConst: constKeyword != null,
        typeArguments: types
    ));
  }
  endLiteralMapEntry(colon, endToken) {
    Expression value = pop();
    Expression key = pop();
    push(new LiteralMapEntry(key,value));
  }
  handleNamedArgument(colon) {
    Expression exp = pop();
    Identifier name = pop();
    push(new NamedArgument(name.name, exp));
  }
  endConstructorReference(Token start, Token period, Token end) {
    if (period == null) {
      push(null); // indicate missing constructor name
    }
  }
  handleNewExpression(t) {
    List<Argument> args = pop();
    String constructorName = pop(asName);
    TypeAnnotation type = popTypeAnnotation();
    push(new CallNew(type, args, constructorName: constructorName));
  }
  handleConstExpression(t) {
    List<Argument> args = pop();
    String constructorName = pop(asName);
    TypeAnnotation type = popTypeAnnotation();
    push(new CallNew(type, args, constructorName: constructorName,
                     isConst:true));
  }
  handleParenthesizedExpression(t) {
    // do nothing, just leave expression on top of stack
  }
  handleSuperExpression(t) {
    push(new SuperReceiver());
  }
  handleThisExpression(t) {
    push(new This());
  }
  handleUnaryPostfixAssignmentExpression(Token t) {
    push(new Increment.postfix(pop(), t.value));
  }
  handleUnaryPrefixAssignmentExpression(Token t) {
    push(new Increment.prefix(pop(), t.value));
  }
  handleUnaryPrefixExpression(Token t) {
    push(new UnaryOperator(t.value, pop()));
  }

  handleFunctionTypedFormalParameter(tok) {
    // handled in endFormalParameter
  }
  endFormalParameter(thisKeyword) {
    Expression defaultValue = null;
    var x = pop();
    if (x is DefaultValue) {
      defaultValue = x.expression;
      x = pop();
    }
    if (x is Parameters) {
      String name = pop(asName);
      TypeAnnotation returnType = popTypeAnnotation();
      push(new Parameter.function(name, returnType, x, defaultValue));
    } else {
      String name = asName(x);
      TypeAnnotation type = popTypeAnnotation();
      push(new Parameter(name, type:type, defaultValue:defaultValue));
    }
  }
  handleValuedFormalParameter(eq, tok) {
    push(new DefaultValue(pop()));
  }
  endOptionalFormalParameters(int count, begin, end) {
    bool isNamed = end.value == '}';
    push(popList(count, <Parameter>[], asParameter));
    push(isNamed); // Indicate optional parameters to endFormalParameters.
  }
  endFormalParameters(count, begin, end) {
    if (count == 0) {
      push(new Parameters([]));
      return;
    }
    var last = pop();   // Detect if optional parameters are present.
    if (last is bool) { // See endOptionalFormalParameters.
      List<Parameter> optional = pop();
      List<Parameter> required = popList(count-1, <Parameter>[], asParameter);
      push(new Parameters(required, optional, last));
    } else {
      // No optional parameters.
      List<Parameter> required = popList(count-1, <Parameter>[], asParameter);
      required.add(last);
      push(new Parameters(required));
    }
  }
  handleNoFormalParameters(tok) {
    push(new Parameters([]));
  }

  endUnnamedFunction(t) {
    Statement body = pop();
    Parameters parameters = pop();
    push(new FunctionExpression(parameters, body));
  }

  handleNoType(Token token) {
    push(null);
  }

  endReturnStatement(bool hasExpression, begin, end) {
    // This is also called for functions whose body is "=> expression"
    if (hasExpression) {
      push(new Return(pop()));
    } else {
      push(new Return());
    }
  }

  endExpressionStatement(Token token) {
    push(new ExpressionStatement(pop()));
  }

  endDoWhileStatement(Token doKeyword, Token whileKeyword, Token end) {
    Expression condition = pop();
    Statement body = pop();
    push(new DoWhile(body, condition));
  }

  endWhileStatement(Token whileKeyword, Token end) {
    Statement body = pop();
    Expression condition = pop();
    push(new While(condition, body));
  }

  endBlock(int count, Token begin, Token end) {
    push(new Block(popList(count, <Statement>[])));
  }

  endRethrowStatement(Token throwToken, Token endToken) {
    push(new Rethrow());
  }

  endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
    Statement finallyBlock = null;
    if (finallyKeyword != null) {
      finallyBlock = pop();
    }
    List<CatchBlock> catchBlocks = popList(catchCount, <CatchBlock>[]);
    Statement tryBlock = pop();
    push(new Try(tryBlock, catchBlocks, finallyBlock));
  }

  void handleCatchBlock(Token onKeyword, Token catchKeyword) {
    Statement block = pop();
    String exceptionVar = null;
    String stackVar = null;
    if (catchKeyword != null) {
      Parameters params = pop();
      exceptionVar = params.requiredParameters[0].name;
      if (params.requiredParameters.length > 1) {
        stackVar = params.requiredParameters[1].name;
      }
    }
    TypeAnnotation type = onKeyword == null ? null : pop();
    push(new CatchBlock(block,
      onType: type,
      exceptionVar: exceptionVar,
      stackVar: stackVar
    ));
  }

  endSwitchStatement(Token switchKeyword, Token end) {
    List<SwitchCase> cases = pop();
    Expression expression = pop();
    push(new Switch(expression, cases));
  }

  endSwitchBlock(int caseCount, Token begin, Token end) {
    push(popList(caseCount, <SwitchCase>[]));
  }

  handleSwitchCase(int labelCount, int caseCount, Token defaultKeyword,
                   int statementCount, Token first, Token end) {
    List<Statement> statements = popList(statementCount, <Statement>[]);
    List<Expression> cases = popList(caseCount, <Expression>[]);
    if (defaultKeyword != null) {
      cases = null;
    }
    push(new SwitchCase(cases, statements));
  }

  handleCaseMatch(Token caseKeyword, Token colon) {
    // do nothing, leave case expression on stack
  }

  handleBreakStatement(bool hasTarget, Token breakKeyword, Token end) {
    String target = hasTarget ? pop(asName) : null;
    push(new Break(target));
  }

  handleContinueStatement(bool hasTarget, Token continueKeyword, Token end) {
    String target = hasTarget ? pop(asName) : null;
    push(new Continue(target));
  }

  handleEmptyStatement(Token token) {
    push(new EmptyStatement());
  }


  VariableDeclaration asVariableDeclaration(x) {
    if (x is VariableDeclaration)
      return x;
    if (x is Identifier)
      return new VariableDeclaration(x.name);
    throw "Not a variable definition: ${x.runtimeType}";
  }

  endVariablesDeclaration(int count, Token end) {
    List<VariableDeclaration> variables =
        popList(count, <VariableDeclaration>[], asVariableDeclaration);
    TypeAnnotation type = popTypeAnnotation();
    push(new VariableDeclarations(variables,
      type: type,
      isFinal: false, // TODO(asgerf): Parse modifiers.
      isConst: false
    ));
  }

  endInitializer(Token assign) {
    Expression init = pop();
    String name = pop(asName);
    push(new VariableDeclaration(name, init));
  }

  endIfStatement(Token ifToken, Token elseToken) {
    Statement elsePart = (elseToken == null) ? null : pop();
    Statement thenPart = pop();
    Expression condition = pop();
    push(new If(condition, thenPart, elsePart));
  }

  endForStatement(int updateCount, Token begin, Token end) {
    Statement body = pop();
    List<Expression> updates = popList(updateCount, <Expression>[]);
    ExpressionStatement condition = pop(); // parsed as expression statement
    Expression exp = condition == null ? null : condition.expression;
    Node initializer = pop();
    push(new For(initializer, exp, updates, body));
  }

  handleNoExpression(Token token) {
    push(null);
  }

  endForIn(Token await, Token begin, Token inKeyword, Token end) {
    Statement body = pop();
    Expression exp = pop();
    Node declaredIdentifier = pop();
    push(new ForIn(declaredIdentifier, exp, body));
  }

  handleAssertStatement(Token assertKeyword,
                        Token commaToken, Token semicolonToken) {
    Expression message;
    if (commaToken != null) message = pop();
    Expression exp = pop();
    var arguments = [exp];
    if (message != null) arguments.add(message);
    Expression call = new CallFunction(new Identifier("assert"), arguments);
    push(new ExpressionStatement(call));
  }

  endLabeledStatement(int labelCount) {
    Statement statement = pop();
    for (int i=0; i<labelCount; i++) {
      String label = pop(asName);
      statement = new LabeledStatement(label, statement);
    }
    push(statement);
  }

  endFunctionDeclaration(Token end) {
    Statement body = pop();
    Parameters parameters = pop();
    String name = pop(asName);
    TypeAnnotation returnType = popTypeAnnotation();
    push(new FunctionDeclaration(new FunctionExpression(parameters, body,
        name: name,
        returnType: returnType)));
  }

  endFunctionBody(int count, Token begin, Token end) {
    push(new Block(popList(count, <Statement>[])));
  }
}

class DefaultValue {
  final Expression expression;
  DefaultValue(this.expression);
}

/// Compares ASTs for structural equality.
void checkDeepEqual(x, y) {
  if (x is List && y is List) {
    if (x.length != y.length)
      return;
    for (var i=0; i<x.length; i++) {
      checkDeepEqual(x[i], y[i]);
    }
  }
  else if (x is Node && y is Node) {
    if (x.runtimeType != y.runtimeType)
      throw new Error();
    InstanceMirror xm = reflect(x);
    InstanceMirror ym = reflect(y);
    for (Symbol name in xm.type.instanceMembers.keys) {
      if (reflectClass(Object).declarations.containsKey(name)) {
        continue; // do not check things from Object, such as hashCode
      }
      MethodMirror mm = xm.type.instanceMembers[name];
      if (mm.isGetter) {
        var xv = xm.getField(name).reflectee;
        var yv = ym.getField(name).reflectee;
        checkDeepEqual(xv,yv);
      }
    }
  }
  else if (x is PrimitiveConstantValue && y is PrimitiveConstantValue) {
    checkDeepEqual(x.primitiveValue, y.primitiveValue);
  }
  else if (x is DartString && y is DartString) {
    if (x.slowToString() != y.slowToString()) {
      throw new Error();
    }
  }
  else {
    if (x != y) {
      throw new Error();
    }
  }
}

Expression parseExpression(String code) {
  SourceFile file = new StringSourceFile.fromName('', code);
  Scanner scan = new Scanner(file);
  Token tok = scan.tokenize();
  AstBuilder builder = new AstBuilder();
  Parser parser = new Parser(builder, new MockParserOptions());
  tok = parser.parseExpression(tok);
  if (builder.stack.length != 1 || tok.kind != EOF_TOKEN) {
    throw "Parse error in $code";
  }
  return builder.pop();
}
Statement parseStatement(String code) {
  SourceFile file = new StringSourceFile.fromName('', code);
  Scanner scan = new Scanner(file);
  Token tok = scan.tokenize();
  AstBuilder builder = new AstBuilder();
  Parser parser = new Parser(builder, new MockParserOptions());
  tok = parser.parseStatement(tok);
  if (builder.stack.length != 1 || tok.kind != EOF_TOKEN) {
    throw "Parse error in $code";
  }
  return builder.pop();
}

String unparseExpression(Expression exp) {
  StringBuffer buf = new StringBuffer();
  new Unparser(buf).writeExpression(exp);
  return buf.toString();
}
String unparseStatement(Statement stmt) {
  StringBuffer buf = new StringBuffer();
  new Unparser(buf).writeStatement(stmt);
  return buf.toString();
}

/// Converts [exp] to an instance of the frontend AST and unparses that.
String frontUnparseExpression(Expression exp) {
  tree.Node node = new TreePrinter().makeExpression(exp);
  return tree.unparse(node);
}
/// Converts [stmt] to an instance of the frontend AST and unparses that.
String frontUnparseStatement(Statement stmt) {
  tree.Node node = new TreePrinter().makeStatement(stmt);
  return tree.unparse(node);
}

/// Parses [code], unparses the resulting AST, then parses the unparsed text.
/// The ASTs from the first and second parse are then compared for structural
/// equality. Alternatively, if [expected] is not an empty string, the second
/// parse must match the AST of parsing [expected].
void checkFn(String code, String expected, Function parse, Function unparse) {
  var firstParse = parse(code);
  String unparsed = unparse(firstParse);
  try {
    var secondParse = parse(unparsed);
    var baseline = expected == "" ? firstParse : parse(expected);
    checkDeepEqual(baseline, secondParse);
  } catch (e, stack) {
    Expect.fail('"$code" was unparsed as "$unparsed"');
  }
}

void checkExpression(String code, [String expected="", String expected2=""]) {
  checkFn(code, expected, parseExpression, unparseExpression);
  checkFn(code, expected2, parseExpression, frontUnparseExpression);
}
void checkStatement(String code, [String expected="", String expected2=""]) {
  checkFn(code, expected, parseStatement, unparseStatement);
  checkFn(code, expected2, parseStatement, frontUnparseStatement);
}

void debugTokens(String code) {
  SourceFile file = new StringSourceFile.fromName('', code);
  Scanner scan = new Scanner(file);
  Token tok = scan.tokenize();
  while (tok.next != tok) {
    print(tok.toString());
    tok = tok.next;
  }
}

void main() {
  // To check if these tests are effective, one should manually alter
  // something in [Unparser] and see if a test fails.

  checkExpression(" a +  b  + c");
  checkExpression("(a +  b) + c");
  checkExpression(" a + (b  + c)");

  checkExpression(" a +  b  - c");
  checkExpression("(a +  b) - c");
  checkExpression(" a + (b  - c)");

  checkExpression(" a -  b  + c");
  checkExpression("(a -  b) + c");
  checkExpression(" a - (b  + c)");

  checkExpression(" a *  b  + c");
  checkExpression("(a *  b) + c");
  checkExpression(" a * (b  + c)");

  checkExpression(" a +  b  * c");
  checkExpression("(a +  b) * c");
  checkExpression(" a + (b  * c)");

  checkExpression(" a *  b  * c");
  checkExpression("(a *  b) * c");
  checkExpression(" a * (b  * c)");

  checkExpression("a is T");
  checkExpression("a is! T");
  checkExpression("!(a is T)");

  checkExpression("a is T.x");
  checkExpression("a is! T.x");
  checkExpression("!(a is T.x)");
  checkExpression("!(a is T).x");

  checkExpression("a as T.x");
  checkExpression("(a as T).x");

  checkExpression("a == b");
  checkExpression("a != b");
  checkExpression("!(a == b)", "a != b");

  checkExpression("a && b ? c : d");
  checkExpression("(a && b) ? c : d");
  checkExpression("a && (b ? c : d)");

  checkExpression("a || b ? c : d");
  checkExpression("(a || b) ? c : d");
  checkExpression("a || (b ? c : d)");

  checkExpression(" a ? b :  c && d");
  checkExpression(" a ? b : (c && d)");
  checkExpression("(a ? b :  c) && d");

  checkExpression(" a ? b : c = d");
  checkExpression(" a ? b : (c = d)");

  checkExpression("(a == b) == c");
  checkExpression("a == (b == c)");

  checkExpression(" a <  b  == c");
  checkExpression("(a <  b) == c");
  checkExpression(" a < (b  == c)");

  checkExpression(" a ==  b  < c");
  checkExpression("(a ==  b) < c");
  checkExpression(" a == (b  < c)");

  checkExpression("x.f()");
  checkExpression("(x.f)()");

  checkExpression("x.f()()");
  checkExpression("(x.f)()()");

  checkExpression("x.f().g()");
  checkExpression("(x.f)().g()");

  checkExpression("x.f()");
  checkExpression("x.f(1 + 2)");
  checkExpression("x.f(1 + 2, 3 + 4)");
  checkExpression("x.f(1 + 2, foo:3 + 4)");
  checkExpression("x.f(1 + 2, foo:3 + 4, bar: 5)");
  checkExpression("x.f(foo:3 + 4)");
  checkExpression("x.f(foo:3 + 4, bar: 5)");

  checkExpression("x.f.g.h");
  checkExpression("(x.f).g.h");
  checkExpression("(x.f.g).h");

  checkExpression(" a =  b  + c");
  checkExpression(" a = (b  + c)");
  checkExpression("(a =  b) + c");

  checkExpression("a + (b = c)");

  checkExpression("dx * dx + dy * dy < r * r",
                  "((dx * dx) + (dy * dy)) < (r * r)");
  checkExpression("mid = left + right << 1",
                  "mid = ((left + right) << 1)");
  checkExpression("a + b % c * -d ^  e - f  ~/ x & ++y / z++ | w > a ? b : c");
  checkExpression("a + b % c * -d ^ (e - f) ~/ x & ++y / z++ | w > a ? b : c");

  checkExpression("'foo'");
  checkExpression("'foo' 'bar'", "'foobar'");

  checkExpression("{}.length");
  checkExpression("{x: 1+2}.length");
  checkExpression("<String,int>{}.length");
  checkExpression("<String,int>{x: 1+2}.length");

  checkExpression("[].length");
  checkExpression("[1+2].length");
  checkExpression("<num>[].length");
  checkExpression("<num>[1+2].length");

  checkExpression("x + -y");
  checkExpression("x + --y");
  checkExpression("x++ + y");
  checkExpression("x + ++y");
  checkExpression("x-- - y");
  checkExpression("x-- - -y");
  checkExpression("x - --y");

  checkExpression("x && !y");
  checkExpression("!x && y");
  checkExpression("!(x && y)");

  checkExpression(" super +  1  * 2");
  checkExpression("(super +  1) * 2");
  checkExpression(" super + (1  * 2)");
  checkExpression("x + -super");
  checkExpression("x-- - -super");
  checkExpression("x - -super");
  checkExpression("x && !super");

  checkExpression("super.f(1, 2) + 3");
  checkExpression("super.f + 3");

  checkExpression(r"'foo\nbar'");
  checkExpression(r"'foo\r\nbar'");
  checkExpression(r"'foo\rbar'");
  checkExpression(r"'foo\'bar'");
  checkExpression(r"""'foo"bar'""");
  checkExpression(r"r'foo\nbar'");
  checkExpression("''");
  checkExpression("r''");

  var sq = "'";
  var dq = '"';
  checkExpression("'$dq$dq' \"$sq$sq\"");
  checkExpression("'$dq$dq$dq$dq' \"$sq$sq$sq$sq\"");
  checkExpression(r"'\$\$\$\$\$\$\$\$\$'");
  checkExpression("'$dq$dq$dq' '\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n' \"$sq$sq$sq\"");
  checkExpression("'$dq$dq$dq' '\\r\\r\\r\\r\\r\\r\\r\\r\\r\\r' \"$sq$sq$sq\"");
  checkExpression("'$dq$dq$dq' '\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n' \"$sq$sq$sq\"");

  checkExpression(r"'$foo'");
  checkExpression(r"'${foo}x'");
  checkExpression(r"'${foo}x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'");
  checkExpression(r"'abc' '${foo}' r'\\\\\\\'");

  checkExpression(r"'${$x}'");
  checkExpression(r"'${$x}y'");
  checkExpression("null + null");

  checkExpression("(x) => x",
                  '',
                  '(x){return x;}');
  checkStatement("fn(x) => x;",
                  '',
                  'fn(x){return x;}');

  checkExpression("throw x");
  checkStatement("throw x;");

  checkStatement("var x, y, z;");
  checkStatement("final x, y, z;");
  checkStatement("dynamic x, y, z;");
  checkStatement("String x, y, z;");
  checkStatement("List<int> x, y, z;");
  checkStatement("final dynamic x, y, z;");
  checkStatement("final String x, y, z;");
  checkStatement("final List<int> x, y, z;");

  checkStatement("var x = y, z;");
  checkStatement("var x, y = z;");
  checkStatement("var x = y = z;");

  // Note: We sometimes have to pass an expected string to account for
  //       block flattening which does not preserve structural AST equality
  checkStatement("if (x)   if (y) foo();   else bar();  ");
  checkStatement("if (x) { if (y) foo(); } else bar();  ");
  checkStatement("if (x) { if (y) foo();   else bar(); }",
                 "if (x)   if (y) foo();   else bar();  ");

  checkStatement("if (x) while (y)   if (z) foo();   else bar();  ");
  checkStatement("if (x) while (y) { if (z) foo(); } else bar();  ");
  checkStatement("if (x) while (y) { if (z) foo();   else bar(); }",
                 "if (x) while (y)   if (z) foo();   else bar();  ");

  checkStatement("{var x = 1; {var x = 2;} return x;}");
  checkStatement("{var x = 1; {x = 2;} return x;}",
                 "{var x = 1;  x = 2;  return x;}",
                 "{var x = 1;  x = 2;  return x;}");

  checkStatement("if (x) {var x = 1;}");

  checkStatement("({'foo': 1}).bar();");
  checkStatement("({'foo': 1}).length;");
  checkStatement("({'foo': 1}).length + 1;");
  checkStatement("({'foo': 1})['foo'].toString();");
  checkStatement("({'foo': 1})['foo'] = 3;");
  checkStatement("({'foo': 1}['foo']());");
  checkStatement("({'foo': 1}['foo'])();");
  checkStatement("({'foo': 1})['foo'].x++;");
  checkStatement("({'foo': 1}) is Map;");
  checkStatement("({'foo': 1}) as Map;");
  checkStatement("({'foo': 1}) is util.Map;");
  checkStatement("({'foo': 1}) + 1;");

  checkStatement("[1].bar();");
  checkStatement("1.bar();");
  checkStatement("'foo'.bar();");

  checkStatement("do while(x); while (y);");
  checkStatement("{do; while(x); while (y);}");

  checkStatement('switch(x) { case 1: case 2: return y; }');
  checkStatement('switch(x) { default: return y; }');
  checkStatement('switch(x) { case 1: x=y; default: return y; }');
  checkStatement('switch(x) { case 1: x=y; y=z; break; default: return y; }');

}

