// 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/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/builder.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/element_search.dart';
import 'package:analyzer/src/generated/testing/node_search.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../generated/parser_test.dart';
import '../../generated/test_support.dart';
import '../../util/element_type_matchers.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ApiElementBuilderTest);
    defineReflectiveTests(ElementBuilderTest);
    defineReflectiveTests(LocalElementBuilderTest);
  });
}

@reflectiveTest
class ApiElementBuilderTest extends _BaseTest with _ApiElementBuilderTestMixin {
  @override
  AstVisitor createElementBuilder(ElementHolder holder) {
    return new ApiElementBuilder(holder, compilationUnitElement);
  }

  void test_api_class_field() {
    List<FieldElement> fields = buildElementsForText(r'''
class C {
  var a = 42;
  var b = () {
    int v = 0;
    localFunction() {}
  };
}
''').types[0].fields;
    expect(fields, hasLength(2));
    {
      FieldElement a = fields[0];
      expect(a.displayName, 'a');
      expect(a.initializer, isNull);
    }
    {
      FieldElement b = fields[1];
      expect(b.displayName, 'b');
      expect(b.initializer, isNull);
    }
  }

  void test_api_class_method_blockBody() {
    MethodElement method = buildElementsForText(r'''
class C {
  void m(int a, {int b: 42}) {
    int v = 0;
    localFunction() {}
  }
}
''').types[0].methods[0];
    {
      expect(method.parameters, hasLength(2));
      expect(method.parameters[0].displayName, 'a');
      expect(method.parameters[0].initializer, isNull);
      expect(method.parameters[1].displayName, 'b');
      expect(method.parameters[1].initializer, isNull);
    }
    expect(
        findDeclaredIdentifiersByName(compilationUnit, 'v')
            .single
            .staticElement,
        isNull);
    expect(
        findDeclaredIdentifiersByName(compilationUnit, 'localFunction')
            .single
            .staticElement,
        isNull);
  }

  void test_api_topLevelFunction_blockBody() {
    FunctionElement topLevelFunction = buildElementsForText(r'''
void topLevelFunction() {
  int v = 0;
  localFunction() {}
}
''').functions[0];
    expect(topLevelFunction, isNotNull);
    expect(topLevelFunction.name, 'topLevelFunction');
    expect(
        findDeclaredIdentifiersByName(compilationUnit, 'v')
            .single
            .staticElement,
        isNull);
    expect(
        findDeclaredIdentifiersByName(compilationUnit, 'localFunction')
            .single
            .staticElement,
        isNull);
  }

  void test_api_topLevelFunction_expressionBody() {
    FunctionElement topLevelFunction = buildElementsForText(r'''
topLevelFunction() => () {
  int localVar = 0;
};
''').functions[0];
    expect(topLevelFunction, isNotNull);
    expect(topLevelFunction.name, 'topLevelFunction');
    expect(
        findDeclaredIdentifiersByName(compilationUnit, 'localVar')
            .single
            .staticElement,
        isNull);
  }

  void test_api_topLevelFunction_parameters() {
    FunctionElement function = buildElementsForText(r'''
void topLevelFunction(int a, int b(double b2), {c: () {int c2; c3() {} }}) {
}
''').functions[0];
    List<ParameterElement> parameters = function.parameters;
    expect(parameters, hasLength(3));
    {
      ParameterElement a = parameters[0];
      expect(a.displayName, 'a');
      expect(a.initializer, isNull);
    }
    {
      ParameterElement b = parameters[1];
      expect(b.displayName, 'b');
      expect(b.initializer, isNull);
      var bTypeElement = b.type.element as GenericFunctionTypeElementImpl;
      expect(bTypeElement.parameters, hasLength(1));
      expect(bTypeElement.parameters[0].displayName, 'b2');
    }
    {
      var c = parameters[2] as DefaultParameterElementImpl;
      expect(c.displayName, 'c');
      expect(c.initializer, isNull);
    }
  }

  void test_api_topLevelVariable() {
    List<TopLevelVariableElement> variables = buildElementsForText(r'''
var A = 42;
var B = () {
  int v = 0;
  localFunction(int _) {}
};
''').topLevelVariables;
    expect(variables, hasLength(2));
    {
      TopLevelVariableElement a = variables[0];
      expect(a.displayName, 'A');
      expect(a.initializer, isNull);
    }
    {
      TopLevelVariableElement b = variables[1];
      expect(b.displayName, 'B');
      expect(b.initializer, isNull);
    }
  }

  @override
  void _assertHasVariableInitializer(VariableElement element) {
    expect(element.initializer, isNull);
  }
}

@reflectiveTest
class ElementBuilderTest extends _BaseTest with _ApiElementBuilderTestMixin {
  /**
   * Parse the given [code], pass it through [ElementBuilder], and return the
   * resulting [ElementHolder].
   */
  ElementHolder buildElementsForText(String code) {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = new ElementBuilder(holder, compilationUnitElement);
    _visitAstOfCode(code, builder);
    return holder;
  }

  AstVisitor createElementBuilder(ElementHolder holder) {
    return new ElementBuilder(holder, compilationUnitElement);
  }

  void fail_visitMethodDeclaration_setter_duplicate() {
    // https://github.com/dart-lang/sdk/issues/25601
    String code = r'''
class C {
  set zzz(x) {}
  set zzz(y) {}
}
''';
    ClassElement classElement = buildElementsForText(code).types[0];
    for (PropertyAccessorElement accessor in classElement.accessors) {
      expect(accessor.variable.setter, same(accessor));
    }
  }

  @override
  void setUp() {
    super.setUp();
    compilationUnitElement = new CompilationUnitElementImpl();
  }

  void test_metadata_localVariableDeclaration() {
    var code = 'f() { @a int x, y; }';
    buildElementsForText(code);
    var x = findLocalVariable(code, 'x, ');
    var y = findLocalVariable(code, 'x, ');
    checkMetadata(x);
    checkMetadata(y);
    expect(x.metadata, same(y.metadata));
  }

  void test_metadata_visitDeclaredIdentifier() {
    var code = 'f() { for (@a var x in y) {} }';
    buildElementsForText(code);
    var x = findLocalVariable(code, 'x in');
    checkMetadata(x);
  }

  void test_visitCatchClause() {
    var code = 'f() { try {} catch (e, s) {} }';
    buildElementsForText(code);
    var e = findLocalVariable(code, 'e, ');
    var s = findLocalVariable(code, 's) {}');

    expect(e, isNotNull);
    expect(e.name, 'e');
    expect(e.hasImplicitType, isTrue);
    expect(e.isSynthetic, isFalse);
    expect(e.isConst, isFalse);
    expect(e.isFinal, isFalse);
    expect(e.initializer, isNull);
    _assertVisibleRange(e, 13, 28);

    expect(s, isNotNull);
    expect(s.name, 's');
    expect(s.isSynthetic, isFalse);
    expect(s.isConst, isFalse);
    expect(s.isFinal, isFalse);
    expect(s.initializer, isNull);
    _assertVisibleRange(s, 13, 28);
  }

  void test_visitCatchClause_withType() {
    var code = 'f() { try {} on E catch (e) {} }';
    buildElementsForText(code);
    var e = findLocalVariable(code, 'e) {}');
    expect(e, isNotNull);
    expect(e.name, 'e');
    expect(e.hasImplicitType, isFalse);
  }

  void test_visitCompilationUnit_codeRange() {
    TopLevelVariableDeclaration topLevelVariableDeclaration =
        AstTestFactory.topLevelVariableDeclaration(
            null,
            AstTestFactory.typeName4('int'),
            [AstTestFactory.variableDeclaration('V')]);
    CompilationUnit unit = astFactory.compilationUnit2(
        beginToken: topLevelVariableDeclaration.beginToken,
        declarations: [topLevelVariableDeclaration],
        endToken: topLevelVariableDeclaration.endToken,
        featureSet: null);
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    unit.beginToken.offset = 10;
    unit.endToken.offset = 40;
    unit.accept(builder);

    assertHasCodeRange(compilationUnitElement, 0, 41);
  }

  void test_visitDeclaredIdentifier_noType() {
    var code = 'f() { for (var i in []) {} }';
    buildElementsForText(code);
    var variable = findLocalVariable(code, 'i in');
    assertHasCodeRange(variable, 11, 5);
    expect(variable, isNotNull);
    expect(variable.hasImplicitType, isTrue);
    expect(variable.isConst, isFalse);
    expect(variable.hasDeprecated, isFalse);
    expect(variable.isFinal, isFalse);
    expect(variable.hasAlwaysThrows, isFalse);
    expect(variable.isPrivate, isFalse);
    expect(variable.isPublic, isTrue);
    expect(variable.isSynthetic, isFalse);
    expect(variable.name, 'i');
  }

  void test_visitDeclaredIdentifier_type() {
    var code = 'f() { for (int i in []) {} }';
    buildElementsForText(code);
    var variable = findLocalVariable(code, 'i in');
    assertHasCodeRange(variable, 11, 5);
    expect(variable.hasImplicitType, isFalse);
    expect(variable.isConst, isFalse);
    expect(variable.hasDeprecated, isFalse);
    expect(variable.isFinal, isFalse);
    expect(variable.hasOverride, isFalse);
    expect(variable.isPrivate, isFalse);
    expect(variable.isPublic, isTrue);
    expect(variable.isSynthetic, isFalse);
    expect(variable.name, 'i');
  }

