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

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/string_source.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../generated/parser_test.dart' show ParserTestCase;
import '../../generated/test_support.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ClassDeclarationTest);
    defineReflectiveTests(ClassTypeAliasTest);
    defineReflectiveTests(ConstructorDeclarationTest);
    defineReflectiveTests(FieldFormalParameterTest);
    defineReflectiveTests(IndexExpressionTest);
    defineReflectiveTests(MethodDeclarationTest);
    defineReflectiveTests(NodeListTest);
    defineReflectiveTests(PreviousTokenTest);
    defineReflectiveTests(SimpleIdentifierTest);
    defineReflectiveTests(SimpleStringLiteralTest);
    defineReflectiveTests(StringInterpolationTest);
    defineReflectiveTests(VariableDeclarationTest);
  });
}

@reflectiveTest
class ClassDeclarationTest extends ParserTestCase {
  void test_getConstructor() {
    List<ConstructorInitializer> initializers =
        new List<ConstructorInitializer>();
    ConstructorDeclaration defaultConstructor =
        AstTestFactory.constructorDeclaration(
            AstTestFactory.identifier3("Test"),
            null,
            AstTestFactory.formalParameterList(),
            initializers);
    ConstructorDeclaration aConstructor = AstTestFactory.constructorDeclaration(
        AstTestFactory.identifier3("Test"),
        "a",
        AstTestFactory.formalParameterList(),
        initializers);
    ConstructorDeclaration bConstructor = AstTestFactory.constructorDeclaration(
        AstTestFactory.identifier3("Test"),
        "b",
        AstTestFactory.formalParameterList(),
        initializers);
    ClassDeclaration clazz = AstTestFactory.classDeclaration(null, "Test", null,
        null, null, null, [defaultConstructor, aConstructor, bConstructor]);
    expect(clazz.getConstructor(null), same(defaultConstructor));
    expect(clazz.getConstructor("a"), same(aConstructor));
    expect(clazz.getConstructor("b"), same(bConstructor));
    expect(clazz.getConstructor("noSuchConstructor"), same(null));
  }

  void test_getField() {
    VariableDeclaration aVar = AstTestFactory.variableDeclaration("a");
    VariableDeclaration bVar = AstTestFactory.variableDeclaration("b");
    VariableDeclaration cVar = AstTestFactory.variableDeclaration("c");
    ClassDeclaration clazz =
        AstTestFactory.classDeclaration(null, "Test", null, null, null, null, [
      AstTestFactory.fieldDeclaration2(false, null, [aVar]),
      AstTestFactory.fieldDeclaration2(false, null, [bVar, cVar])
    ]);
    expect(clazz.getField("a"), same(aVar));
    expect(clazz.getField("b"), same(bVar));
    expect(clazz.getField("c"), same(cVar));
    expect(clazz.getField("noSuchField"), same(null));
  }

  void test_getMethod() {
    MethodDeclaration aMethod = AstTestFactory.methodDeclaration(
        null,
        null,
        null,
        null,
        AstTestFactory.identifier3("a"),
        AstTestFactory.formalParameterList());
    MethodDeclaration bMethod = AstTestFactory.methodDeclaration(
        null,
        null,
        null,
        null,
        AstTestFactory.identifier3("b"),
        AstTestFactory.formalParameterList());
    ClassDeclaration clazz = AstTestFactory.classDeclaration(
        null, "Test", null, null, null, null, [aMethod, bMethod]);
    expect(clazz.getMethod("a"), same(aMethod));
    expect(clazz.getMethod("b"), same(bMethod));
    expect(clazz.getMethod("noSuchMethod"), same(null));
  }

  void test_isAbstract() {
    expect(
        AstTestFactory.classDeclaration(null, "A", null, null, null, null)
            .isAbstract,
        isFalse);
    expect(
        AstTestFactory.classDeclaration(
                Keyword.ABSTRACT, "B", null, null, null, null)
            .isAbstract,
        isTrue);
  }
}

@reflectiveTest
class ClassTypeAliasTest extends ParserTestCase {
  void test_isAbstract() {
    expect(
        AstTestFactory.classTypeAlias("A", null, null, null, null, null)
            .isAbstract,
        isFalse);
    expect(
        AstTestFactory.classTypeAlias(
                "B", null, Keyword.ABSTRACT, null, null, null)
            .isAbstract,
        isTrue);
  }
}

@reflectiveTest
class ConstructorDeclarationTest extends EngineTestCase {
  void test_firstTokenAfterCommentAndMetadata_all_inverted() {
    Token externalKeyword = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
    externalKeyword.offset = 14;
    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
        Keyword.CONST,
        Keyword.FACTORY,
        AstTestFactory.identifier3('int'),
        null,
        null,
        null,
        null);
    declaration.externalKeyword = externalKeyword;
    declaration.constKeyword.offset = 8;
    Token factoryKeyword = declaration.factoryKeyword;
    factoryKeyword.offset = 0;
    expect(declaration.firstTokenAfterCommentAndMetadata, factoryKeyword);
  }

  void test_firstTokenAfterCommentAndMetadata_all_normal() {
    Token token = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
    token.offset = 0;
    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
        Keyword.CONST,
        Keyword.FACTORY,
        AstTestFactory.identifier3('int'),
        null,
        null,
        null,
        null);
    declaration.externalKeyword = token;
    declaration.constKeyword.offset = 9;
    declaration.factoryKeyword.offset = 15;
    expect(declaration.firstTokenAfterCommentAndMetadata, token);
  }

  void test_firstTokenAfterCommentAndMetadata_constOnly() {
    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
        Keyword.CONST,
        null,
        AstTestFactory.identifier3('int'),
        null,
        null,
        null,
        null);
    expect(declaration.firstTokenAfterCommentAndMetadata,
        declaration.constKeyword);
  }

  void test_firstTokenAfterCommentAndMetadata_externalOnly() {
    Token externalKeyword = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
        null, null, AstTestFactory.identifier3('int'), null, null, null, null);
    declaration.externalKeyword = externalKeyword;
    expect(declaration.firstTokenAfterCommentAndMetadata, externalKeyword);
  }

  void test_firstTokenAfterCommentAndMetadata_factoryOnly() {
    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
        null,
        Keyword.FACTORY,
        AstTestFactory.identifier3('int'),
        null,
        null,
        null,
        null);
    expect(declaration.firstTokenAfterCommentAndMetadata,
        declaration.factoryKeyword);
  }
}

@reflectiveTest
class FieldFormalParameterTest extends EngineTestCase {
  void test_endToken_noParameters() {
    FieldFormalParameter parameter =
        AstTestFactory.fieldFormalParameter2('field');
    expect(parameter.endToken, parameter.identifier.endToken);
  }

  void test_endToken_parameters() {
    FieldFormalParameter parameter = AstTestFactory.fieldFormalParameter(
        null, null, 'field', AstTestFactory.formalParameterList([]));
    expect(parameter.endToken, parameter.parameters.endToken);
  }
}

@reflectiveTest
class IndexExpressionTest extends EngineTestCase {
  void test_inGetterContext_assignment_compound_left() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    // a[b] += c
    AstTestFactory.assignmentExpression(
        expression, TokenType.PLUS_EQ, AstTestFactory.identifier3("c"));
    expect(expression.inGetterContext(), isTrue);
  }

  void test_inGetterContext_assignment_simple_left() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    // a[b] = c
    AstTestFactory.assignmentExpression(
        expression, TokenType.EQ, AstTestFactory.identifier3("c"));
    expect(expression.inGetterContext(), isFalse);
  }

  void test_inGetterContext_nonAssignment() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    // a[b] + c
    AstTestFactory.binaryExpression(
        expression, TokenType.PLUS, AstTestFactory.identifier3("c"));
    expect(expression.inGetterContext(), isTrue);
  }

  void test_inSetterContext_assignment_compound_left() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    // a[b] += c
    AstTestFactory.assignmentExpression(
        expression, TokenType.PLUS_EQ, AstTestFactory.identifier3("c"));
    expect(expression.inSetterContext(), isTrue);
  }

  void test_inSetterContext_assignment_compound_right() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    // c += a[b]
    AstTestFactory.assignmentExpression(
        AstTestFactory.identifier3("c"), TokenType.PLUS_EQ, expression);
    expect(expression.inSetterContext(), isFalse);
  }

  void test_inSetterContext_assignment_simple_left() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    // a[b] = c
    AstTestFactory.assignmentExpression(
        expression, TokenType.EQ, AstTestFactory.identifier3("c"));
    expect(expression.inSetterContext(), isTrue);
  }

  void test_inSetterContext_assignment_simple_right() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    // c = a[b]
    AstTestFactory.assignmentExpression(
        AstTestFactory.identifier3("c"), TokenType.EQ, expression);
    expect(expression.inSetterContext(), isFalse);
  }

  void test_inSetterContext_nonAssignment() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    AstTestFactory.binaryExpression(
        expression, TokenType.PLUS, AstTestFactory.identifier3("c"));
    // a[b] + cc
    expect(expression.inSetterContext(), isFalse);
  }

  void test_inSetterContext_postfix() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    AstTestFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
    // a[b]++
    expect(expression.inSetterContext(), isTrue);
  }

  void test_inSetterContext_prefix_bang() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    // !a[b]
    AstTestFactory.prefixExpression(TokenType.BANG, expression);
    expect(expression.inSetterContext(), isFalse);
  }

  void test_inSetterContext_prefix_minusMinus() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    // --a[b]
    AstTestFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
    expect(expression.inSetterContext(), isTrue);
  }

  void test_inSetterContext_prefix_plusPlus() {
    IndexExpression expression = AstTestFactory.indexExpression(
        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
    // ++a[b]
    AstTestFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
    expect(expression.inSetterContext(), isTrue);
  }
}

@reflectiveTest
class MethodDeclarationTest extends EngineTestCase {
  void test_firstTokenAfterCommentAndMetadata_external() {
    MethodDeclaration declaration =
        AstTestFactory.methodDeclaration4(external: true, name: 'm');
    expect(declaration.firstTokenAfterCommentAndMetadata,
        declaration.externalKeyword);
  }

  void test_firstTokenAfterCommentAndMetadata_external_getter() {
    MethodDeclaration declaration = AstTestFactory.methodDeclaration4(
        external: true, property: Keyword.GET, name: 'm');
    expect(declaration.firstTokenAfterCommentAndMetadata,
        declaration.externalKeyword);
  }

  void test_firstTokenAfterCommentAndMetadata_external_operator() {
    MethodDeclaration declaration = AstTestFactory.methodDeclaration4(
        external: true, operator: true, name: 'm');
    expect(declaration.firstTokenAfterCommentAndMetadata,
        declaration.externalKeyword);
  }

  void test_firstTokenAfterCommentAndMetadata_getter() {
    MethodDeclaration declaration =
        AstTestFactory.methodDeclaration4(property: Keyword.GET, name: 'm');
    expect(declaration.firstTokenAfterCommentAndMetadata,
        declaration.propertyKeyword);
  }

  void test_firstTokenAfterCommentAndMetadata_operator() {
    MethodDeclaration declaration =
        AstTestFactory.methodDeclaration4(operator: true, name: 'm');
    expect(declaration.firstTokenAfterCommentAndMetadata,
        declaration.operatorKeyword);
  }
}