  void test_visitDefaultFormalParameter_noType() {
    // p = 0
    String parameterName = 'p';
    DefaultFormalParameter formalParameter =
        AstTestFactory.positionalFormalParameter(
            AstTestFactory.simpleFormalParameter3(parameterName),
            AstTestFactory.integer(0));
    formalParameter.beginToken.offset = 50;
    formalParameter.endToken.offset = 80;

    ElementHolder holder = buildElementsForAst(formalParameter);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElement parameter = parameters[0];
    assertHasCodeRange(parameter, 50, 31);
    expect(parameter.hasImplicitType, isTrue);
    expect(parameter.initializer, isNotNull);
    expect(parameter.initializer.type, isNotNull);
    expect(parameter.initializer.hasImplicitReturnType, isTrue);
    expect(parameter.isConst, isFalse);
    expect(parameter.hasDeprecated, isFalse);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isInitializingFormal, isFalse);
    expect(parameter.hasOverride, isFalse);
    expect(parameter.isPrivate, isFalse);
    expect(parameter.isPublic, isTrue);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.name, parameterName);
  }

  void test_visitDefaultFormalParameter_type() {
    // E p = 0
    String parameterName = 'p';
    DefaultFormalParameter formalParameter =
        AstTestFactory.namedFormalParameter(
            AstTestFactory.simpleFormalParameter4(
                AstTestFactory.typeName4('E'), parameterName),
            AstTestFactory.integer(0));

    ElementHolder holder = buildElementsForAst(formalParameter);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElement parameter = parameters[0];
    expect(parameter.hasImplicitType, isFalse);
    expect(parameter.initializer, isNotNull);
    expect(parameter.initializer.type, isNotNull);
    expect(parameter.initializer.hasImplicitReturnType, isTrue);
    expect(parameter.isConst, isFalse);
    expect(parameter.hasDeprecated, isFalse);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isInitializingFormal, isFalse);
    expect(parameter.hasOverride, isFalse);
    expect(parameter.isPrivate, isFalse);
    expect(parameter.isPublic, isTrue);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.name, parameterName);
  }

  void test_visitFunctionExpression() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    FunctionExpression expression = AstTestFactory.functionExpression2(
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2());
    expression.accept(builder);
    List<FunctionElement> functions = holder.functions;
    expect(functions, hasLength(1));
    FunctionElement function = functions[0];
    expect(function, isNotNull);
    expect(expression.declaredElement, same(function));
    expect(function.hasImplicitReturnType, isTrue);
    expect(function.isSynthetic, isFalse);
    expect(function.typeParameters, hasLength(0));
  }

  void test_visitFunctionExpression_inBlockBody() {
    buildElementsForText('f() { return () => 42; }');
    FunctionDeclaration f = compilationUnit.declarations[0];
    BlockFunctionBody fBody = f.functionExpression.body;
    ReturnStatement returnStatement = fBody.block.statements[0];
    FunctionExpression closure = returnStatement.expression;
    FunctionElement function = closure.declaredElement;
    expect(function, isNotNull);
    expect(function.hasImplicitReturnType, isTrue);
    expect(function.isSynthetic, isFalse);
    expect(function.typeParameters, hasLength(0));
  }

  void test_visitFunctionExpression_inExpressionBody() {
    buildElementsForText('f() => () => 42;');
    FunctionDeclaration f = compilationUnit.declarations[0];
    ExpressionFunctionBody fBody = f.functionExpression.body;
    FunctionExpression closure = fBody.expression;
    FunctionElement function = closure.declaredElement;
    expect(function, isNotNull);
    expect(function.hasImplicitReturnType, isTrue);
    expect(function.isSynthetic, isFalse);
    expect(function.typeParameters, hasLength(0));
  }

  void test_visitFunctionTypeAlias() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String aliasName = "F";
    String parameterName = "E";
    FunctionTypeAlias aliasNode = AstTestFactory.typeAlias(null, aliasName,
        AstTestFactory.typeParameterList([parameterName]), null);
    aliasNode.documentationComment = AstTestFactory.documentationComment(
        [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
    aliasNode.endToken.offset = 80;
    aliasNode.accept(builder);

    List<FunctionTypeAliasElement> aliases = holder.typeAliases;
    expect(aliases, hasLength(1));
    FunctionTypeAliasElement alias = aliases[0];
    expect(alias, isNotNull);
    assertHasCodeRange(alias, 50, 31);
    expect(alias.documentationComment, '/// aaa');
    expect(alias.name, aliasName);
    expect(alias.parameters, hasLength(0));
    List<TypeParameterElement> typeParameters = alias.typeParameters;
    expect(typeParameters, hasLength(1));
    TypeParameterElement typeParameter = typeParameters[0];
    expect(typeParameter, isNotNull);
    expect(typeParameter.name, parameterName);
  }

  void test_visitFunctionTypedFormalParameter() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String parameterName = "p";
    FunctionTypedFormalParameter formalParameter =
        AstTestFactory.functionTypedFormalParameter(null, parameterName);
    _useParameterInMethod(formalParameter, 100, 110);
    formalParameter.accept(builder);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElement parameter = parameters[0];
    expect(parameter, isNotNull);
    expect(parameter.name, parameterName);
    expect(parameter.initializer, isNull);
    expect(parameter.isConst, isFalse);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.isRequiredPositional, isTrue);
    _assertVisibleRange(parameter, 100, 110);
  }

  void test_visitFunctionTypedFormalParameter_covariant() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String parameterName = "p";
    FunctionTypedFormalParameterImpl formalParameter =
        AstTestFactory.functionTypedFormalParameter(null, parameterName);
    formalParameter.covariantKeyword =
        TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
    _useParameterInMethod(formalParameter, 100, 110);
    formalParameter.accept(builder);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElementImpl parameter = parameters[0];
    expect(parameter, isNotNull);
    expect(parameter.name, parameterName);
    expect(parameter.initializer, isNull);
    expect(parameter.isConst, isFalse);
    expect(parameter.isExplicitlyCovariant, isTrue);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.isRequiredPositional, isTrue);
    _assertVisibleRange(parameter, 100, 110);
  }

  void test_visitFunctionTypedFormalParameter_withTypeParameters() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String parameterName = "p";
    FunctionTypedFormalParameter formalParameter =
        AstTestFactory.functionTypedFormalParameter(null, parameterName);
    formalParameter.typeParameters = AstTestFactory.typeParameterList(['F']);
    _useParameterInMethod(formalParameter, 100, 110);
    formalParameter.accept(builder);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));

    ParameterElement parameter = parameters[0];
    var typeElement = parameter.type.element as GenericFunctionTypeElementImpl;
    expect(parameter, isNotNull);
    expect(parameter.name, parameterName);
    expect(parameter.initializer, isNull);
    expect(parameter.isConst, isFalse);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.isRequiredPositional, isTrue);
    expect(typeElement.typeParameters, hasLength(1));
    _assertVisibleRange(parameter, 100, 110);
  }

  void test_visitLabeledStatement() {
    String code = 'f() { l: print(42); }';
    buildElementsForText(code);
    LabelElement label = findLabel(code, 'l:');
    expect(label, isNotNull);
    expect(label.name, 'l');
    expect(label.isSynthetic, isFalse);
  }

  void test_visitMethodDeclaration_withMembers() {
    var code = 'class C { m(p) { var v; try { l: return; } catch (e) {} } }';
    MethodElement method = buildElementsForText(code).types[0].methods[0];
    String methodName = "m";
    String parameterName = "p";
    String labelName = "l";
    expect(method, isNotNull);
    expect(method.hasImplicitReturnType, isTrue);
    expect(method.name, methodName);
    expect(method.typeParameters, hasLength(0));
    expect(method.isAbstract, isFalse);
    expect(method.isExternal, isFalse);
    expect(method.isStatic, isFalse);
    expect(method.isSynthetic, isFalse);
    List<VariableElement> parameters = method.parameters;
    expect(parameters, hasLength(1));
    VariableElement parameter = parameters[0];
    expect(parameter, isNotNull);
    expect(parameter.name, parameterName);

    var v = findLocalVariable(code, 'v;');
    expect(v.name, 'v');

    var e = findLocalVariable(code, 'e) {}');
    expect(e.name, 'e');

    LabelElement label = findLabel(code, 'l:');
    expect(label, isNotNull);
    expect(label.name, labelName);
  }

  void test_visitNamedFormalParameter() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String parameterName = "p";
    DefaultFormalParameter formalParameter =
        AstTestFactory.namedFormalParameter(
            AstTestFactory.simpleFormalParameter3(parameterName),
            AstTestFactory.identifier3("42"));
    _useParameterInMethod(formalParameter, 100, 110);
    formalParameter.beginToken.offset = 50;
    formalParameter.endToken.offset = 80;
    formalParameter.accept(builder);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElement parameter = parameters[0];
    expect(parameter, isNotNull);
    assertHasCodeRange(parameter, 50, 32);
    expect(parameter.name, parameterName);
    expect(parameter.isConst, isFalse);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.isNamed, isTrue);
    _assertVisibleRange(parameter, 100, 110);
    expect(parameter.defaultValueCode, "42");
    FunctionElement initializer = parameter.initializer;
    expect(initializer, isNotNull);
    expect(initializer.isSynthetic, isTrue);
    expect(initializer.hasImplicitReturnType, isTrue);
  }

  void test_visitNamedFormalParameter_covariant() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String parameterName = "p";
    DefaultFormalParameter formalParameter =
        AstTestFactory.namedFormalParameter(
            AstTestFactory.simpleFormalParameter3(parameterName),
            AstTestFactory.identifier3("42"));
    (formalParameter.parameter as NormalFormalParameterImpl).covariantKeyword =
        TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
    _useParameterInMethod(formalParameter, 100, 110);
    formalParameter.beginToken.offset = 50;
    formalParameter.endToken.offset = 80;
    formalParameter.accept(builder);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElementImpl parameter = parameters[0];
    expect(parameter, isNotNull);
    assertHasCodeRange(parameter, 50, 32);
    expect(parameter.name, parameterName);
    expect(parameter.isConst, isFalse);
    expect(parameter.isExplicitlyCovariant, isTrue);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.isNamed, isTrue);
    _assertVisibleRange(parameter, 100, 110);
    expect(parameter.defaultValueCode, "42");
    FunctionElement initializer = parameter.initializer;
    expect(initializer, isNotNull);
    expect(initializer.isSynthetic, isTrue);
    expect(initializer.hasImplicitReturnType, isTrue);
  }

  void test_visitSimpleFormalParameter_noType() {
    // p
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String parameterName = "p";
    SimpleFormalParameter formalParameter =
        AstTestFactory.simpleFormalParameter3(parameterName);
    _useParameterInMethod(formalParameter, 100, 110);
    formalParameter.accept(builder);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElement parameter = parameters[0];
    expect(parameter, isNotNull);
    expect(parameter.hasImplicitType, isTrue);
    expect(parameter.initializer, isNull);
    expect(parameter.isConst, isFalse);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.name, parameterName);
    expect(parameter.isRequiredPositional, isTrue);
    _assertVisibleRange(parameter, 100, 110);
  }

  void test_visitSimpleFormalParameter_noType_covariant() {
    // p
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String parameterName = "p";
    SimpleFormalParameterImpl formalParameter =
        AstTestFactory.simpleFormalParameter3(parameterName);
    formalParameter.covariantKeyword =
        TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
    _useParameterInMethod(formalParameter, 100, 110);
    formalParameter.accept(builder);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElementImpl parameter = parameters[0];
    expect(parameter, isNotNull);
    expect(parameter.hasImplicitType, isTrue);
    expect(parameter.initializer, isNull);
    expect(parameter.isConst, isFalse);
    expect(parameter.isExplicitlyCovariant, isTrue);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.name, parameterName);
    expect(parameter.isRequiredPositional, isTrue);
    _assertVisibleRange(parameter, 100, 110);
  }

  void test_visitSimpleFormalParameter_type() {
    // T p
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String parameterName = "p";
    SimpleFormalParameter formalParameter =
        AstTestFactory.simpleFormalParameter4(
            AstTestFactory.typeName4('T'), parameterName);
    _useParameterInMethod(formalParameter, 100, 110);
    formalParameter.accept(builder);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElement parameter = parameters[0];
    expect(parameter, isNotNull);
    expect(parameter.hasImplicitType, isFalse);
    expect(parameter.initializer, isNull);
    expect(parameter.isConst, isFalse);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.name, parameterName);
    expect(parameter.isRequiredPositional, isTrue);
    _assertVisibleRange(parameter, 100, 110);
  }

  void test_visitSimpleFormalParameter_type_covariant() {
    // T p
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String parameterName = "p";
    SimpleFormalParameterImpl formalParameter =
        AstTestFactory.simpleFormalParameter4(
            AstTestFactory.typeName4('T'), parameterName);
    formalParameter.covariantKeyword =
        TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
    _useParameterInMethod(formalParameter, 100, 110);
    formalParameter.accept(builder);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElementImpl parameter = parameters[0];
    expect(parameter, isNotNull);
    expect(parameter.hasImplicitType, isFalse);
    expect(parameter.initializer, isNull);
    expect(parameter.isConst, isFalse);
    expect(parameter.isExplicitlyCovariant, isTrue);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.name, parameterName);
    expect(parameter.isRequiredPositional, isTrue);
    _assertVisibleRange(parameter, 100, 110);
  }

  void test_visitVariableDeclaration_field_covariant() {
    // covariant int f;
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String fieldName = "f";
    VariableDeclarationImpl variableDeclaration =
        AstTestFactory.variableDeclaration2(fieldName, null);
    FieldDeclarationImpl fieldDeclaration = AstTestFactory.fieldDeclaration(
        false,
        null,
        AstTestFactory.typeName4('int'),
        <VariableDeclaration>[variableDeclaration]);
    fieldDeclaration.covariantKeyword =
        TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
    variableDeclaration.accept(builder);

    List<FieldElement> fields = holder.fields;
    expect(fields, hasLength(1));
    FieldElementImpl field = fields[0];
    expect(field, isNotNull);
    PropertyAccessorElementImpl setter = field.setter;
    expect(setter, isNotNull);
    expect(setter.parameters[0].isCovariant, isTrue);
  }

  void test_visitVariableDeclaration_inConstructor() {
    var code = 'class C { C() { var v = 1; } }';
    buildElementsForText(code);
    var v = findLocalVariable(code, 'v =');
    assertHasCodeRange(v, 16, 9);
    expect(v.hasImplicitType, isTrue);
    expect(v.name, 'v');
    _assertVisibleRange(v, 14, 28);
  }

  void test_visitVariableDeclaration_inForEachStatement() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    //
    // m() { for (var v in []) }
    //
    String variableName = "v";
    DeclaredIdentifier variableIdentifier =
        AstTestFactory.declaredIdentifier3('v');
    Statement statement = AstTestFactory.forStatement(
        AstTestFactory.forEachPartsWithDeclaration(
            variableIdentifier, AstTestFactory.listLiteral()),
        AstTestFactory.block());
    _setNodeSourceRange(statement, 100, 110);
    MethodDeclaration method = AstTestFactory.methodDeclaration2(
        null,
        null,
        null,
        null,
        AstTestFactory.identifier3("m"),
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2([statement]));
    _setBlockBodySourceRange(method.body, 200, 220);
    method.accept(builder);

    List<MethodElement> methods = holder.methods;
    expect(methods, hasLength(1));
    LocalVariableElement variableElement = variableIdentifier.declaredElement;
    expect(variableElement.name, variableName);
    _assertVisibleRange(variableElement, 100, 110);
  }

  void test_visitVariableDeclaration_inForStatement() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    //
    // m() { for (T v;;) }
    //
    String variableName = "v";
    VariableDeclaration variableIdentifier =
        AstTestFactory.variableDeclaration('v');
    ForStatement statement = AstTestFactory.forStatement(
        AstTestFactory.forPartsWithDeclarations(
            AstTestFactory.variableDeclarationList(
                null, AstTestFactory.typeName4('T'), [variableIdentifier]),
            null,
            null),
        AstTestFactory.block());
    _setNodeSourceRange(statement, 100, 110);
    MethodDeclaration method = AstTestFactory.methodDeclaration2(
        null,
        null,
        null,
        null,
        AstTestFactory.identifier3("m"),
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2([statement]));
    _setBlockBodySourceRange(method.body, 200, 220);
    method.accept(builder);

    List<MethodElement> methods = holder.methods;
    expect(methods, hasLength(1));
    LocalVariableElement variableElement = variableIdentifier.declaredElement;
    expect(variableElement.name, variableName);
    _assertVisibleRange(variableElement, 100, 110);
  }

  void test_visitVariableDeclaration_inMethod() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    //
    // m() {T v;}
    //
    String variableName = "v";
    VariableDeclaration variable =
        AstTestFactory.variableDeclaration2(variableName, null);
    Statement statement = AstTestFactory.variableDeclarationStatement(
        null, AstTestFactory.typeName4('T'), [variable]);
    MethodDeclaration method = AstTestFactory.methodDeclaration2(
        null,
        null,
        null,
        null,
        AstTestFactory.identifier3("m"),
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2([statement]));
    _setBlockBodySourceRange(method.body, 100, 110);
    method.accept(builder);

    List<MethodElement> methods = holder.methods;
    expect(methods, hasLength(1));
    LocalVariableElement variableElement = variable.declaredElement;
    expect(variableElement.hasImplicitType, isFalse);
    expect(variableElement.name, variableName);
    _assertVisibleRange(variableElement, 100, 110);
  }

  void test_visitVariableDeclaration_localNestedInFunction() {
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    //
    // var f = () {var v;};
    //
    String variableName = "v";
    VariableDeclaration variable =
        AstTestFactory.variableDeclaration2(variableName, null);
    Statement statement =
        AstTestFactory.variableDeclarationStatement2(null, [variable]);
    FunctionExpression initializer = AstTestFactory.functionExpression2(
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2([statement]));
    String fieldName = "f";
    VariableDeclaration field =
        AstTestFactory.variableDeclaration2(fieldName, initializer);
    FieldDeclaration fieldDeclaration =
        AstTestFactory.fieldDeclaration2(false, null, [field]);
    fieldDeclaration.accept(builder);

    List<FieldElement> variables = holder.fields;
    expect(variables, hasLength(1));
    FieldElement fieldElement = variables[0];
    expect(fieldElement, isNotNull);
    FunctionElement initializerElement = fieldElement.initializer;
    expect(initializerElement, isNotNull);
    expect(initializerElement.hasImplicitReturnType, isTrue);
    expect(initializer.declaredElement, isFunctionElement);
    LocalVariableElement variableElement = variable.declaredElement;
    expect(variableElement.hasImplicitType, isTrue);
    expect(variableElement.isConst, isFalse);
    expect(variableElement.isFinal, isFalse);
    expect(variableElement.isSynthetic, isFalse);
    expect(variableElement.name, variableName);
  }

  void test_visitVariableDeclaration_noInitializer() {
    // var v;
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String variableName = "v";
    VariableDeclaration variableDeclaration =
        AstTestFactory.variableDeclaration2(variableName, null);
    AstTestFactory.variableDeclarationList2(null, [variableDeclaration]);
    variableDeclaration.accept(builder);

    List<TopLevelVariableElement> variables = holder.topLevelVariables;
    expect(variables, hasLength(1));
    TopLevelVariableElement variable = variables[0];
    expect(variable, isNotNull);
    expect(variable.hasImplicitType, isTrue);
    expect(variable.initializer, isNull);
    expect(variable.name, variableName);
    expect(variable.isConst, isFalse);
    expect(variable.isFinal, isFalse);
    expect(variable.isSynthetic, isFalse);
    expect(variable.getter, isNotNull);
    expect(variable.setter, isNotNull);
  }

  void test_visitVariableDeclaration_top() {
    // final a, b;
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    VariableDeclaration variableDeclaration1 =
        AstTestFactory.variableDeclaration('a');
    VariableDeclaration variableDeclaration2 =
        AstTestFactory.variableDeclaration('b');
    TopLevelVariableDeclaration topLevelVariableDeclaration =
        AstTestFactory.topLevelVariableDeclaration(
            Keyword.FINAL, null, [variableDeclaration1, variableDeclaration2]);
    topLevelVariableDeclaration.documentationComment =
        AstTestFactory.documentationComment(
            [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);

    topLevelVariableDeclaration.accept(builder);
    List<TopLevelVariableElement> variables = holder.topLevelVariables;
    expect(variables, hasLength(2));

    TopLevelVariableElement variable1 = variables[0];
    expect(variable1, isNotNull);
    expect(variable1.documentationComment, '/// aaa');

    TopLevelVariableElement variable2 = variables[1];
    expect(variable2, isNotNull);
    expect(variable2.documentationComment, '/// aaa');
  }

  void test_visitVariableDeclaration_top_const_hasInitializer() {
    // const v = 42;
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String variableName = "v";
    VariableDeclaration variableDeclaration =
        AstTestFactory.variableDeclaration2(
            variableName, AstTestFactory.integer(42));
    AstTestFactory.variableDeclarationList2(
        Keyword.CONST, [variableDeclaration]);
    variableDeclaration.accept(builder);

    List<TopLevelVariableElement> variables = holder.topLevelVariables;
    expect(variables, hasLength(1));
    TopLevelVariableElement variable = variables[0];
    expect(variable, new TypeMatcher<ConstTopLevelVariableElementImpl>());
    expect(variable.initializer, isNotNull);
    expect(variable.initializer.type, isNotNull);
    expect(variable.initializer.hasImplicitReturnType, isTrue);
    expect(variable.name, variableName);
    expect(variable.hasImplicitType, isTrue);
    expect(variable.isConst, isTrue);
    expect(variable.isFinal, isFalse);
    expect(variable.isSynthetic, isFalse);
    expect(variable.getter, isNotNull);
    expect(variable.setter, isNull);
  }

  void test_visitVariableDeclaration_top_final() {
    // final v;
    ElementHolder holder = new ElementHolder();
    ElementBuilder builder = _makeBuilder(holder);
    String variableName = "v";
    VariableDeclaration variableDeclaration =
        AstTestFactory.variableDeclaration2(variableName, null);
    AstTestFactory.variableDeclarationList2(
        Keyword.FINAL, [variableDeclaration]);
    variableDeclaration.accept(builder);
    List<TopLevelVariableElement> variables = holder.topLevelVariables;
    expect(variables, hasLength(1));
    TopLevelVariableElement variable = variables[0];
    expect(variable, isNotNull);
    expect(variable.hasImplicitType, isTrue);
    expect(variable.initializer, isNull);
    expect(variable.name, variableName);
    expect(variable.isConst, isFalse);
    expect(variable.isFinal, isTrue);
    expect(variable.isSynthetic, isFalse);
    expect(variable.getter, isNotNull);
    expect(variable.setter, isNull);
  }

  ElementBuilder _makeBuilder(ElementHolder holder) =>
      new ElementBuilder(holder, compilationUnitElement);

  void _setBlockBodySourceRange(BlockFunctionBody body, int offset, int end) {
    _setNodeSourceRange(body.block, offset, end);
  }

  void _setNodeSourceRange(AstNode node, int offset, int end) {
    node.beginToken.offset = offset;
    Token endToken = node.endToken;
    endToken.offset = end - endToken.length;
  }

  void _useParameterInMethod(
      FormalParameter formalParameter, int blockOffset, int blockEnd) {
    Block block = AstTestFactory.block();
    block.leftBracket.offset = blockOffset;
    block.rightBracket.offset = blockEnd - 1;
    BlockFunctionBody body = AstTestFactory.blockFunctionBody(block);
    AstTestFactory.methodDeclaration2(
        null,
        null,
        null,
        null,
        AstTestFactory.identifier3("main"),
        AstTestFactory.formalParameterList([formalParameter]),
        body);
  }
}