@reflectiveTest
class NodeListTest extends EngineTestCase {
  void test_add() {
    AstNode parent = AstTestFactory.argumentList();
    AstNode firstNode = AstTestFactory.booleanLiteral(true);
    AstNode secondNode = AstTestFactory.booleanLiteral(false);
    NodeList<AstNode> list = astFactory.nodeList<AstNode>(parent);
    list.insert(0, secondNode);
    list.insert(0, firstNode);
    expect(list, hasLength(2));
    expect(list[0], same(firstNode));
    expect(list[1], same(secondNode));
    expect(firstNode.parent, same(parent));
    expect(secondNode.parent, same(parent));
    AstNode thirdNode = AstTestFactory.booleanLiteral(false);
    list.insert(1, thirdNode);
    expect(list, hasLength(3));
    expect(list[0], same(firstNode));
    expect(list[1], same(thirdNode));
    expect(list[2], same(secondNode));
    expect(firstNode.parent, same(parent));
    expect(secondNode.parent, same(parent));
    expect(thirdNode.parent, same(parent));
  }

  void test_add_negative() {
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    try {
      list.insert(-1, AstTestFactory.booleanLiteral(true));
      fail("Expected IndexOutOfBoundsException");
    } on RangeError {
      // Expected
    }
  }

  void test_add_tooBig() {
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    try {
      list.insert(1, AstTestFactory.booleanLiteral(true));
      fail("Expected IndexOutOfBoundsException");
    } on RangeError {
      // Expected
    }
  }

  void test_addAll() {
    AstNode parent = AstTestFactory.argumentList();
    List<AstNode> firstNodes = new List<AstNode>();
    AstNode firstNode = AstTestFactory.booleanLiteral(true);
    AstNode secondNode = AstTestFactory.booleanLiteral(false);
    firstNodes.add(firstNode);
    firstNodes.add(secondNode);
    NodeList<AstNode> list = astFactory.nodeList<AstNode>(parent);
    list.addAll(firstNodes);
    expect(list, hasLength(2));
    expect(list[0], same(firstNode));
    expect(list[1], same(secondNode));
    expect(firstNode.parent, same(parent));
    expect(secondNode.parent, same(parent));
    List<AstNode> secondNodes = new List<AstNode>();
    AstNode thirdNode = AstTestFactory.booleanLiteral(true);
    AstNode fourthNode = AstTestFactory.booleanLiteral(false);
    secondNodes.add(thirdNode);
    secondNodes.add(fourthNode);
    list.addAll(secondNodes);
    expect(list, hasLength(4));
    expect(list[0], same(firstNode));
    expect(list[1], same(secondNode));
    expect(list[2], same(thirdNode));
    expect(list[3], same(fourthNode));
    expect(firstNode.parent, same(parent));
    expect(secondNode.parent, same(parent));
    expect(thirdNode.parent, same(parent));
    expect(fourthNode.parent, same(parent));
  }

  void test_creation() {
    AstNode owner = AstTestFactory.argumentList();
    NodeList<AstNode> list = astFactory.nodeList<AstNode>(owner);
    expect(list, isNotNull);
    expect(list, hasLength(0));
    expect(list.owner, same(owner));
  }

  void test_get_negative() {
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    try {
      list[-1];
      fail("Expected IndexOutOfBoundsException");
    } on RangeError {
      // Expected
    }
  }

  void test_get_tooBig() {
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    try {
      list[1];
      fail("Expected IndexOutOfBoundsException");
    } on RangeError {
      // Expected
    }
  }

  void test_getBeginToken_empty() {
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    expect(list.beginToken, isNull);
  }

  void test_getBeginToken_nonEmpty() {
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    AstNode node = AstTestFactory.parenthesizedExpression(
        AstTestFactory.booleanLiteral(true));
    list.add(node);
    expect(list.beginToken, same(node.beginToken));
  }

  void test_getEndToken_empty() {
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    expect(list.endToken, isNull);
  }

  void test_getEndToken_nonEmpty() {
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    AstNode node = AstTestFactory.parenthesizedExpression(
        AstTestFactory.booleanLiteral(true));
    list.add(node);
    expect(list.endToken, same(node.endToken));
  }

  void test_indexOf() {
    List<AstNode> nodes = new List<AstNode>();
    AstNode firstNode = AstTestFactory.booleanLiteral(true);
    AstNode secondNode = AstTestFactory.booleanLiteral(false);
    AstNode thirdNode = AstTestFactory.booleanLiteral(true);
    AstNode fourthNode = AstTestFactory.booleanLiteral(false);
    nodes.add(firstNode);
    nodes.add(secondNode);
    nodes.add(thirdNode);
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    list.addAll(nodes);
    expect(list, hasLength(3));
    expect(list.indexOf(firstNode), 0);
    expect(list.indexOf(secondNode), 1);
    expect(list.indexOf(thirdNode), 2);
    expect(list.indexOf(fourthNode), -1);
    expect(list.indexOf(null), -1);
  }

  void test_remove() {
    List<AstNode> nodes = new List<AstNode>();
    AstNode firstNode = AstTestFactory.booleanLiteral(true);
    AstNode secondNode = AstTestFactory.booleanLiteral(false);
    AstNode thirdNode = AstTestFactory.booleanLiteral(true);
    nodes.add(firstNode);
    nodes.add(secondNode);
    nodes.add(thirdNode);
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    list.addAll(nodes);
    expect(list, hasLength(3));
    expect(list.removeAt(1), same(secondNode));
    expect(list, hasLength(2));
    expect(list[0], same(firstNode));
    expect(list[1], same(thirdNode));
  }