@reflectiveTest
class LocalElementBuilderTest extends _BaseTest {
  @override
  AstVisitor createElementBuilder(ElementHolder holder) {
    return new LocalElementBuilder(holder, compilationUnitElement);
  }

  void test_buildLocalElements() {
    var code = r'''
main() {
  int v1;
  f1() {
    int v2;
    f2() {
      int v3;
    }
  }
}
''';
    _compilationUnit = parseCompilationUnit(code);
    var mainAst = _compilationUnit.declarations.single as FunctionDeclaration;

    // Build API elements.
    FunctionElementImpl main;
    {
      ElementHolder holder = new ElementHolder();
      _compilationUnit
          .accept(new ApiElementBuilder(holder, compilationUnitElement));
      main = holder.functions.single as FunctionElementImpl;
    }

    // Build local elements in body.
    ElementHolder holder = new ElementHolder();
    FunctionBody mainBody = mainAst.functionExpression.body;
    mainBody.accept(new LocalElementBuilder(holder, compilationUnitElement));
    main.encloseElements(holder.functions);
    main.encloseElements(holder.localVariables);

    var f1 = findLocalFunction(code, 'f1() {');
    var f2 = findLocalFunction(code, 'f2() {');
    var v1 = findLocalVariable(code, 'v1;');
    var v2 = findLocalVariable(code, 'v2;');
    var v3 = findLocalVariable(code, 'v3;');

    expect(v1.enclosingElement, main);
    {
      expect(f1.name, 'f1');
      expect(v2.enclosingElement, f1);
      {
        expect(f2.name, 'f2');
        expect(v3.enclosingElement, f2);
      }
    }
  }

  void test_buildParameterInitializer() {
    CompilationUnit unit = parseCompilationUnit('f({p: 42}) {}');
    var function = unit.declarations.single as FunctionDeclaration;
    var parameter = function.functionExpression.parameters.parameters.single
        as DefaultFormalParameter;
    // Build API elements.
    {
      ElementHolder holder = new ElementHolder();
      unit.accept(new ApiElementBuilder(holder, compilationUnitElement));
    }
    // Validate the parameter element.
    var parameterElement = parameter.declaredElement as ParameterElementImpl;
    expect(parameterElement, isNotNull);
    expect(parameterElement.initializer, isNull);
    // Build the initializer element.
    new LocalElementBuilder(new ElementHolder(), compilationUnitElement)
        .buildParameterInitializer(parameterElement, parameter.defaultValue);
    expect(parameterElement.initializer, isNotNull);
  }

  void test_buildVariableInitializer() {
    CompilationUnit unit = parseCompilationUnit('var V = 42;');
    TopLevelVariableDeclaration topLevelDecl =
        unit.declarations[0] as TopLevelVariableDeclaration;
    VariableDeclaration variable = topLevelDecl.variables.variables.single;
    // Build the variable element.
    {
      ElementHolder holder = new ElementHolder();
      unit.accept(new ApiElementBuilder(holder, compilationUnitElement));
    }
    // Validate the variable element.
    var variableElement = variable.declaredElement as VariableElementImpl;
    expect(variableElement, isNotNull);
    expect(variableElement.initializer, isNull);
    // Build the initializer element.
    new LocalElementBuilder(new ElementHolder(), compilationUnitElement)
        .buildVariableInitializer(variableElement, variable.initializer);
    expect(variableElement.initializer, isNotNull);
  }

  void test_genericFunction_isExpression() {
    buildElementsForText('main(p) { p is Function(int a, String); }');
    var main = compilationUnit.declarations[0] as FunctionDeclaration;
    var body = main.functionExpression.body as BlockFunctionBody;
    var statement = body.block.statements[0] as ExpressionStatement;
    var expression = statement.expression as IsExpression;
    var typeNode = expression.type as GenericFunctionType;
    var typeElement = typeNode.type.element as GenericFunctionTypeElementImpl;
    expect(typeElement.parameters, hasLength(2));
    expect(typeElement.parameters[0].name, 'a');
    expect(typeElement.parameters[1].name, '');
  }

  void test_visitDefaultFormalParameter_local() {
    CompilationUnit unit = parseCompilationUnit('''
main() {
  f({bool b: false}) {}
}
''');
    var mainAst = unit.declarations.single as FunctionDeclaration;
    // Build API elements.
    FunctionElementImpl main;
    {
      ElementHolder holder = new ElementHolder();
      unit.accept(new ApiElementBuilder(holder, compilationUnitElement));
      main = holder.functions.single as FunctionElementImpl;
    }
    // Build local elements in body.
    ElementHolder holder = new ElementHolder();
    FunctionBody mainBody = mainAst.functionExpression.body;
    mainBody.accept(new LocalElementBuilder(holder, compilationUnitElement));

    List<FunctionElement> functions = holder.functions;
    main.encloseElements(functions);

    FunctionElement f = findElementsByName(unit, 'f').single;
    expect(f.parameters, hasLength(1));
    expect(f.parameters[0].initializer, isNotNull);
  }