  void test_remove_negative() {
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    try {
      list.removeAt(-1);
      fail("Expected IndexOutOfBoundsException");
    } on RangeError {
      // Expected
    }
  }

  void test_remove_tooBig() {
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    try {
      list.removeAt(1);
      fail("Expected IndexOutOfBoundsException");
    } on RangeError {
      // Expected
    }
  }

  void test_set() {
    List<AstNode> nodes = new List<AstNode>();
    AstNode firstNode = AstTestFactory.booleanLiteral(true);
    AstNode secondNode = AstTestFactory.booleanLiteral(false);
    AstNode thirdNode = AstTestFactory.booleanLiteral(true);
    nodes.add(firstNode);
    nodes.add(secondNode);
    nodes.add(thirdNode);
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    list.addAll(nodes);
    expect(list, hasLength(3));
    AstNode fourthNode = AstTestFactory.integer(0);
    list[1] = fourthNode;
    expect(list, hasLength(3));
    expect(list[0], same(firstNode));
    expect(list[1], same(fourthNode));
    expect(list[2], same(thirdNode));
  }

  void test_set_negative() {
    AstNode node = AstTestFactory.booleanLiteral(true);
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    try {
      list[-1] = node;
      fail("Expected IndexOutOfBoundsException");
    } on RangeError {
      // Expected
    }
  }

  void test_set_tooBig() {
    AstNode node = AstTestFactory.booleanLiteral(true);
    NodeList<AstNode> list =
        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
    try {
      list[1] = node;
      fail("Expected IndexOutOfBoundsException");
    } on RangeError {
      // Expected
    }
  }
}

@reflectiveTest
class PreviousTokenTest {
  static final String contents = '''
class A {
  B foo(C c) {
    return bar;
  }
  D get baz => null;
}
E f() => g;
''';

  final featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');

  CompilationUnit _unit;

  CompilationUnit get unit {
    if (_unit == null) {
      GatheringErrorListener listener =
          new GatheringErrorListener(checkRanges: true);
      var source =
          new StringSource(contents, 'PreviousTokenTest_findPrevious.dart');
      var scanner = new Scanner.fasta(source, listener)
        ..configureFeatures(featureSet);
      Token tokens = scanner.tokenize();
      _unit =
          new Parser(source, listener, featureSet: featureSet, useFasta: true)
              .parseCompilationUnit(tokens);
    }
    return _unit;
  }

  Token findToken(String lexeme) {
    Token token = unit.beginToken;
    while (!token.isEof) {
      if (token.lexeme == lexeme) {
        return token;
      }
      token = token.next;
    }
    fail('Failed to find $lexeme');
  }

  void test_findPrevious_basic_class() {
    ClassDeclaration clazz = unit.declarations[0];
    expect(clazz.findPrevious(findToken('A')).lexeme, 'class');
  }

  void test_findPrevious_basic_method() {
    ClassDeclaration clazz = unit.declarations[0];
    MethodDeclaration method = clazz.members[0];
    expect(method.findPrevious(findToken('foo')).lexeme, 'B');
  }

  void test_findPrevious_basic_statement() {
    ClassDeclaration clazz = unit.declarations[0];
    MethodDeclaration method = clazz.members[0];
    BlockFunctionBody body = method.body;
    Statement statement = body.block.statements[0];
    expect(statement.findPrevious(findToken('bar')).lexeme, 'return');
    expect(statement.findPrevious(findToken(';')).lexeme, 'bar');
  }

  void test_findPrevious_missing() {
    ClassDeclaration clazz = unit.declarations[0];
    MethodDeclaration method = clazz.members[0];
    BlockFunctionBody body = method.body;
    Statement statement = body.block.statements[0];

    GatheringErrorListener listener =
        new GatheringErrorListener(checkRanges: true);
    var source = new StringSource('missing', 'PreviousTokenTest_missing.dart');
    var scanner = new Scanner.fasta(source, listener)
      ..configureFeatures(featureSet);
    Token missing = scanner.tokenize();

    expect(statement.findPrevious(missing), null);
    expect(statement.findPrevious(null), null);
  }

  void test_findPrevious_parent_method() {
    ClassDeclaration clazz = unit.declarations[0];
    MethodDeclaration method = clazz.members[0];
    expect(method.findPrevious(findToken('B')).lexeme, '{');
  }

  void test_findPrevious_parent_statement() {
    ClassDeclaration clazz = unit.declarations[0];
    MethodDeclaration method = clazz.members[0];
    BlockFunctionBody body = method.body;
    Statement statement = body.block.statements[0];
    expect(statement.findPrevious(findToken('return')).lexeme, '{');
  }

  void test_findPrevious_sibling_class() {
    CompilationUnitMember declaration = unit.declarations[1];
    expect(declaration.findPrevious(findToken('E')).lexeme, '}');
  }

  void test_findPrevious_sibling_method() {
    ClassDeclaration clazz = unit.declarations[0];
    MethodDeclaration method = clazz.members[1];
    expect(method.findPrevious(findToken('D')).lexeme, '}');
  }
}

@reflectiveTest
class SimpleIdentifierTest extends ParserTestCase {
  void test_inGetterContext() {
    for (_WrapperKind wrapper in _WrapperKind.values) {
      for (_AssignmentKind assignment in _AssignmentKind.values) {
        SimpleIdentifier identifier = _createIdentifier(wrapper, assignment);
        if (assignment == _AssignmentKind.SIMPLE_LEFT &&
            wrapper != _WrapperKind.PREFIXED_LEFT &&
            wrapper != _WrapperKind.PROPERTY_LEFT) {
          if (identifier.inGetterContext()) {
            fail("Expected ${_topMostNode(identifier).toSource()} to be false");
          }
        } else {
          if (!identifier.inGetterContext()) {
            fail("Expected ${_topMostNode(identifier).toSource()} to be true");
          }
        }
      }
    }
  }