  void test_visitFieldFormalParameter() {
    CompilationUnit unit = parseCompilationUnit(r'''
main() {
  f(a, this.b) {}
}
''', codes: [ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
    var main = unit.declarations[0] as FunctionDeclaration;
    var mainBody = main.functionExpression.body as BlockFunctionBody;
    var mainBlock = mainBody.block;
    var statement = mainBlock.statements[0] as FunctionDeclarationStatement;
    FunctionDeclaration f = statement.functionDeclaration;

    // Build API elements.
    {
      ElementHolder holder = new ElementHolder();
      unit.accept(new ApiElementBuilder(holder, compilationUnitElement));
    }

    // Build local elements.
    ElementHolder holder = new ElementHolder();
    var builder = new LocalElementBuilder(holder, compilationUnitElement);
    f.accept(builder);

    List<FormalParameter> parameters =
        f.functionExpression.parameters.parameters;

    ParameterElement a = parameters[0].declaredElement;
    expect(a, isNotNull);
    expect(a.name, 'a');

    ParameterElement b = parameters[1].declaredElement;
    expect(b, isNotNull);
    expect(b.name, 'b');
  }

  void test_visitVariableDeclaration_local() {
    var code = 'class C { m() { T v = null; } }';
    buildElementsForText(code);
    LocalVariableElement element = findIdentifier(code, 'v =').staticElement;
    expect(element.hasImplicitType, isFalse);
    expect(element.name, 'v');
    expect(element.initializer, isNotNull);
    _assertVisibleRange(element, 14, 29);
  }
}

/**
 * Mixin with test methods for testing element building in [ApiElementBuilder].
 * It is used to test the [ApiElementBuilder] itself, and its usage by
 * [ElementBuilder].
 */
mixin _ApiElementBuilderTestMixin {
  CompilationUnit get compilationUnit;

  void set isMixinSupportEnabled(bool value);

  void assertHasCodeRange(Element element, int offset, int length);

  /**
   * Build elements using [ApiElementBuilder].
   */
  ElementHolder buildElementsForAst(AstNode node);

  /**
   * Parse the given [code], and build elements using [ApiElementBuilder].
   */
  ElementHolder buildElementsForText(String code);

  /**
   * Verify that the given [metadata] has exactly one annotation, and that its
   * [ElementAnnotationImpl] is unresolved.
   */
  void checkAnnotation(NodeList<Annotation> metadata);

  /**
   * Verify that the given [element] has exactly one annotation, and that its
   * [ElementAnnotationImpl] is unresolved.
   */
  void checkMetadata(Element element);

  void test_genericFunction_asTopLevelVariableType() {
    buildElementsForText('int Function(int a, String) v;');
    var v = compilationUnit.declarations[0] as TopLevelVariableDeclaration;
    var typeNode = v.variables.type as GenericFunctionType;
    var typeElement = typeNode.type.element as GenericFunctionTypeElementImpl;
    expect(typeElement.parameters, hasLength(2));
    expect(typeElement.parameters[0].name, 'a');
    expect(typeElement.parameters[1].name, '');
  }

  void test_metadata_fieldDeclaration() {
    List<FieldElement> fields =
        buildElementsForText('class C { @a int x, y; }').types[0].fields;
    checkMetadata(fields[0]);
    checkMetadata(fields[1]);
    expect(fields[0].metadata, same(fields[1].metadata));
  }

  void test_metadata_topLevelVariableDeclaration() {
    List<TopLevelVariableElement> topLevelVariables =
        buildElementsForText('@a int x, y;').topLevelVariables;
    checkMetadata(topLevelVariables[0]);
    checkMetadata(topLevelVariables[1]);
    expect(topLevelVariables[0].metadata, same(topLevelVariables[1].metadata));
  }

  void test_metadata_visitClassDeclaration() {
    ClassElement classElement = buildElementsForText('@a class C {}').types[0];
    checkMetadata(classElement);
  }

  void test_metadata_visitClassTypeAlias() {
    ClassElement classElement =
        buildElementsForText('@a class C = D with E;').types[0];
    checkMetadata(classElement);
  }

  void test_metadata_visitConstructorDeclaration() {
    ConstructorElement constructorElement =
        buildElementsForText('class C { @a C(); }').types[0].constructors[0];
    checkMetadata(constructorElement);
  }

  void test_metadata_visitDefaultFormalParameter_fieldFormalParameter() {
    ParameterElement parameterElement =
        buildElementsForText('class C { var x; C([@a this.x = null]); }')
            .types[0]
            .constructors[0]
            .parameters[0];
    checkMetadata(parameterElement);
  }

  void
      test_metadata_visitDefaultFormalParameter_functionTypedFormalParameter() {
    ParameterElement parameterElement =
        buildElementsForText('f([@a g() = null]) {}')
            .functions[0]
            .parameters[0];
    checkMetadata(parameterElement);
  }

  void test_metadata_visitDefaultFormalParameter_simpleFormalParameter() {
    ParameterElement parameterElement =
        buildElementsForText('f([@a gx = null]) {}').functions[0].parameters[0];
    checkMetadata(parameterElement);
  }

  void test_metadata_visitEnumConstant() {
    ElementHolder enumElement = buildElementsForText('enum E { @a v }');
    FieldElement v = enumElement.enums[0].fields[0];
    expect(v.name, 'v');
    checkMetadata(v);
  }

  void test_metadata_visitEnumDeclaration() {
    ClassElement classElement =
        buildElementsForText('@a enum E { v }').enums[0];
    checkMetadata(classElement);
  }

  void test_metadata_visitExportDirective() {
    buildElementsForText('@a export "foo.dart";');
    expect(compilationUnit.directives[0], new TypeMatcher<ExportDirective>());
    ExportDirective exportDirective = compilationUnit.directives[0];
    checkAnnotation(exportDirective.metadata);
  }

  void test_metadata_visitFieldFormalParameter() {
    ParameterElement parameterElement =
        buildElementsForText('class C { var x; C(@a this.x); }')
            .types[0]
            .constructors[0]
            .parameters[0];
    checkMetadata(parameterElement);
  }

  void test_metadata_visitFunctionDeclaration_function() {
    FunctionElement functionElement =
        buildElementsForText('@a f() {}').functions[0];
    checkMetadata(functionElement);
  }

  void test_metadata_visitFunctionDeclaration_getter() {
    PropertyAccessorElement propertyAccessorElement =
        buildElementsForText('@a get f => null;').accessors[0];
    checkMetadata(propertyAccessorElement);
  }

  void test_metadata_visitFunctionDeclaration_setter() {
    PropertyAccessorElement propertyAccessorElement =
        buildElementsForText('@a set f(value) {}').accessors[0];
    checkMetadata(propertyAccessorElement);
  }

  void test_metadata_visitFunctionTypeAlias() {
    FunctionTypeAliasElement functionTypeAliasElement =
        buildElementsForText('@a typedef F();').typeAliases[0];
    checkMetadata(functionTypeAliasElement);
  }

  void test_metadata_visitFunctionTypedFormalParameter() {
    ParameterElement parameterElement =
        buildElementsForText('f(@a g()) {}').functions[0].parameters[0];
    checkMetadata(parameterElement);
  }

  void test_metadata_visitImportDirective() {
    buildElementsForText('@a import "foo.dart";');
    expect(compilationUnit.directives[0], new TypeMatcher<ImportDirective>());
    ImportDirective importDirective = compilationUnit.directives[0];
    checkAnnotation(importDirective.metadata);
  }

  void test_metadata_visitLibraryDirective() {
    buildElementsForText('@a library L;');
    expect(compilationUnit.directives[0], new TypeMatcher<LibraryDirective>());
    LibraryDirective libraryDirective = compilationUnit.directives[0];
    checkAnnotation(libraryDirective.metadata);
  }

  void test_metadata_visitMethodDeclaration_getter() {
    PropertyAccessorElement propertyAccessorElement =
        buildElementsForText('class C { @a get m => null; }')
            .types[0]
            .accessors[0];
    checkMetadata(propertyAccessorElement);
  }

  void test_metadata_visitMethodDeclaration_method() {
    MethodElement methodElement =
        buildElementsForText('class C { @a m() {} }').types[0].methods[0];
    checkMetadata(methodElement);
  }

  void test_metadata_visitMethodDeclaration_setter() {
    PropertyAccessorElement propertyAccessorElement =
        buildElementsForText('class C { @a set f(value) {} }')
            .types[0]
            .accessors[0];
    checkMetadata(propertyAccessorElement);
  }

  void test_metadata_visitPartDirective() {
    buildElementsForText('@a part "foo.dart";');
    expect(compilationUnit.directives[0], new TypeMatcher<PartDirective>());
    PartDirective partDirective = compilationUnit.directives[0];
    checkAnnotation(partDirective.metadata);
  }

  void test_metadata_visitPartOfDirective() {
    // We don't build ElementAnnotation objects for `part of` directives, since
    // analyzer ignores them in favor of annotations on the library directive.
    buildElementsForText('@a part of L;');
    expect(compilationUnit.directives[0], new TypeMatcher<PartOfDirective>());
    PartOfDirective partOfDirective = compilationUnit.directives[0];
    expect(partOfDirective.metadata, hasLength(1));
    expect(partOfDirective.metadata[0].elementAnnotation, isNull);
  }

  void test_metadata_visitSimpleFormalParameter() {
    ParameterElement parameterElement =
        buildElementsForText('f(@a x) {}').functions[0].parameters[0];
    checkMetadata(parameterElement);
  }

  void test_metadata_visitTypeParameter() {
    TypeParameterElement typeParameterElement =
        buildElementsForText('class C<@a T> {}').types[0].typeParameters[0];
    checkMetadata(typeParameterElement);
  }

  void test_visitClassDeclaration_abstract() {
    List<ClassElement> types =
        buildElementsForText('abstract class C {}').types;
    expect(types, hasLength(1));
    ClassElement type = types[0];
    expect(type, isNotNull);
    expect(type.name, 'C');
    List<TypeParameterElement> typeParameters = type.typeParameters;
    expect(typeParameters, hasLength(0));
    expect(type.isAbstract, isTrue);
    expect(type.isMixinApplication, isFalse);
    expect(type.isSynthetic, isFalse);
  }

  void test_visitClassDeclaration_invalidFunctionInAnnotation_class() {
    // https://github.com/dart-lang/sdk/issues/25696
    String code = r'''
class A {
  const A({f});
}

@A(f: () {})
class C {}
''';
    buildElementsForText(code);
  }

  void test_visitClassDeclaration_invalidFunctionInAnnotation_method() {
    String code = r'''
class A {
  const A({f});
}

class C {
  @A(f: () {})
  void m() {}
}
''';
    ElementHolder holder = buildElementsForText(code);
    ClassElement elementC = holder.types[1];
    expect(elementC, isNotNull);
    MethodElement methodM = elementC.methods[0];
    expect(methodM, isNotNull);
  }

  void test_visitClassDeclaration_minimal() {
    String className = "C";
    ClassDeclaration classDeclaration = AstTestFactory.classDeclaration(
        null, className, null, null, null, null);
    classDeclaration.documentationComment = AstTestFactory.documentationComment(
        [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
    classDeclaration.endToken.offset = 80;

    ElementHolder holder = buildElementsForAst(classDeclaration);
    List<ClassElement> types = holder.types;
    expect(types, hasLength(1));
    ClassElement type = types[0];
    expect(type, isNotNull);
    expect(type.name, className);
    List<TypeParameterElement> typeParameters = type.typeParameters;
    expect(typeParameters, hasLength(0));
    expect(type.isAbstract, isFalse);
    expect(type.isMixinApplication, isFalse);
    expect(type.isSynthetic, isFalse);
    expect(type.documentationComment, '/// aaa');
    assertHasCodeRange(type, 50, 31);
  }

  void test_visitClassDeclaration_parameterized() {
    String className = "C";
    String firstVariableName = "E";
    String secondVariableName = "F";
    ClassDeclaration classDeclaration = AstTestFactory.classDeclaration(
        null,
        className,
        AstTestFactory.typeParameterList(
            [firstVariableName, secondVariableName]),
        null,
        null,
        null);

    ElementHolder holder = buildElementsForAst(classDeclaration);
    List<ClassElement> types = holder.types;
    expect(types, hasLength(1));
    ClassElement type = types[0];
    expect(type, isNotNull);
    expect(type.name, className);
    List<TypeParameterElement> typeParameters = type.typeParameters;
    expect(typeParameters, hasLength(2));
    expect(typeParameters[0].name, firstVariableName);
    expect(typeParameters[1].name, secondVariableName);
    expect(type.isAbstract, isFalse);
    expect(type.isMixinApplication, isFalse);
    expect(type.isSynthetic, isFalse);
  }

  void test_visitClassDeclaration_withMembers() {
    String className = "C";
    String typeParameterName = "E";
    String fieldName = "f";
    String methodName = "m";
    ClassDeclaration classDeclaration = AstTestFactory.classDeclaration(
        null,
        className,
        AstTestFactory.typeParameterList([typeParameterName]),
        null,
        null,
        null, [
      AstTestFactory.fieldDeclaration2(
          false, null, [AstTestFactory.variableDeclaration(fieldName)]),
      AstTestFactory.methodDeclaration2(
          null,
          null,
          null,
          null,
          AstTestFactory.identifier3(methodName),
          AstTestFactory.formalParameterList(),
          AstTestFactory.blockFunctionBody2())
    ]);

    ElementHolder holder = buildElementsForAst(classDeclaration);
    List<ClassElement> types = holder.types;
    expect(types, hasLength(1));
    ClassElement type = types[0];
    expect(type, isNotNull);
    expect(type.name, className);
    expect(type.isAbstract, isFalse);
    expect(type.isMixinApplication, isFalse);
    expect(type.isSynthetic, isFalse);
    List<TypeParameterElement> typeParameters = type.typeParameters;
    expect(typeParameters, hasLength(1));
    TypeParameterElement typeParameter = typeParameters[0];
    expect(typeParameter, isNotNull);
    expect(typeParameter.name, typeParameterName);
    List<FieldElement> fields = type.fields;
    expect(fields, hasLength(1));
    FieldElement field = fields[0];
    expect(field, isNotNull);
    expect(field.name, fieldName);
    List<MethodElement> methods = type.methods;
    expect(methods, hasLength(1));
    MethodElement method = methods[0];
    expect(method, isNotNull);
    expect(method.name, methodName);
  }

  void test_visitClassTypeAlias() {
    // class B {}
    // class M {}
    // class C = B with M
    ClassElementImpl classB = ElementFactory.classElement2('B', []);
    ConstructorElementImpl constructorB =
        ElementFactory.constructorElement2(classB, '', []);
    constructorB.setModifier(Modifier.SYNTHETIC, true);
    classB.constructors = [constructorB];
    ClassElement classM = ElementFactory.classElement2('M', []);
    WithClause withClause =
        AstTestFactory.withClause([AstTestFactory.typeName(classM, [])]);
    ClassTypeAlias alias = AstTestFactory.classTypeAlias(
        'C', null, null, AstTestFactory.typeName(classB, []), withClause, null);

    ElementHolder holder = buildElementsForAst(alias);
    List<ClassElement> types = holder.types;
    expect(types, hasLength(1));
    ClassElement type = types[0];
    expect(alias.declaredElement, same(type));
    expect(type.name, equals('C'));
    expect(type.isAbstract, isFalse);
    expect(type.isMixinApplication, isTrue);
    expect(type.isSynthetic, isFalse);
    expect(type.typeParameters, isEmpty);
    expect(type.fields, isEmpty);
    expect(type.methods, isEmpty);
  }

  void test_visitClassTypeAlias_abstract() {
    // class B {}
    // class M {}
    // abstract class C = B with M
    ClassElementImpl classB = ElementFactory.classElement2('B', []);
    ConstructorElementImpl constructorB =
        ElementFactory.constructorElement2(classB, '', []);
    constructorB.setModifier(Modifier.SYNTHETIC, true);
    classB.constructors = [constructorB];
    ClassElement classM = ElementFactory.classElement2('M', []);
    WithClause withClause =
        AstTestFactory.withClause([AstTestFactory.typeName(classM, [])]);
    ClassTypeAlias alias = AstTestFactory.classTypeAlias(
        'C',
        null,
        Keyword.ABSTRACT,
        AstTestFactory.typeName(classB, []),
        withClause,
        null);

    ElementHolder holder = buildElementsForAst(alias);
    List<ClassElement> types = holder.types;
    expect(types, hasLength(1));
    ClassElement type = types[0];
    expect(type.isAbstract, isTrue);
    expect(type.isMixinApplication, isTrue);
  }

  void test_visitClassTypeAlias_typeParams() {
    // class B {}
    // class M {}
    // class C<T> = B with M
    ClassElementImpl classB = ElementFactory.classElement2('B', []);
    ConstructorElementImpl constructorB =
        ElementFactory.constructorElement2(classB, '', []);
    constructorB.setModifier(Modifier.SYNTHETIC, true);
    classB.constructors = [constructorB];
    ClassElementImpl classM = ElementFactory.classElement2('M', []);
    WithClause withClause =
        AstTestFactory.withClause([AstTestFactory.typeName(classM, [])]);
    ClassTypeAlias alias = AstTestFactory.classTypeAlias(
        'C',
        AstTestFactory.typeParameterList(['T']),
        null,
        AstTestFactory.typeName(classB, []),
        withClause,
        null);

    ElementHolder holder = buildElementsForAst(alias);
    List<ClassElement> types = holder.types;
    expect(types, hasLength(1));
    ClassElement type = types[0];
    expect(type.typeParameters, hasLength(1));
    expect(type.typeParameters[0].name, equals('T'));
  }

  void test_visitConstructorDeclaration_external() {
    String className = "A";
    ConstructorDeclaration constructorDeclaration =
        AstTestFactory.constructorDeclaration2(
            null,
            null,
            AstTestFactory.identifier3(className),
            null,
            AstTestFactory.formalParameterList(),
            null,
            AstTestFactory.blockFunctionBody2());
    constructorDeclaration.externalKeyword =
        TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);

    ElementHolder holder = buildElementsForAst(constructorDeclaration);
    List<ConstructorElement> constructors = holder.constructors;
    expect(constructors, hasLength(1));
    ConstructorElement constructor = constructors[0];
    expect(constructor, isNotNull);
    expect(constructor.isExternal, isTrue);
    expect(constructor.isFactory, isFalse);
    expect(constructor.name, "");
    expect(constructor.parameters, hasLength(0));
  }

  void test_visitConstructorDeclaration_factory() {
    String className = "A";
    ConstructorDeclaration constructorDeclaration =
        AstTestFactory.constructorDeclaration2(
            null,
            Keyword.FACTORY,
            AstTestFactory.identifier3(className),
            null,
            AstTestFactory.formalParameterList(),
            null,
            AstTestFactory.blockFunctionBody2());

    ElementHolder holder = buildElementsForAst(constructorDeclaration);
    List<ConstructorElement> constructors = holder.constructors;
    expect(constructors, hasLength(1));
    ConstructorElement constructor = constructors[0];
    expect(constructor, isNotNull);
    expect(constructor.isExternal, isFalse);
    expect(constructor.isFactory, isTrue);
    expect(constructor.name, "");
    expect(constructor.parameters, hasLength(0));
  }

  void test_visitConstructorDeclaration_minimal() {
    String className = "A";
    ConstructorDeclaration constructorDeclaration =
        AstTestFactory.constructorDeclaration2(
            null,
            null,
            AstTestFactory.identifier3(className),
            null,
            AstTestFactory.formalParameterList(),
            null,
            AstTestFactory.blockFunctionBody2());
    constructorDeclaration.documentationComment =
        AstTestFactory.documentationComment(
            [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
    constructorDeclaration.endToken.offset = 80;

    ElementHolder holder = buildElementsForAst(constructorDeclaration);
    List<ConstructorElement> constructors = holder.constructors;
    expect(constructors, hasLength(1));
    ConstructorElement constructor = constructors[0];
    expect(constructor, isNotNull);
    assertHasCodeRange(constructor, 50, 31);
    expect(constructor.documentationComment, '/// aaa');
    expect(constructor.isExternal, isFalse);
    expect(constructor.isFactory, isFalse);
    expect(constructor.name, "");
    expect(constructor.parameters, hasLength(0));
  }

  void test_visitConstructorDeclaration_named() {
    String className = "A";
    String constructorName = "c";
    ConstructorDeclaration constructorDeclaration =
        AstTestFactory.constructorDeclaration2(
            null,
            null,
            AstTestFactory.identifier3(className),
            constructorName,
            AstTestFactory.formalParameterList(),
            null,
            AstTestFactory.blockFunctionBody2());

    ElementHolder holder = buildElementsForAst(constructorDeclaration);
    List<ConstructorElement> constructors = holder.constructors;
    expect(constructors, hasLength(1));
    ConstructorElement constructor = constructors[0];
    expect(constructor, isNotNull);
    expect(constructor.isExternal, isFalse);
    expect(constructor.isFactory, isFalse);
    expect(constructor.name, constructorName);
    expect(constructor.parameters, hasLength(0));
    expect(constructorDeclaration.name.staticElement, same(constructor));
    expect(constructorDeclaration.declaredElement, same(constructor));
  }

  void test_visitConstructorDeclaration_unnamed() {
    String className = "A";
    ConstructorDeclaration constructorDeclaration =
        AstTestFactory.constructorDeclaration2(
            null,
            null,
            AstTestFactory.identifier3(className),
            null,
            AstTestFactory.formalParameterList(),
            null,
            AstTestFactory.blockFunctionBody2());

    ElementHolder holder = buildElementsForAst(constructorDeclaration);
    List<ConstructorElement> constructors = holder.constructors;
    expect(constructors, hasLength(1));
    ConstructorElement constructor = constructors[0];
    expect(constructor, isNotNull);
    expect(constructor.isExternal, isFalse);
    expect(constructor.isFactory, isFalse);
    expect(constructor.name, "");
    expect(constructor.parameters, hasLength(0));
    expect(constructorDeclaration.declaredElement, same(constructor));
  }

  void test_visitEnumDeclaration() {
    String enumName = "E";
    EnumDeclaration enumDeclaration =
        AstTestFactory.enumDeclaration2(enumName, ["ONE"]);
    enumDeclaration.documentationComment = AstTestFactory.documentationComment(
        [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
    enumDeclaration.endToken.offset = 80;
    ElementHolder holder = buildElementsForAst(enumDeclaration);
    List<ClassElement> enums = holder.enums;
    expect(enums, hasLength(1));
    ClassElement enumElement = enums[0];
    expect(enumElement, isNotNull);
    assertHasCodeRange(enumElement, 50, 31);
    expect(enumElement.documentationComment, '/// aaa');
    expect(enumElement.name, enumName);
  }

  void test_visitFieldDeclaration() {
    var holder = buildElementsForText(r'''
class C {
  /// aaa
  int x = 1, y;
}
''');
    ClassElement c = holder.types.single;
    List<FieldElement> fields = c.fields;
    expect(fields, hasLength(2));

    FieldElement x = fields[0];
    expect(x, isNotNull);
    assertHasCodeRange(x, 12, 19);
    expect(x.documentationComment, '/// aaa');
    expect(x.name, 'x');
    _assertHasVariableInitializer(x);
    expect(x.isConst, isFalse);
    expect(x.isFinal, isFalse);
    expect(x.isSynthetic, isFalse);

    FieldElement y = fields[1];
    expect(y, isNotNull);
    assertHasCodeRange(y, 33, 1);
    expect(y.documentationComment, '/// aaa');
    expect(y.name, 'y');
    expect(y.initializer, isNull);
    expect(y.isConst, isFalse);
    expect(y.isFinal, isFalse);
    expect(y.isSynthetic, isFalse);
  }

  void test_visitFieldFormalParameter() {
    String parameterName = "p";
    FieldFormalParameter formalParameter =
        AstTestFactory.fieldFormalParameter(null, null, parameterName);
    formalParameter.beginToken.offset = 50;
    formalParameter.endToken.offset = 80;
    ElementHolder holder = buildElementsForAst(formalParameter);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));
    ParameterElement parameter = parameters[0];
    expect(parameter, isNotNull);
    assertHasCodeRange(parameter, 50, 31);
    expect(parameter.name, parameterName);
    expect(parameter.initializer, isNull);
    expect(parameter.isConst, isFalse);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.isRequiredPositional, isTrue);
    expect(parameter.parameters, hasLength(0));
  }

  void test_visitFieldFormalParameter_functionTyped() {
    String parameterName = "p";
    FieldFormalParameter formalParameter = AstTestFactory.fieldFormalParameter(
        null,
        null,
        parameterName,
        AstTestFactory.formalParameterList(
            [AstTestFactory.simpleFormalParameter3("a")]));
    ElementHolder holder = buildElementsForAst(formalParameter);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(1));

    ParameterElement parameter = parameters[0];
    var typeElement = parameter.type.element as GenericFunctionTypeElementImpl;
    expect(parameter, isNotNull);
    expect(parameter.name, parameterName);
    expect(parameter.initializer, isNull);
    expect(parameter.isConst, isFalse);
    expect(parameter.isFinal, isFalse);
    expect(parameter.isSynthetic, isFalse);
    expect(parameter.isRequiredPositional, isTrue);
    expect(typeElement.parameters, hasLength(1));
  }

  void test_visitFormalParameterList() {
    String firstParameterName = "a";
    String secondParameterName = "b";
    FormalParameterList parameterList = AstTestFactory.formalParameterList([
      AstTestFactory.simpleFormalParameter3(firstParameterName),
      AstTestFactory.simpleFormalParameter3(secondParameterName)
    ]);
    ElementHolder holder = buildElementsForAst(parameterList);
    List<ParameterElement> parameters = holder.parameters;
    expect(parameters, hasLength(2));
    expect(parameters[0].name, firstParameterName);
    expect(parameters[1].name, secondParameterName);
  }

  void test_visitFunctionDeclaration_external() {
    // external f();
    String functionName = "f";
    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
        null,
        null,
        functionName,
        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
            AstTestFactory.emptyFunctionBody()));
    declaration.externalKeyword =
        TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);

    ElementHolder holder = buildElementsForAst(declaration);
    List<FunctionElement> functions = holder.functions;
    expect(functions, hasLength(1));
    FunctionElement function = functions[0];
    expect(function, isNotNull);
    expect(function.name, functionName);
    expect(declaration.declaredElement, same(function));
    expect(declaration.functionExpression.declaredElement, same(function));
    expect(function.hasImplicitReturnType, isTrue);
    expect(function.isExternal, isTrue);
    expect(function.isSynthetic, isFalse);
    expect(function.typeParameters, hasLength(0));
  }

  void test_visitFunctionDeclaration_getter() {
    // get f() {}
    String functionName = "f";
    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
        null,
        Keyword.GET,
        functionName,
        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
            AstTestFactory.blockFunctionBody2()));
    declaration.documentationComment = AstTestFactory.documentationComment(
        [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
    declaration.endToken.offset = 80;

    ElementHolder holder = buildElementsForAst(declaration);
    List<PropertyAccessorElement> accessors = holder.accessors;
    expect(accessors, hasLength(1));
    PropertyAccessorElement accessor = accessors[0];
    expect(accessor, isNotNull);
    assertHasCodeRange(accessor, 50, 31);
    expect(accessor.documentationComment, '/// aaa');
    expect(accessor.name, functionName);
    expect(declaration.declaredElement, same(accessor));
    expect(declaration.functionExpression.declaredElement, same(accessor));
    expect(accessor.hasImplicitReturnType, isTrue);
    expect(accessor.isGetter, isTrue);
    expect(accessor.isExternal, isFalse);
    expect(accessor.isSetter, isFalse);
    expect(accessor.isSynthetic, isFalse);
    expect(accessor.typeParameters, hasLength(0));
    TopLevelVariableElement variable = accessor.variable;
    expect(variable.isSynthetic, isTrue);
  }

  void test_visitFunctionDeclaration_plain() {
    // T f() {}
    String functionName = "f";
    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
        AstTestFactory.typeName4('T'),
        null,
        functionName,
        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
            AstTestFactory.blockFunctionBody2()));
    declaration.documentationComment = AstTestFactory.documentationComment(
        [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
    declaration.endToken.offset = 80;

    ElementHolder holder = buildElementsForAst(declaration);
    List<FunctionElement> functions = holder.functions;
    expect(functions, hasLength(1));
    FunctionElement function = functions[0];
    expect(function, isNotNull);
    assertHasCodeRange(function, 50, 31);
    expect(function.documentationComment, '/// aaa');
    expect(function.hasImplicitReturnType, isFalse);
    expect(function.name, functionName);
    expect(declaration.declaredElement, same(function));
    expect(declaration.functionExpression.declaredElement, same(function));
    expect(function.isExternal, isFalse);
    expect(function.isSynthetic, isFalse);
    expect(function.typeParameters, hasLength(0));
  }

  void test_visitFunctionDeclaration_setter() {
    // set f() {}
    String functionName = "f";
    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
        null,
        Keyword.SET,
        functionName,
        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
            AstTestFactory.blockFunctionBody2()));
    declaration.documentationComment = AstTestFactory.documentationComment(
        [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
    declaration.endToken.offset = 80;

    ElementHolder holder = buildElementsForAst(declaration);
    List<PropertyAccessorElement> accessors = holder.accessors;
    expect(accessors, hasLength(1));
    PropertyAccessorElement accessor = accessors[0];
    expect(accessor, isNotNull);
    assertHasCodeRange(accessor, 50, 31);
    expect(accessor.documentationComment, '/// aaa');
    expect(accessor.hasImplicitReturnType, isTrue);
    expect(accessor.name, "$functionName=");
    expect(declaration.declaredElement, same(accessor));
    expect(declaration.functionExpression.declaredElement, same(accessor));
    expect(accessor.isGetter, isFalse);
    expect(accessor.isExternal, isFalse);
    expect(accessor.isSetter, isTrue);
    expect(accessor.isSynthetic, isFalse);
    expect(accessor.typeParameters, hasLength(0));
    TopLevelVariableElement variable = accessor.variable;
    expect(variable.isSynthetic, isTrue);
  }

  void test_visitFunctionDeclaration_typeParameters() {
    // f<E>() {}
    String functionName = 'f';
    String typeParameterName = 'E';
    FunctionExpression expression = AstTestFactory.functionExpression3(
        AstTestFactory.typeParameterList([typeParameterName]),
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2());
    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
        null, null, functionName, expression);

    ElementHolder holder = buildElementsForAst(declaration);
    List<FunctionElement> functions = holder.functions;
    expect(functions, hasLength(1));
    FunctionElement function = functions[0];
    expect(function, isNotNull);
    expect(function.hasImplicitReturnType, isTrue);
    expect(function.name, functionName);
    expect(function.isExternal, isFalse);
    expect(function.isSynthetic, isFalse);
    expect(declaration.declaredElement, same(function));
    expect(expression.declaredElement, same(function));
    List<TypeParameterElement> typeParameters = function.typeParameters;
    expect(typeParameters, hasLength(1));
    TypeParameterElement typeParameter = typeParameters[0];
    expect(typeParameter, isNotNull);
    expect(typeParameter.name, typeParameterName);
  }

  void test_visitMethodDeclaration_abstract() {
    // m();
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
        null,
        null,
        null,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList(),
        AstTestFactory.emptyFunctionBody());

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<MethodElement> methods = holder.methods;
    expect(methods, hasLength(1));
    MethodElement method = methods[0];
    expect(method, isNotNull);
    expect(method.hasImplicitReturnType, isTrue);
    expect(method.name, methodName);
    expect(method.parameters, hasLength(0));
    expect(method.typeParameters, hasLength(0));
    expect(method.isAbstract, isTrue);
    expect(method.isExternal, isFalse);
    expect(method.isStatic, isFalse);
    expect(method.isSynthetic, isFalse);
  }

  void test_visitMethodDeclaration_duplicateField_synthetic() {
    buildElementsForText(r'''
class A {
  int f;
  int get f => 42;
}
''');
    ClassDeclaration classNode = compilationUnit.declarations.single;
    // ClassElement
    ClassElement classElement = classNode.declaredElement;
    expect(classElement.fields, hasLength(2));
    expect(classElement.accessors, hasLength(3));
    FieldElement notSyntheticFieldElement = classElement.fields
        .singleWhere((f) => f.displayName == 'f' && !f.isSynthetic);
    FieldElement syntheticFieldElement = classElement.fields
        .singleWhere((f) => f.displayName == 'f' && f.isSynthetic);
    PropertyAccessorElement syntheticGetterElement = classElement.accessors
        .singleWhere(
            (a) => a.displayName == 'f' && a.isGetter && a.isSynthetic);
    PropertyAccessorElement syntheticSetterElement = classElement.accessors
        .singleWhere(
            (a) => a.displayName == 'f' && a.isSetter && a.isSynthetic);
    PropertyAccessorElement notSyntheticGetterElement = classElement.accessors
        .singleWhere(
            (a) => a.displayName == 'f' && a.isGetter && !a.isSynthetic);
    expect(notSyntheticFieldElement.getter, same(syntheticGetterElement));
    expect(notSyntheticFieldElement.setter, same(syntheticSetterElement));
    expect(syntheticFieldElement.getter, same(notSyntheticGetterElement));
    expect(syntheticFieldElement.setter, isNull);
    // class members nodes and their elements
    FieldDeclaration fieldDeclNode = classNode.members[0];
    VariableDeclaration fieldNode = fieldDeclNode.fields.variables.single;
    MethodDeclaration getterNode = classNode.members[1];
    expect(fieldNode.declaredElement, notSyntheticFieldElement);
    expect(getterNode.declaredElement, notSyntheticGetterElement);
  }

  void test_visitMethodDeclaration_external() {
    // external m();
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
        null,
        null,
        null,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList(),
        AstTestFactory.emptyFunctionBody());
    methodDeclaration.externalKeyword =
        TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<MethodElement> methods = holder.methods;
    expect(methods, hasLength(1));
    MethodElement method = methods[0];
    expect(method, isNotNull);
    expect(method.hasImplicitReturnType, isTrue);
    expect(method.name, methodName);
    expect(method.parameters, hasLength(0));
    expect(method.typeParameters, hasLength(0));
    expect(method.isAbstract, isFalse);
    expect(method.isExternal, isTrue);
    expect(method.isStatic, isFalse);
    expect(method.isSynthetic, isFalse);
  }

  void test_visitMethodDeclaration_getter() {
    // get m() {}
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
        null,
        null,
        Keyword.GET,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2());
    methodDeclaration.documentationComment =
        AstTestFactory.documentationComment(
            [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
    methodDeclaration.endToken.offset = 80;

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<FieldElement> fields = holder.fields;
    expect(fields, hasLength(1));
    FieldElement field = fields[0];
    expect(field, isNotNull);
    expect(field.name, methodName);
    expect(field.isSynthetic, isTrue);
    expect(field.setter, isNull);
    PropertyAccessorElement getter = field.getter;
    expect(getter, isNotNull);
    assertHasCodeRange(getter, 50, 31);
    expect(getter.documentationComment, '/// aaa');
    expect(getter.hasImplicitReturnType, isTrue);
    expect(getter.isAbstract, isFalse);
    expect(getter.isExternal, isFalse);
    expect(getter.isGetter, isTrue);
    expect(getter.isSynthetic, isFalse);
    expect(getter.name, methodName);
    expect(getter.variable, field);
    expect(getter.parameters, hasLength(0));
  }

  void test_visitMethodDeclaration_getter_abstract() {
    // get m();
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
        null,
        null,
        Keyword.GET,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList(),
        AstTestFactory.emptyFunctionBody());

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<FieldElement> fields = holder.fields;
    expect(fields, hasLength(1));
    FieldElement field = fields[0];
    expect(field, isNotNull);
    expect(field.name, methodName);
    expect(field.isSynthetic, isTrue);
    expect(field.setter, isNull);
    PropertyAccessorElement getter = field.getter;
    expect(getter, isNotNull);
    expect(getter.hasImplicitReturnType, isTrue);
    expect(getter.isAbstract, isTrue);
    expect(getter.isExternal, isFalse);
    expect(getter.isGetter, isTrue);
    expect(getter.isSynthetic, isFalse);
    expect(getter.name, methodName);
    expect(getter.variable, field);
    expect(getter.parameters, hasLength(0));
  }

  void test_visitMethodDeclaration_getter_external() {
    // external get m();
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration(
        null,
        null,
        Keyword.GET,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList());
    methodDeclaration.externalKeyword =
        TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<FieldElement> fields = holder.fields;
    expect(fields, hasLength(1));
    FieldElement field = fields[0];
    expect(field, isNotNull);
    expect(field.name, methodName);
    expect(field.isSynthetic, isTrue);
    expect(field.setter, isNull);
    PropertyAccessorElement getter = field.getter;
    expect(getter, isNotNull);
    expect(getter.hasImplicitReturnType, isTrue);
    expect(getter.isAbstract, isFalse);
    expect(getter.isExternal, isTrue);
    expect(getter.isGetter, isTrue);
    expect(getter.isSynthetic, isFalse);
    expect(getter.name, methodName);
    expect(getter.variable, field);
    expect(getter.parameters, hasLength(0));
  }

  void test_visitMethodDeclaration_minimal() {
    // T m() {}
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
        null,
        AstTestFactory.typeName4('T'),
        null,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2());
    methodDeclaration.documentationComment =
        AstTestFactory.documentationComment(
            [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
    methodDeclaration.endToken.offset = 80;

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<MethodElement> methods = holder.methods;
    expect(methods, hasLength(1));
    MethodElement method = methods[0];
    expect(method, isNotNull);
    assertHasCodeRange(method, 50, 31);
    expect(method.documentationComment, '/// aaa');
    expect(method.hasImplicitReturnType, isFalse);
    expect(method.name, methodName);
    expect(method.parameters, hasLength(0));
    expect(method.typeParameters, hasLength(0));
    expect(method.isAbstract, isFalse);
    expect(method.isExternal, isFalse);
    expect(method.isStatic, isFalse);
    expect(method.isSynthetic, isFalse);
  }

  void test_visitMethodDeclaration_operator() {
    // operator +(addend) {}
    String methodName = "+";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
        null,
        null,
        null,
        Keyword.OPERATOR,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList(
            [AstTestFactory.simpleFormalParameter3("addend")]),
        AstTestFactory.blockFunctionBody2());

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<MethodElement> methods = holder.methods;
    expect(methods, hasLength(1));
    MethodElement method = methods[0];
    expect(method, isNotNull);
    expect(method.hasImplicitReturnType, isTrue);
    expect(method.name, methodName);
    expect(method.parameters, hasLength(1));
    expect(method.typeParameters, hasLength(0));
    expect(method.isAbstract, isFalse);
    expect(method.isExternal, isFalse);
    expect(method.isStatic, isFalse);
    expect(method.isSynthetic, isFalse);
  }

  void test_visitMethodDeclaration_setter() {
    // set m() {}
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
        null,
        null,
        Keyword.SET,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2());
    methodDeclaration.documentationComment =
        AstTestFactory.documentationComment(
            [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
    methodDeclaration.endToken.offset = 80;

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<FieldElement> fields = holder.fields;
    expect(fields, hasLength(1));
    FieldElement field = fields[0];
    expect(field, isNotNull);
    expect(field.name, methodName);
    expect(field.isSynthetic, isTrue);
    expect(field.getter, isNull);

    PropertyAccessorElement setter = field.setter;
    expect(setter, isNotNull);
    assertHasCodeRange(setter, 50, 31);
    expect(setter.documentationComment, '/// aaa');
    expect(setter.hasImplicitReturnType, isTrue);
    expect(setter.isAbstract, isFalse);
    expect(setter.isExternal, isFalse);
    expect(setter.isSetter, isTrue);
    expect(setter.isSynthetic, isFalse);
    expect(setter.name, "$methodName=");
    expect(setter.displayName, methodName);
    expect(setter.variable, field);
    expect(setter.parameters, hasLength(0));
  }

  void test_visitMethodDeclaration_setter_abstract() {
    // set m();
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
        null,
        null,
        Keyword.SET,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList(),
        AstTestFactory.emptyFunctionBody());

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<FieldElement> fields = holder.fields;
    expect(fields, hasLength(1));
    FieldElement field = fields[0];
    expect(field, isNotNull);
    expect(field.name, methodName);
    expect(field.isSynthetic, isTrue);
    expect(field.getter, isNull);
    PropertyAccessorElement setter = field.setter;
    expect(setter, isNotNull);
    expect(setter.hasImplicitReturnType, isTrue);
    expect(setter.isAbstract, isTrue);
    expect(setter.isExternal, isFalse);
    expect(setter.isSetter, isTrue);
    expect(setter.isSynthetic, isFalse);
    expect(setter.name, "$methodName=");
    expect(setter.displayName, methodName);
    expect(setter.variable, field);
    expect(setter.parameters, hasLength(0));
  }

  void test_visitMethodDeclaration_setter_external() {
    // external m();
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration(
        null,
        null,
        Keyword.SET,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList());
    methodDeclaration.externalKeyword =
        TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<FieldElement> fields = holder.fields;
    expect(fields, hasLength(1));
    FieldElement field = fields[0];
    expect(field, isNotNull);
    expect(field.name, methodName);
    expect(field.isSynthetic, isTrue);
    expect(field.getter, isNull);
    PropertyAccessorElement setter = field.setter;
    expect(setter, isNotNull);
    expect(setter.hasImplicitReturnType, isTrue);
    expect(setter.isAbstract, isFalse);
    expect(setter.isExternal, isTrue);
    expect(setter.isSetter, isTrue);
    expect(setter.isSynthetic, isFalse);
    expect(setter.name, "$methodName=");
    expect(setter.displayName, methodName);
    expect(setter.variable, field);
    expect(setter.parameters, hasLength(0));
  }

  void test_visitMethodDeclaration_static() {
    // static m() {}
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
        Keyword.STATIC,
        null,
        null,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2());
    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<MethodElement> methods = holder.methods;
    expect(methods, hasLength(1));
    MethodElement method = methods[0];
    expect(method, isNotNull);
    expect(method.hasImplicitReturnType, isTrue);
    expect(method.name, methodName);
    expect(method.parameters, hasLength(0));
    expect(method.typeParameters, hasLength(0));
    expect(method.isAbstract, isFalse);
    expect(method.isExternal, isFalse);
    expect(method.isStatic, isTrue);
    expect(method.isSynthetic, isFalse);
  }

  void test_visitMethodDeclaration_typeParameters() {
    // m<E>() {}
    String methodName = "m";
    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
        null,
        null,
        null,
        null,
        AstTestFactory.identifier3(methodName),
        AstTestFactory.formalParameterList(),
        AstTestFactory.blockFunctionBody2());
    methodDeclaration.typeParameters = AstTestFactory.typeParameterList(['E']);

    ElementHolder holder = buildElementsForAst(methodDeclaration);
    List<MethodElement> methods = holder.methods;
    expect(methods, hasLength(1));
    MethodElement method = methods[0];
    expect(method, isNotNull);
    expect(method.hasImplicitReturnType, isTrue);
    expect(method.name, methodName);
    expect(method.parameters, hasLength(0));
    expect(method.typeParameters, hasLength(1));
    expect(method.isAbstract, isFalse);
    expect(method.isExternal, isFalse);
    expect(method.isStatic, isFalse);
    expect(method.isSynthetic, isFalse);
  }

  void test_visitMixinDeclaration() {
    isMixinSupportEnabled = true;
    var holder = buildElementsForText(r'''
/// doc
mixin M<T, U> on A, B implements C {
  double f;
  int get g => 0;
  set s(int v) {}
  int m(int v) => 0;
}
''');
    var mixins = holder.mixins;
    expect(mixins, hasLength(1));
    var type = mixins[0];
    expect(type.name, 'M');
    expect(type.isMixin, isTrue);
    expect(type.documentationComment, '/// doc');
    assertHasCodeRange(type, 0, 115);

    List<TypeParameterElement> typeParameters = type.typeParameters;
    expect(typeParameters, hasLength(2));
    expect(typeParameters[0].name, 'T');
    expect(typeParameters[1].name, 'U');

    var fields = type.fields;
    expect(fields, hasLength(3));
    expect(fields[0].name, 'f');
    expect(fields[1].name, 'g');
    expect(fields[2].name, 's');

    var accessors = type.accessors;
    expect(accessors, hasLength(4));
    expect(accessors[0].name, 'f');
    expect(accessors[1].name, 'f=');
    expect(accessors[2].name, 'g');
    expect(accessors[3].name, 's=');

    var methods = type.methods;
    expect(methods, hasLength(1));
    expect(methods[0].name, 'm');
  }

  void test_visitTypeAlias_minimal() {
    String aliasName = "F";
    TypeAlias typeAlias = AstTestFactory.typeAlias(null, aliasName, null, null);
    ElementHolder holder = buildElementsForAst(typeAlias);
    List<FunctionTypeAliasElement> aliases = holder.typeAliases;
    expect(aliases, hasLength(1));
    FunctionTypeAliasElement alias = aliases[0];
    expect(alias, isNotNull);
    expect(alias.name, aliasName);
    expect(alias.type, isNotNull);
    expect(alias.isSynthetic, isFalse);
  }

  void test_visitTypeAlias_withFormalParameters() {
    String aliasName = "F";
    String firstParameterName = "x";
    String secondParameterName = "y";
    TypeAlias typeAlias = AstTestFactory.typeAlias(
        null,
        aliasName,
        AstTestFactory.typeParameterList(),
        AstTestFactory.formalParameterList([
          AstTestFactory.simpleFormalParameter3(firstParameterName),
          AstTestFactory.simpleFormalParameter3(secondParameterName)
        ]));
    typeAlias.beginToken.offset = 50;
    typeAlias.endToken.offset = 80;
    ElementHolder holder = buildElementsForAst(typeAlias);
    List<FunctionTypeAliasElement> aliases = holder.typeAliases;
    expect(aliases, hasLength(1));
    GenericTypeAliasElementImpl alias = aliases[0];
    expect(alias, isNotNull);
    assertHasCodeRange(alias, 50, 31);
    expect(alias.name, aliasName);
    expect(alias.type, isNotNull);
    expect(alias.isSynthetic, isFalse);
    List<VariableElement> parameters = alias.parameters;
    expect(parameters, hasLength(2));
    expect(parameters[0].name, firstParameterName);
    expect(parameters[1].name, secondParameterName);
    List<TypeParameterElement> typeParameters = alias.typeParameters;
    expect(typeParameters, isNotNull);
    expect(typeParameters, hasLength(0));
  }

  void test_visitTypeAlias_withTypeParameters() {
    String aliasName = "F";
    String firstTypeParameterName = "A";
    String secondTypeParameterName = "B";
    TypeAlias typeAlias = AstTestFactory.typeAlias(
        null,
        aliasName,
        AstTestFactory.typeParameterList(
            [firstTypeParameterName, secondTypeParameterName]),
        AstTestFactory.formalParameterList());
    ElementHolder holder = buildElementsForAst(typeAlias);
    List<FunctionTypeAliasElement> aliases = holder.typeAliases;
    expect(aliases, hasLength(1));
    GenericTypeAliasElementImpl alias = aliases[0];
    expect(alias, isNotNull);
    expect(alias.name, aliasName);
    expect(alias.type, isNotNull);
    expect(alias.isSynthetic, isFalse);
    List<VariableElement> parameters = alias.parameters;
    expect(parameters, isNotNull);
    expect(parameters, hasLength(0));
    List<TypeParameterElement> typeParameters = alias.typeParameters;
    expect(typeParameters, hasLength(2));
    expect(typeParameters[0].name, firstTypeParameterName);
    expect(typeParameters[1].name, secondTypeParameterName);
  }

  void test_visitTypeParameter() {
    String parameterName = "E";
    TypeParameter typeParameter = AstTestFactory.typeParameter(parameterName);
    typeParameter.beginToken.offset = 50;
    ElementHolder holder = buildElementsForAst(typeParameter);
    List<TypeParameterElement> typeParameters = holder.typeParameters;
    expect(typeParameters, hasLength(1));
    TypeParameterElement typeParameterElement = typeParameters[0];
    expect(typeParameterElement, isNotNull);
    assertHasCodeRange(typeParameterElement, 50, 1);
    expect(typeParameterElement.name, parameterName);
    expect(typeParameterElement.bound, isNull);
    expect(typeParameterElement.isSynthetic, isFalse);
  }

  void _assertHasVariableInitializer(VariableElement element) {
    expect(element.initializer, isNotNull);
  }
}