  void test_inGetterContext_constructorFieldInitializer() {
    ConstructorFieldInitializer initializer =
        AstTestFactory.constructorFieldInitializer(
            false, 'f', AstTestFactory.integer(0));
    SimpleIdentifier identifier = initializer.fieldName;
    expect(identifier.inGetterContext(), isFalse);
  }

  void test_inGetterContext_fieldFormalParameter() {
    FieldFormalParameter parameter =
        AstTestFactory.fieldFormalParameter2('test');
    SimpleIdentifier identifier = parameter.identifier;
    expect(identifier.inGetterContext(), isFalse);
  }

  void test_inGetterContext_forEachLoop() {
    SimpleIdentifier identifier = AstTestFactory.identifier3("a");
    Expression iterator = AstTestFactory.listLiteral();
    Statement body = AstTestFactory.block();
    AstTestFactory.forStatement(
        AstTestFactory.forEachPartsWithIdentifier(identifier, iterator), body);
    expect(identifier.inGetterContext(), isFalse);
  }

  void test_inGetterContext_variableDeclaration() {
    VariableDeclaration variable = AstTestFactory.variableDeclaration('test');
    SimpleIdentifier identifier = variable.name;
    expect(identifier.inGetterContext(), isFalse);
  }

  void test_inReferenceContext() {
    SimpleIdentifier identifier = AstTestFactory.identifier3("id");
    AstTestFactory.namedExpression(
        AstTestFactory.label(identifier), AstTestFactory.identifier3("_"));
    expect(identifier.inGetterContext(), isFalse);
    expect(identifier.inSetterContext(), isFalse);
  }

  void test_inSetterContext() {
    for (_WrapperKind wrapper in _WrapperKind.values) {
      for (_AssignmentKind assignment in _AssignmentKind.values) {
        SimpleIdentifier identifier = _createIdentifier(wrapper, assignment);
        if (wrapper == _WrapperKind.PREFIXED_LEFT ||
            wrapper == _WrapperKind.PROPERTY_LEFT ||
            assignment == _AssignmentKind.BINARY ||
            assignment == _AssignmentKind.COMPOUND_RIGHT ||
            assignment == _AssignmentKind.PREFIX_NOT ||
            assignment == _AssignmentKind.SIMPLE_RIGHT ||
            assignment == _AssignmentKind.NONE) {
          if (identifier.inSetterContext()) {
            fail("Expected ${_topMostNode(identifier).toSource()} to be false");
          }
        } else {
          if (!identifier.inSetterContext()) {
            fail("Expected ${_topMostNode(identifier).toSource()} to be true");
          }
        }
      }
    }
  }

  void test_inSetterContext_forEachLoop() {
    SimpleIdentifier identifier = AstTestFactory.identifier3("a");
    Expression iterator = AstTestFactory.listLiteral();
    Statement body = AstTestFactory.block();
    AstTestFactory.forStatement(
        AstTestFactory.forEachPartsWithIdentifier(identifier, iterator), body);
    expect(identifier.inSetterContext(), isTrue);
  }

  void test_isQualified_inMethodInvocation_noTarget() {
    MethodInvocation invocation = AstTestFactory.methodInvocation2(
        "test", [AstTestFactory.identifier3("arg0")]);
    SimpleIdentifier identifier = invocation.methodName;
    expect(identifier.isQualified, isFalse);
  }

  void test_isQualified_inMethodInvocation_withTarget() {
    MethodInvocation invocation = AstTestFactory.methodInvocation(
        AstTestFactory.identifier3("target"),
        "test",
        [AstTestFactory.identifier3("arg0")]);
    SimpleIdentifier identifier = invocation.methodName;
    expect(identifier.isQualified, isTrue);
  }

  void test_isQualified_inPrefixedIdentifier_name() {
    SimpleIdentifier identifier = AstTestFactory.identifier3("test");
    AstTestFactory.identifier4("prefix", identifier);
    expect(identifier.isQualified, isTrue);
  }

  void test_isQualified_inPrefixedIdentifier_prefix() {
    SimpleIdentifier identifier = AstTestFactory.identifier3("test");
    AstTestFactory.identifier(identifier, AstTestFactory.identifier3("name"));
    expect(identifier.isQualified, isFalse);
  }

  void test_isQualified_inPropertyAccess_name() {
    SimpleIdentifier identifier = AstTestFactory.identifier3("test");
    AstTestFactory.propertyAccess(
        AstTestFactory.identifier3("target"), identifier);
    expect(identifier.isQualified, isTrue);
  }

  void test_isQualified_inPropertyAccess_target() {
    SimpleIdentifier identifier = AstTestFactory.identifier3("test");
    AstTestFactory.propertyAccess(
        identifier, AstTestFactory.identifier3("name"));
    expect(identifier.isQualified, isFalse);
  }

  void test_isQualified_inReturnStatement() {
    SimpleIdentifier identifier = AstTestFactory.identifier3("test");
    AstTestFactory.returnStatement2(identifier);
    expect(identifier.isQualified, isFalse);
  }