abstract class _BaseTest extends ParserTestCase {
  CompilationUnitElement compilationUnitElement;
  CompilationUnit _compilationUnit;

  CompilationUnit get compilationUnit => _compilationUnit;

  void assertHasCodeRange(Element element, int offset, int length) {
    ElementImpl elementImpl = element;
    expect(elementImpl.codeOffset, offset);
    expect(elementImpl.codeLength, length);
  }

  /**
   * Build elements using [ApiElementBuilder].
   */
  ElementHolder buildElementsForAst(AstNode node) {
    ElementHolder holder = new ElementHolder();
    AstVisitor builder = createElementBuilder(holder);
    node.accept(builder);
    return holder;
  }

  /**
   * Parse the given [code], and build elements using [ApiElementBuilder].
   */
  ElementHolder buildElementsForText(String code) {
    ElementHolder holder = new ElementHolder();
    AstVisitor builder = createElementBuilder(holder);
    _visitAstOfCode(code, builder);
    return holder;
  }

  /**
   * Verify that the given [metadata] has exactly one annotation, and that its
   * [ElementAnnotationImpl] is unresolved.
   */
  void checkAnnotation(NodeList<Annotation> metadata) {
    expect(metadata, hasLength(1));
    expect(metadata[0], new TypeMatcher<AnnotationImpl>());
    AnnotationImpl annotation = metadata[0];
    expect(
        annotation.elementAnnotation, new TypeMatcher<ElementAnnotationImpl>());
    ElementAnnotationImpl elementAnnotation = annotation.elementAnnotation;
    expect(elementAnnotation.element, isNull); // Not yet resolved
    expect(elementAnnotation.compilationUnit, isNotNull);
    expect(elementAnnotation.compilationUnit, compilationUnitElement);
  }