  SimpleIdentifier _createIdentifier(
      _WrapperKind wrapper, _AssignmentKind assignment) {
    SimpleIdentifier identifier = AstTestFactory.identifier3("a");
    Expression expression = identifier;
    while (true) {
      if (wrapper == _WrapperKind.PREFIXED_LEFT) {
        expression = AstTestFactory.identifier(
            identifier, AstTestFactory.identifier3("_"));
      } else if (wrapper == _WrapperKind.PREFIXED_RIGHT) {
        expression = AstTestFactory.identifier(
            AstTestFactory.identifier3("_"), identifier);
      } else if (wrapper == _WrapperKind.PROPERTY_LEFT) {
        expression = AstTestFactory.propertyAccess2(expression, "_");
      } else if (wrapper == _WrapperKind.PROPERTY_RIGHT) {
        expression = AstTestFactory.propertyAccess(
            AstTestFactory.identifier3("_"), identifier);
      } else if (wrapper == _WrapperKind.NONE) {}
      break;
    }
    while (true) {
      if (assignment == _AssignmentKind.BINARY) {
        AstTestFactory.binaryExpression(
            expression, TokenType.PLUS, AstTestFactory.identifier3("_"));
      } else if (assignment == _AssignmentKind.COMPOUND_LEFT) {
        AstTestFactory.assignmentExpression(
            expression, TokenType.PLUS_EQ, AstTestFactory.identifier3("_"));
      } else if (assignment == _AssignmentKind.COMPOUND_RIGHT) {
        AstTestFactory.assignmentExpression(
            AstTestFactory.identifier3("_"), TokenType.PLUS_EQ, expression);
      } else if (assignment == _AssignmentKind.POSTFIX_INC) {
        AstTestFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
      } else if (assignment == _AssignmentKind.PREFIX_DEC) {
        AstTestFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
      } else if (assignment == _AssignmentKind.PREFIX_INC) {
        AstTestFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
      } else if (assignment == _AssignmentKind.PREFIX_NOT) {
        AstTestFactory.prefixExpression(TokenType.BANG, expression);
      } else if (assignment == _AssignmentKind.SIMPLE_LEFT) {
        AstTestFactory.assignmentExpression(
            expression, TokenType.EQ, AstTestFactory.identifier3("_"));
      } else if (assignment == _AssignmentKind.SIMPLE_RIGHT) {
        AstTestFactory.assignmentExpression(
            AstTestFactory.identifier3("_"), TokenType.EQ, expression);
      } else if (assignment == _AssignmentKind.NONE) {}
      break;
    }
    return identifier;
  }

  /**
   * Return the top-most node in the AST structure containing the given identifier.
   *
   * @param identifier the identifier in the AST structure being traversed
   * @return the root of the AST structure containing the identifier
   */
  AstNode _topMostNode(SimpleIdentifier identifier) {
    AstNode child = identifier;
    AstNode parent = identifier.parent;
    while (parent != null) {
      child = parent;
      parent = parent.parent;
    }
    return child;
  }
}

@reflectiveTest
class SimpleStringLiteralTest extends ParserTestCase {
  void test_contentsEnd() {
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X")
            .contentsEnd,
        2);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString('"X"'), "X")
            .contentsEnd,
        2);

    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString('"""X"""'), "X")
            .contentsEnd,
        4);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
            .contentsEnd,
        4);
    expect(
        astFactory
            .simpleStringLiteral(
                TokenFactory.tokenFromString("'''  \nX'''"), "X")
            .contentsEnd,
        7);

    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
            .contentsEnd,
        3);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString('r"X"'), "X")
            .contentsEnd,
        3);

    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString('r"""X"""'), "X")
            .contentsEnd,
        5);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
            .contentsEnd,
        5);
    expect(
        astFactory
            .simpleStringLiteral(
                TokenFactory.tokenFromString("r'''  \nX'''"), "X")
            .contentsEnd,
        8);
  }

  void test_contentsOffset() {
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X")
            .contentsOffset,
        1);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("\"X\""), "X")
            .contentsOffset,
        1);
    expect(
        astFactory
            .simpleStringLiteral(
                TokenFactory.tokenFromString("\"\"\"X\"\"\""), "X")
            .contentsOffset,
        3);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
            .contentsOffset,
        3);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
            .contentsOffset,
        2);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r\"X\""), "X")
            .contentsOffset,
        2);
    expect(
        astFactory
            .simpleStringLiteral(
                TokenFactory.tokenFromString("r\"\"\"X\"\"\""), "X")
            .contentsOffset,
        4);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
            .contentsOffset,
        4);
    // leading whitespace
    expect(
        astFactory
            .simpleStringLiteral(
                TokenFactory.tokenFromString("''' \ \nX''"), "X")
            .contentsOffset,
        6);
    expect(
        astFactory
            .simpleStringLiteral(
                TokenFactory.tokenFromString('r""" \ \nX"""'), "X")
            .contentsOffset,
        7);
  }

  void test_isMultiline() {
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X")
            .isMultiline,
        isFalse);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
            .isMultiline,
        isFalse);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("\"X\""), "X")
            .isMultiline,
        isFalse);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r\"X\""), "X")
            .isMultiline,
        isFalse);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
            .isMultiline,
        isTrue);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
            .isMultiline,
        isTrue);
    expect(
        astFactory
            .simpleStringLiteral(
                TokenFactory.tokenFromString("\"\"\"X\"\"\""), "X")
            .isMultiline,
        isTrue);
    expect(
        astFactory
            .simpleStringLiteral(
                TokenFactory.tokenFromString("r\"\"\"X\"\"\""), "X")
            .isMultiline,
        isTrue);
  }

  void test_isRaw() {
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X")
            .isRaw,
        isFalse);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("\"X\""), "X")
            .isRaw,
        isFalse);
    expect(
        astFactory
            .simpleStringLiteral(
                TokenFactory.tokenFromString("\"\"\"X\"\"\""), "X")
            .isRaw,
        isFalse);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
            .isRaw,
        isFalse);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
            .isRaw,
        isTrue);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r\"X\""), "X")
            .isRaw,
        isTrue);
    expect(
        astFactory
            .simpleStringLiteral(
                TokenFactory.tokenFromString("r\"\"\"X\"\"\""), "X")
            .isRaw,
        isTrue);
    expect(
        astFactory
            .simpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
            .isRaw,
        isTrue);
  }

  void test_isSingleQuoted() {
    // '
    {
      var token = TokenFactory.tokenFromString("'X'");
      var node = astFactory.simpleStringLiteral(token, null);
      expect(node.isSingleQuoted, isTrue);
    }
    // '''
    {
      var token = TokenFactory.tokenFromString("'''X'''");
      var node = astFactory.simpleStringLiteral(token, null);
      expect(node.isSingleQuoted, isTrue);
    }
    // "
    {
      var token = TokenFactory.tokenFromString('"X"');
      var node = astFactory.simpleStringLiteral(token, null);
      expect(node.isSingleQuoted, isFalse);
    }
    // """
    {
      var token = TokenFactory.tokenFromString('"""X"""');
      var node = astFactory.simpleStringLiteral(token, null);
      expect(node.isSingleQuoted, isFalse);
    }
  }

  void test_isSingleQuoted_raw() {
    // r'
    {
      var token = TokenFactory.tokenFromString("r'X'");
      var node = astFactory.simpleStringLiteral(token, null);
      expect(node.isSingleQuoted, isTrue);
    }
    // r'''
    {
      var token = TokenFactory.tokenFromString("r'''X'''");
      var node = astFactory.simpleStringLiteral(token, null);
      expect(node.isSingleQuoted, isTrue);
    }
    // r"
    {
      var token = TokenFactory.tokenFromString('r"X"');
      var node = astFactory.simpleStringLiteral(token, null);
      expect(node.isSingleQuoted, isFalse);
    }
    // r"""
    {
      var token = TokenFactory.tokenFromString('r"""X"""');
      var node = astFactory.simpleStringLiteral(token, null);
      expect(node.isSingleQuoted, isFalse);
    }
  }

  void test_simple() {
    Token token = TokenFactory.tokenFromString("'value'");
    SimpleStringLiteral stringLiteral =
        astFactory.simpleStringLiteral(token, "value");
    expect(stringLiteral.literal, same(token));
    expect(stringLiteral.beginToken, same(token));
    expect(stringLiteral.endToken, same(token));
    expect(stringLiteral.value, "value");
  }
}