  /**
   * Verify that the given [element] has exactly one annotation, and that its
   * [ElementAnnotationImpl] is unresolved.
   */
  void checkMetadata(Element element) {
    expect(element.metadata, hasLength(1));
    expect(element.metadata[0], new TypeMatcher<ElementAnnotationImpl>());
    ElementAnnotationImpl elementAnnotation = element.metadata[0];
    expect(elementAnnotation.element, isNull); // Not yet resolved
    expect(elementAnnotation.compilationUnit, isNotNull);
    expect(elementAnnotation.compilationUnit, compilationUnitElement);
  }

  AstVisitor createElementBuilder(ElementHolder holder);

  SimpleIdentifier findIdentifier(String code, String prefix) {
    return EngineTestCase.findSimpleIdentifier(compilationUnit, code, prefix);
  }

  LabelElement findLabel(String code, String prefix) {
    return findIdentifier(code, prefix).staticElement;
  }

  FunctionElement findLocalFunction(String code, String prefix) {
    return findIdentifier(code, prefix).staticElement;
  }

  LocalVariableElement findLocalVariable(String code, String prefix) {
    return findIdentifier(code, prefix).staticElement;
  }

  void setUp() {
    compilationUnitElement = new CompilationUnitElementImpl();
  }

  void _assertVisibleRange(LocalElement element, int offset, int end) {
    SourceRange visibleRange = element.visibleRange;
    expect(visibleRange.offset, offset);
    expect(visibleRange.end, end);
  }

  /**
   * Parse the given [code], and visit it with the given [visitor].
   * Fail if any error is logged.
   */
  void _visitAstOfCode(String code, AstVisitor visitor) {
    TestLogger logger = new TestLogger();
    AnalysisEngine.instance.logger = logger;
    try {
      _compilationUnit = parseCompilationUnit(code);
      compilationUnit.accept(visitor);
    } finally {
      expect(logger.log, hasLength(0));
      AnalysisEngine.instance.logger = Logger.NULL;
    }
  }
}