@reflectiveTest
class StringInterpolationTest extends ParserTestCase {
  void test_contentsOffsetEnd() {
    AstTestFactory.interpolationExpression(AstTestFactory.identifier3('bb'));
    // 'a${bb}ccc'
    {
      var ae = AstTestFactory.interpolationString("'a", "a");
      var cToken = new StringToken(TokenType.STRING, "ccc'", 10);
      var cElement = astFactory.interpolationString(cToken, 'ccc');
      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
      expect(node.contentsOffset, 1);
      expect(node.contentsEnd, 10 + 4 - 1);
    }
    // '''a${bb}ccc'''
    {
      var ae = AstTestFactory.interpolationString("'''a", "a");
      var cToken = new StringToken(TokenType.STRING, "ccc'''", 10);
      var cElement = astFactory.interpolationString(cToken, 'ccc');
      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
      expect(node.contentsOffset, 3);
      expect(node.contentsEnd, 10 + 4 - 1);
    }
    // """a${bb}ccc"""
    {
      var ae = AstTestFactory.interpolationString('"""a', "a");
      var cToken = new StringToken(TokenType.STRING, 'ccc"""', 10);
      var cElement = astFactory.interpolationString(cToken, 'ccc');
      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
      expect(node.contentsOffset, 3);
      expect(node.contentsEnd, 10 + 4 - 1);
    }
    // r'a${bb}ccc'
    {
      var ae = AstTestFactory.interpolationString("r'a", "a");
      var cToken = new StringToken(TokenType.STRING, "ccc'", 10);
      var cElement = astFactory.interpolationString(cToken, 'ccc');
      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
      expect(node.contentsOffset, 2);
      expect(node.contentsEnd, 10 + 4 - 1);
    }
    // r'''a${bb}ccc'''
    {
      var ae = AstTestFactory.interpolationString("r'''a", "a");
      var cToken = new StringToken(TokenType.STRING, "ccc'''", 10);
      var cElement = astFactory.interpolationString(cToken, 'ccc');
      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
      expect(node.contentsOffset, 4);
      expect(node.contentsEnd, 10 + 4 - 1);
    }
    // r"""a${bb}ccc"""
    {
      var ae = AstTestFactory.interpolationString('r"""a', "a");
      var cToken = new StringToken(TokenType.STRING, 'ccc"""', 10);
      var cElement = astFactory.interpolationString(cToken, 'ccc');
      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
      expect(node.contentsOffset, 4);
      expect(node.contentsEnd, 10 + 4 - 1);
    }
  }

  void test_isMultiline() {
    var b = AstTestFactory.interpolationExpression(
        AstTestFactory.identifier3('bb'));
    // '
    {
      var a = AstTestFactory.interpolationString("'a", "a");
      var c = AstTestFactory.interpolationString("ccc'", "ccc");
      StringInterpolation node = AstTestFactory.string([a, b, c]);
      expect(node.isMultiline, isFalse);
    }
    // '''
    {
      var a = AstTestFactory.interpolationString("'''a", "a");
      var c = AstTestFactory.interpolationString("ccc'''", "ccc");
      StringInterpolation node = AstTestFactory.string([a, b, c]);
      expect(node.isMultiline, isTrue);
    }
    // "
    {
      var a = AstTestFactory.interpolationString('"a', "a");
      var c = AstTestFactory.interpolationString('ccc"', "ccc");
      StringInterpolation node = AstTestFactory.string([a, b, c]);
      expect(node.isMultiline, isFalse);
    }
    // """
    {
      var a = AstTestFactory.interpolationString('"""a', "a");
      var c = AstTestFactory.interpolationString('ccc"""', "ccc");
      StringInterpolation node = AstTestFactory.string([a, b, c]);
      expect(node.isMultiline, isTrue);
    }
  }

  void test_isRaw() {
    StringInterpolation node = AstTestFactory.string();
    expect(node.isRaw, isFalse);
  }

  void test_isSingleQuoted() {
    var b = AstTestFactory.interpolationExpression(
        AstTestFactory.identifier3('bb'));
    // "
    {
      var a = AstTestFactory.interpolationString('"a', "a");
      var c = AstTestFactory.interpolationString('ccc"', "ccc");
      StringInterpolation node = AstTestFactory.string([a, b, c]);
      expect(node.isSingleQuoted, isFalse);
    }
    // """
    {
      var a = AstTestFactory.interpolationString('"""a', "a");
      var c = AstTestFactory.interpolationString('ccc"""', "ccc");
      StringInterpolation node = AstTestFactory.string([a, b, c]);
      expect(node.isSingleQuoted, isFalse);
    }
    // '
    {
      var a = AstTestFactory.interpolationString("'a", "a");
      var c = AstTestFactory.interpolationString("ccc'", "ccc");
      StringInterpolation node = AstTestFactory.string([a, b, c]);
      expect(node.isSingleQuoted, isTrue);
    }
    // '''
    {
      var a = AstTestFactory.interpolationString("'''a", "a");
      var c = AstTestFactory.interpolationString("ccc'''", "ccc");
      StringInterpolation node = AstTestFactory.string([a, b, c]);
      expect(node.isSingleQuoted, isTrue);
    }
  }
}

@reflectiveTest
class VariableDeclarationTest extends ParserTestCase {
  void test_getDocumentationComment_onGrandParent() {
    VariableDeclaration varDecl = AstTestFactory.variableDeclaration("a");
    TopLevelVariableDeclaration decl =
        AstTestFactory.topLevelVariableDeclaration2(Keyword.VAR, [varDecl]);
    Comment comment = astFactory.documentationComment(new List<Token>(0));
    expect(varDecl.documentationComment, isNull);
    decl.documentationComment = comment;
    expect(varDecl.documentationComment, isNotNull);
    expect(decl.documentationComment, isNotNull);
  }

  void test_getDocumentationComment_onNode() {
    VariableDeclaration decl = AstTestFactory.variableDeclaration("a");
    Comment comment = astFactory.documentationComment(new List<Token>(0));
    decl.documentationComment = comment;
    expect(decl.documentationComment, isNotNull);
  }
}

class _AssignmentKind {
  static const _AssignmentKind BINARY = const _AssignmentKind('BINARY', 0);

  static const _AssignmentKind COMPOUND_LEFT =
      const _AssignmentKind('COMPOUND_LEFT', 1);

  static const _AssignmentKind COMPOUND_RIGHT =
      const _AssignmentKind('COMPOUND_RIGHT', 2);

  static const _AssignmentKind POSTFIX_INC =
      const _AssignmentKind('POSTFIX_INC', 3);

  static const _AssignmentKind PREFIX_DEC =
      const _AssignmentKind('PREFIX_DEC', 4);

  static const _AssignmentKind PREFIX_INC =
      const _AssignmentKind('PREFIX_INC', 5);

  static const _AssignmentKind PREFIX_NOT =
      const _AssignmentKind('PREFIX_NOT', 6);

  static const _AssignmentKind SIMPLE_LEFT =
      const _AssignmentKind('SIMPLE_LEFT', 7);

  static const _AssignmentKind SIMPLE_RIGHT =
      const _AssignmentKind('SIMPLE_RIGHT', 8);

  static const _AssignmentKind NONE = const _AssignmentKind('NONE', 9);

  static const List<_AssignmentKind> values = const [
    BINARY,
    COMPOUND_LEFT,
    COMPOUND_RIGHT,
    POSTFIX_INC,
    PREFIX_DEC,
    PREFIX_INC,
    PREFIX_NOT,
    SIMPLE_LEFT,
    SIMPLE_RIGHT,
    NONE
  ];

  final String name;

  final int ordinal;

  const _AssignmentKind(this.name, this.ordinal);

  int get hashCode => ordinal;

  int compareTo(_AssignmentKind other) => ordinal - other.ordinal;

  String toString() => name;
}

class _WrapperKind {
  static const _WrapperKind PREFIXED_LEFT =
      const _WrapperKind('PREFIXED_LEFT', 0);

  static const _WrapperKind PREFIXED_RIGHT =
      const _WrapperKind('PREFIXED_RIGHT', 1);

  static const _WrapperKind PROPERTY_LEFT =
      const _WrapperKind('PROPERTY_LEFT', 2);

  static const _WrapperKind PROPERTY_RIGHT =
      const _WrapperKind('PROPERTY_RIGHT', 3);

  static const _WrapperKind NONE = const _WrapperKind('NONE', 4);

  static const List<_WrapperKind> values = const [
    PREFIXED_LEFT,
    PREFIXED_RIGHT,
    PROPERTY_LEFT,
    PROPERTY_RIGHT,
    NONE
  ];

  final String name;

  final int ordinal;

  const _WrapperKind(this.name, this.ordinal);

  int get hashCode => ordinal;

  int compareTo(_WrapperKind other) => ordinal - other.ordinal;

  String toString() => name;
}
