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

library test.src.serialization.elements_test;

import 'dart:convert';

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/resolver.dart' show Namespace;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/resynthesize.dart';
import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:unittest/unittest.dart';

import '../../generated/test_support.dart';
import '../../reflective_tests.dart';
import '../abstract_single_unit.dart';
import '../context/abstract_context.dart';
import 'summary_common.dart' show canonicalize;

main() {
  groupSep = ' | ';
  runReflectiveTests(ResynthesizeElementTest);
}

/**
 * Abstract base class for resynthesizing and comparing elements.
 */
abstract class AbstractResynthesizeTest extends AbstractSingleUnitTest {
  Set<Source> otherLibrarySources = new Set<Source>();

  /**
   * Names of variables which have initializers that are not valid constants,
   * so they are not resynthesized.
   */
  Set<String> variablesWithNotConstInitializers = new Set<String>();

  bool get checkPropagatedTypes => true;

  void addLibrary(String uri) {
    otherLibrarySources.add(context.sourceFactory.forUri(uri));
  }

  Source addLibrarySource(String filePath, String contents) {
    Source source = addSource(filePath, contents);
    otherLibrarySources.add(source);
    return source;
  }

  void assertNoErrors(Source source) {
    GatheringErrorListener errorListener = new GatheringErrorListener();
    for (AnalysisError error in context.computeErrors(source)) {
      expect(error.source, source);
      ErrorCode errorCode = error.errorCode;
      if (errorCode == HintCode.UNUSED_ELEMENT ||
          errorCode == HintCode.UNUSED_FIELD) {
        continue;
      }
      if (errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
          errorCode == HintCode.UNUSED_CATCH_STACK ||
          errorCode == HintCode.UNUSED_LOCAL_VARIABLE) {
        continue;
      }
      errorListener.onError(error);
    }
    errorListener.assertNoErrors();
  }

  /**
   * Verify that the given prefix is safe to elide from a resynthesized AST.
   */
  void checkElidablePrefix(SimpleIdentifier prefix) {
    if (prefix.staticElement is! PrefixElement &&
        prefix.staticElement is! ClassElement) {
      fail('Prefix of type ${prefix.staticElement.runtimeType}'
          ' should not have been elided');
    }
  }

  void checkLibraryElements(
      LibraryElementImpl original, LibraryElementImpl resynthesized) {
    compareElements(resynthesized, original, '(library)');
    expect(resynthesized.displayName, original.displayName);
    expect(original.enclosingElement, isNull);
    expect(resynthesized.enclosingElement, isNull);
    expect(resynthesized.hasExtUri, original.hasExtUri);
    compareCompilationUnitElements(resynthesized.definingCompilationUnit,
        original.definingCompilationUnit);
    expect(resynthesized.parts.length, original.parts.length, reason: 'parts');
    for (int i = 0; i < resynthesized.parts.length; i++) {
      compareCompilationUnitElements(resynthesized.parts[i], original.parts[i]);
    }
    expect(resynthesized.imports.length, original.imports.length,
        reason: 'imports');
    for (int i = 0; i < resynthesized.imports.length; i++) {
      compareImportElements(resynthesized.imports[i], original.imports[i],
          'import ${original.imports[i].uri}');
    }
    expect(resynthesized.exports.length, original.exports.length,
        reason: 'exports');
    for (int i = 0; i < resynthesized.exports.length; i++) {
      compareExportElements(resynthesized.exports[i], original.exports[i],
          'export ${original.exports[i].uri}');
    }
    expect(resynthesized.nameLength, original.nameLength);
    compareNamespaces(resynthesized.publicNamespace, original.publicNamespace,
        '(public namespace)');
    compareNamespaces(resynthesized.exportNamespace, original.exportNamespace,
        '(export namespace)');
    if (original.entryPoint == null) {
      expect(resynthesized.entryPoint, isNull);
    } else {
      expect(resynthesized.entryPoint, isNotNull);
      compareFunctionElements(
          resynthesized.entryPoint, original.entryPoint, '(entry point)');
    }
    // The libraries `dart:core` and `dart:async` cannot create their
    // `loadLibrary` functions until after both are created.
    if (original.name != 'dart.core' && original.name != 'dart.async') {
      compareExecutableElements(
          resynthesized.loadLibraryFunction as ExecutableElementImpl,
          original.loadLibraryFunction as ExecutableElementImpl,
          '(loadLibraryFunction)');
    }
    expect(resynthesized.libraryCycle.toSet(), original.libraryCycle.toSet());
  }

  /**
   * Verify that the [resynthesizer] didn't do any unnecessary work when
   * resynthesizing [library].
   */
  void checkMinimalResynthesisWork(
      TestSummaryResynthesizer resynthesizer, LibraryElement library) {
    // Check that no other summaries needed to be resynthesized to resynthesize
    // the library element.
    expect(resynthesizer.resynthesisCount, 1);
    // Check that the only linked summary consulted was that for [uri].
    expect(resynthesizer.linkedSummariesRequested, hasLength(1));
    expect(resynthesizer.linkedSummariesRequested.first,
        library.source.uri.toString());
    // Check that the only unlinked summaries consulted were those for the
    // library in question.
    Set<String> expectedCompilationUnitUris = library.units
        .map((CompilationUnitElement unit) => unit.source.uri.toString())
        .toSet();
    for (String requestedUri in resynthesizer.unlinkedSummariesRequested) {
      expect(expectedCompilationUnitUris, contains(requestedUri));
    }
  }

  void checkPossibleLocalElements(Element resynthesized, Element original) {
    if (original is! LocalElement && resynthesized is! LocalElement) {
      return;
    }
    if (original is LocalElement && resynthesized is LocalElement) {
      expect(resynthesized.visibleRange, original.visibleRange);
    } else {
      fail('Incompatible local elements '
          '${resynthesized.runtimeType} vs. ${original.runtimeType}');
    }
  }

  void checkPossibleMember(
      Element resynthesized, Element original, String desc) {
    Element resynthesizedNonHandle = resynthesized is ElementHandle
        ? resynthesized.actualElement
        : resynthesized;
    if (original is Member) {
      expect(resynthesizedNonHandle, new isInstanceOf<Member>(), reason: desc);
      if (resynthesizedNonHandle is Member) {
        List<DartType> resynthesizedTypeArguments =
            resynthesizedNonHandle.definingType.typeArguments;
        List<DartType> originalTypeArguments =
            original.definingType.typeArguments;
        expect(
            resynthesizedTypeArguments, hasLength(originalTypeArguments.length),
            reason: desc);
        for (int i = 0; i < originalTypeArguments.length; i++) {
          compareTypeImpls(resynthesizedTypeArguments[i],
              originalTypeArguments[i], '$desc type argument $i');
        }
      }
    } else {
      expect(
          resynthesizedNonHandle, isNot(new isInstanceOf<ConstructorMember>()),
          reason: desc);
    }
  }

  void compareClassElements(ClassElement r, ClassElement o, String desc) {
    compareElements(r, o, desc);
    expect(r.fields.length, o.fields.length, reason: '$desc fields.length');
    for (int i = 0; i < r.fields.length; i++) {
      String name = o.fields[i].name;
      compareFieldElements(r.fields[i], o.fields[i], '$desc.field $name');
    }
    compareTypes(r.supertype, o.supertype, '$desc supertype');
    expect(r.interfaces.length, o.interfaces.length,
        reason: '$desc interfaces.length');
    for (int i = 0; i < r.interfaces.length; i++) {
      compareTypes(r.interfaces[i], o.interfaces[i],
          '$desc interface ${o.interfaces[i].name}');
    }
    expect(r.mixins.length, o.mixins.length, reason: '$desc mixins.length');
    for (int i = 0; i < r.mixins.length; i++) {
      compareTypes(r.mixins[i], o.mixins[i], '$desc mixin ${o.mixins[i].name}');
    }
    expect(r.typeParameters.length, o.typeParameters.length,
        reason: '$desc typeParameters.length');
    for (int i = 0; i < r.typeParameters.length; i++) {
      compareTypeParameterElements(r.typeParameters[i], o.typeParameters[i],
          '$desc type parameter ${o.typeParameters[i].name}');
    }
    expect(r.constructors.length, o.constructors.length,
        reason: '$desc constructors.length');
    for (int i = 0; i < r.constructors.length; i++) {
      compareConstructorElements(r.constructors[i], o.constructors[i],
          '$desc constructor ${o.constructors[i].name}');
    }
    expect(r.accessors.length, o.accessors.length,
        reason: '$desc accessors.length');
    List<PropertyAccessorElement> rAccessors = _getSortedPropertyAccessors(r);
    List<PropertyAccessorElement> oAccessors = _getSortedPropertyAccessors(o);
    for (int i = 0; i < r.accessors.length; i++) {
      comparePropertyAccessorElements(
          rAccessors[i], oAccessors[i], '$desc accessor ${oAccessors[i].name}');
    }
    expect(r.methods.length, o.methods.length, reason: '$desc methods.length');
    for (int i = 0; i < r.methods.length; i++) {
      compareMethodElements(
          r.methods[i], o.methods[i], '$desc.${o.methods[i].name}');
    }
    compareTypes(r.type, o.type, desc);
    if (r is ClassElementImpl && o is ClassElementImpl) {
      expect(r.hasBeenInferred, o.hasBeenInferred, reason: desc);
    }
  }

  void compareCompilationUnitElements(CompilationUnitElementImpl resynthesized,
      CompilationUnitElementImpl original) {
    String desc = 'Compilation unit ${original.source.uri}';
    compareUriReferencedElements(resynthesized, original, desc);
    expect(resynthesized.source, original.source);
    expect(resynthesized.librarySource, original.librarySource);
    expect(resynthesized.types.length, original.types.length,
        reason: '$desc types');
    for (int i = 0; i < resynthesized.types.length; i++) {
      compareClassElements(
          resynthesized.types[i], original.types[i], original.types[i].name);
    }
    expect(resynthesized.topLevelVariables.length,
        original.topLevelVariables.length,
        reason: '$desc topLevelVariables');
    for (int i = 0; i < resynthesized.topLevelVariables.length; i++) {
      String name = resynthesized.topLevelVariables[i].name;
      compareTopLevelVariableElements(
          resynthesized.topLevelVariables[i],
          original.topLevelVariables
              .singleWhere((TopLevelVariableElement e) => e.name == name),
          'variable $name');
    }
    expect(resynthesized.functions.length, original.functions.length,
        reason: '$desc functions');
    for (int i = 0; i < resynthesized.functions.length; i++) {
      compareFunctionElements(resynthesized.functions[i], original.functions[i],
          'function ${original.functions[i].name}');
    }
    expect(resynthesized.functionTypeAliases.length,
        original.functionTypeAliases.length,
        reason: '$desc functionTypeAliases');
    for (int i = 0; i < resynthesized.functionTypeAliases.length; i++) {
      compareFunctionTypeAliasElements(
          resynthesized.functionTypeAliases[i],
          original.functionTypeAliases[i],
          original.functionTypeAliases[i].name);
    }
    expect(resynthesized.enums.length, original.enums.length,
        reason: '$desc enums');
    for (int i = 0; i < resynthesized.enums.length; i++) {
      compareClassElements(
          resynthesized.enums[i], original.enums[i], original.enums[i].name);
    }
    expect(resynthesized.accessors.length, original.accessors.length,
        reason: '$desc accessors');
    for (int i = 0; i < resynthesized.accessors.length; i++) {
      String name = resynthesized.accessors[i].name;
      if (original.accessors[i].isGetter) {
        comparePropertyAccessorElements(
            resynthesized.accessors[i],
            original.accessors
                .singleWhere((PropertyAccessorElement e) => e.name == name),
            'getter $name');
      } else {
        comparePropertyAccessorElements(
            resynthesized.accessors[i],
            original.accessors
                .singleWhere((PropertyAccessorElement e) => e.name == name),
            'setter $name');
      }
    }
    // Note: no need to test CompilationUnitElementImpl._offsetToElementMap
    // since it is built on demand when needed (see
    // CompilationUnitElementImpl.getElementAt])
  }

  void compareConstAstLists(
      List<Object> rItems, List<Object> oItems, String desc) {
    if (rItems == null && oItems == null) {
      return;
    }
    expect(rItems != null && oItems != null, isTrue);
    expect(rItems, hasLength(oItems.length));
    for (int i = 0; i < oItems.length; i++) {
      Object rItem = rItems[i];
      Object oItem = oItems[i];
      if (rItem is Expression && oItem is Expression) {
        compareConstAsts(rItem, oItem, desc);
      } else if (rItem is TypeName && oItem is TypeName) {
        compareConstAsts(rItem.name, oItem.name, desc);
      } else if (rItem is InterpolationString && oItem is InterpolationString) {
        expect(rItem.value, oItem.value);
      } else if (rItem is InterpolationExpression &&
          oItem is InterpolationExpression) {
        compareConstAsts(rItem.expression, oItem.expression, desc);
      } else if (rItem is MapLiteralEntry && oItem is MapLiteralEntry) {
        compareConstAsts(rItem.key, oItem.key, desc);
        compareConstAsts(rItem.value, oItem.value, desc);
      } else if (oItem is ConstructorFieldInitializer &&
          rItem is ConstructorFieldInitializer) {
        compareConstAsts(rItem.fieldName, oItem.fieldName, desc);
        if (variablesWithNotConstInitializers.contains(rItem.fieldName.name)) {
          _assertUnresolvedIdentifier(rItem.expression, desc);
        } else {
          compareConstAsts(rItem.expression, oItem.expression, desc);
        }
      } else if (oItem is SuperConstructorInvocation &&
          rItem is SuperConstructorInvocation) {
        compareElements(rItem.staticElement, oItem.staticElement, desc);
        compareConstAsts(rItem.constructorName, oItem.constructorName, desc);
        compareConstAstLists(
            rItem.argumentList.arguments, oItem.argumentList.arguments, desc);
      } else if (oItem is RedirectingConstructorInvocation &&
          rItem is RedirectingConstructorInvocation) {
        compareElements(rItem.staticElement, oItem.staticElement, desc);
        compareConstAsts(rItem.constructorName, oItem.constructorName, desc);
        compareConstAstLists(
            rItem.argumentList.arguments, oItem.argumentList.arguments, desc);
      } else {
        fail('$desc Incompatible item types: '
            '${rItem.runtimeType} vs. ${oItem.runtimeType}');
      }
    }
  }

  void compareConstAsts(AstNode r, AstNode o, String desc) {
    if (o == null) {
      expect(r, isNull, reason: desc);
    } else {
      expect(r, isNotNull, reason: desc);
      // ConstantAstCloner does not copy static types, and constant values
      // computer does not use static types. So, we don't set them during
      // resynthesis and should not check them here.
      if (o is ParenthesizedExpression) {
        // We don't resynthesize parenthesis, so just ignore it.
        compareConstAsts(r, o.expression, desc);
      } else if (o is SimpleIdentifier && r is SimpleIdentifier) {
        expect(r.name, o.name, reason: desc);
        compareElements(r.staticElement, o.staticElement, desc);
      } else if (o is PrefixedIdentifier && r is SimpleIdentifier) {
        // We don't resynthesize prefixed identifiers when the prefix refers to
        // a PrefixElement or a ClassElement.  We use simple identifiers with
        // correct elements.
        if (o.prefix.staticElement is PrefixElement ||
            o.prefix.staticElement is ClassElement) {
          compareConstAsts(r, o.identifier, desc);
        } else {
          fail('Prefix of type ${o.prefix.staticElement.runtimeType} should not'
              ' have been elided');
        }
      } else if (o is SimpleIdentifier && r is PrefixedIdentifier) {
        // In 'class C {static const a = 0; static const b = a;}' the reference
        // to 'a' in 'b' is serialized as a fully qualified 'C.a' reference.
        if (r.prefix.staticElement is ClassElement) {
          compareElements(
              r.prefix.staticElement, o.staticElement?.enclosingElement, desc);
          compareConstAsts(r.identifier, o, desc);
        } else {
          fail('Prefix of type ${r.prefix.staticElement.runtimeType} should not'
              ' have been elided');
        }
      } else if (o is PropertyAccess &&
          o.target is PrefixedIdentifier &&
          r is PrefixedIdentifier) {
        // We don't resynthesize prefixed identifiers when the prefix refers to
        // a PrefixElement or a ClassElement.  Which means that if the original
        // expression was e.g. `prefix.topLevelVariableName.length`, it will get
        // resynthesized as `topLevelVariableName.length`
        PrefixedIdentifier oTarget = o.target;
        checkElidablePrefix(oTarget.prefix);
        compareConstAsts(
            r, AstFactory.identifier(oTarget.identifier, o.propertyName), desc);
      } else if (o is PrefixedIdentifier && r is PrefixedIdentifier) {
        compareConstAsts(r.prefix, o.prefix, desc);
        compareConstAsts(r.identifier, o.identifier, desc);
      } else if (o is PropertyAccess && r is PropertyAccess) {
        compareConstAsts(r.target, o.target, desc);
        String oName = o.propertyName.name;
        String rName = r.propertyName.name;
        expect(rName, oName, reason: desc);
        if (oName == 'length') {
          compareElements(
              r.propertyName.staticElement, o.propertyName.staticElement, desc);
        }
      } else if (o is PropertyAccess &&
          o.target is PrefixedIdentifier &&
          r is SimpleIdentifier) {
        // We don't resynthesize property access when it takes the form
        // `prefixName.className.staticMember`.  We just resynthesize a
        // SimpleIdentifier correctly resolved to the static member.
        PrefixedIdentifier oTarget = o.target;
        checkElidablePrefix(oTarget.prefix);
        checkElidablePrefix(oTarget.identifier);
        compareConstAsts(r, o.propertyName, desc);
      } else if (o is NullLiteral) {
        expect(r, new isInstanceOf<NullLiteral>(), reason: desc);
      } else if (o is BooleanLiteral && r is BooleanLiteral) {
        expect(r.value, o.value, reason: desc);
      } else if (o is IntegerLiteral && r is IntegerLiteral) {
        expect(r.value, o.value, reason: desc);
      } else if (o is DoubleLiteral && r is DoubleLiteral) {
        if (r.value != null &&
            r.value.isNaN &&
            o.value != null &&
            o.value.isNaN) {
          // NaN is not comparable.
        } else {
          expect(r.value, o.value, reason: desc);
        }
      } else if (o is StringInterpolation && r is StringInterpolation) {
        compareConstAstLists(r.elements, o.elements, desc);
      } else if (o is StringLiteral && r is StringLiteral) {
        // We don't keep all the tokens of AdjacentStrings.
        // So, we can compare only their values.
        expect(r.stringValue, o.stringValue, reason: desc);
      } else if (o is SymbolLiteral && r is SymbolLiteral) {
        // We don't keep all the tokens of symbol literals.
        // So, we can compare only their values.
        expect(r.components.map((t) => t.lexeme).join('.'),
            o.components.map((t) => t.lexeme).join('.'),
            reason: desc);
      } else if (o is NamedExpression && r is NamedExpression) {
        expect(r.name.label.name, o.name.label.name, reason: desc);
        compareConstAsts(r.expression, o.expression, desc);
      } else if (o is BinaryExpression && r is BinaryExpression) {
        expect(r.operator.lexeme, o.operator.lexeme, reason: desc);
        compareConstAsts(r.leftOperand, o.leftOperand, desc);
        compareConstAsts(r.rightOperand, o.rightOperand, desc);
      } else if (o is PrefixExpression && r is PrefixExpression) {
        expect(r.operator.lexeme, o.operator.lexeme, reason: desc);
        compareConstAsts(r.operand, o.operand, desc);
      } else if (o is ConditionalExpression && r is ConditionalExpression) {
        compareConstAsts(r.condition, o.condition, desc);
        compareConstAsts(r.thenExpression, o.thenExpression, desc);
        compareConstAsts(r.elseExpression, o.elseExpression, desc);
      } else if (o is ListLiteral && r is ListLiteral) {
        compareConstAstLists(
            r.typeArguments?.arguments, o.typeArguments?.arguments, desc);
        compareConstAstLists(r.elements, o.elements, desc);
      } else if (o is MapLiteral && r is MapLiteral) {
        compareConstAstLists(
            r.typeArguments?.arguments, o.typeArguments?.arguments, desc);
        compareConstAstLists(r.entries, o.entries, desc);
      } else if (o is MethodInvocation && r is MethodInvocation) {
        compareConstAsts(r.target, o.target, desc);
        compareConstAsts(r.methodName, o.methodName, desc);
        compareConstAstLists(
            r.typeArguments?.arguments, o.typeArguments?.arguments, desc);
        compareConstAstLists(
            r.argumentList?.arguments, o.argumentList?.arguments, desc);
      } else if (o is InstanceCreationExpression &&
          r is InstanceCreationExpression) {
        compareElements(r.staticElement, o.staticElement, desc);
        ConstructorName oConstructor = o.constructorName;
        ConstructorName rConstructor = r.constructorName;
        expect(oConstructor, isNotNull, reason: desc);
        expect(rConstructor, isNotNull, reason: desc);
        // Note: just compare rConstructor.staticElement and
        // oConstructor.staticElement as elements, because we just want to
        // check that they're pointing to the correct elements; we don't want
        // to check that their constructor initializers match, because that
        // could lead to infinite regress.
        compareElements(
            rConstructor.staticElement, oConstructor.staticElement, desc);
        TypeName oType = oConstructor.type;
        TypeName rType = rConstructor.type;
        expect(oType, isNotNull, reason: desc);
        expect(rType, isNotNull, reason: desc);
        compareConstAsts(rType.name, oType.name, desc);
        compareConstAsts(rConstructor.name, oConstructor.name, desc);
        // In strong mode type inference is performed, so that
        // `C<int> v = new C();` is serialized as `C<int> v = new C<int>();`.
        // So, if there are not type arguments originally, not need to check.
        if (oType.typeArguments?.arguments?.isNotEmpty ?? false) {
          compareConstAstLists(rType.typeArguments?.arguments,
              oType.typeArguments?.arguments, desc);
        }
        compareConstAstLists(
            r.argumentList.arguments, o.argumentList.arguments, desc);
      } else if (o is AnnotationImpl && r is AnnotationImpl) {
        expect(o.atSign.lexeme, r.atSign.lexeme, reason: desc);
        Identifier rName = r.name;
        Identifier oName = o.name;
        if (oName is PrefixedIdentifier && o.constructorName != null) {
          // E.g. `@prefix.cls.ctor`.  This gets resynthesized as `@cls.ctor`,
          // with `cls.ctor` represented as a PrefixedIdentifier.
          expect(rName, new isInstanceOf<PrefixedIdentifier>(), reason: desc);
          if (rName is PrefixedIdentifier) {
            compareConstAsts(rName.prefix, oName.identifier, desc);
            expect(rName.period.lexeme, '.', reason: desc);
            compareConstAsts(rName.identifier, o.constructorName, desc);
            expect(r.period, isNull, reason: desc);
            expect(r.constructorName, isNull, reason: desc);
          }
        } else {
          compareConstAsts(r.name, o.name, desc);
          expect(r.period?.lexeme, o.period?.lexeme, reason: desc);
          compareConstAsts(r.constructorName, o.constructorName, desc);
        }
        compareConstAstLists(
            r.arguments?.arguments, o.arguments?.arguments, desc);
        Element expectedElement = o.element;
        if (oName is PrefixedIdentifier && o.constructorName != null) {
          // Due to dartbug.com/25706, [o.element] incorrectly points to the
          // class rather than the named constructor.  Hack around this.
          // TODO(paulberry): when dartbug.com/25706 is fixed, remove this.
          expectedElement = (expectedElement as ClassElement)
              .getNamedConstructor(o.constructorName.name);
          expect(expectedElement, isNotNull, reason: desc);
        }
        compareElements(r.element, expectedElement, desc);
        // elementAnnotation should be null; it is only used in the full AST.
        expect(o.elementAnnotation, isNull);
        expect(r.elementAnnotation, isNull);
      } else {
        fail('Not implemented for ${r.runtimeType} vs. ${o.runtimeType}');
      }
    }
  }

  void compareConstructorElements(ConstructorElement resynthesized,
      ConstructorElement original, String desc) {
    if (original == null && resynthesized == null) {
      return;
    }
    compareExecutableElements(resynthesized, original, desc);
    ConstructorElementImpl resynthesizedImpl =
        getActualElement(resynthesized, desc);
    ConstructorElementImpl originalImpl = getActualElement(original, desc);
    if (original.isConst) {
      compareConstAstLists(resynthesizedImpl.constantInitializers,
          originalImpl.constantInitializers, desc);
    }
    if (original.redirectedConstructor == null) {
      expect(resynthesized.redirectedConstructor, isNull, reason: desc);
    } else {
      compareConstructorElements(resynthesized.redirectedConstructor,
          original.redirectedConstructor, '$desc redirectedConstructor');
    }
    checkPossibleMember(resynthesized, original, desc);
    expect(resynthesized.nameEnd, original.nameEnd, reason: desc);
    expect(resynthesized.periodOffset, original.periodOffset, reason: desc);
    expect(resynthesizedImpl.isCycleFree, originalImpl.isCycleFree,
        reason: desc);
  }

  void compareConstValues(
      DartObject resynthesized, DartObject original, String desc) {
    if (original == null) {
      expect(resynthesized, isNull, reason: desc);
    } else {
      expect(resynthesized, isNotNull, reason: desc);
      compareTypes(resynthesized.type, original.type, desc);
      expect(resynthesized.hasKnownValue, original.hasKnownValue, reason: desc);
      if (original.isNull) {
        expect(resynthesized.isNull, isTrue, reason: desc);
      } else if (original.toBoolValue() != null) {
        expect(resynthesized.toBoolValue(), original.toBoolValue(),
            reason: desc);
      } else if (original.toIntValue() != null) {
        expect(resynthesized.toIntValue(), original.toIntValue(), reason: desc);
      } else if (original.toDoubleValue() != null) {
        expect(resynthesized.toDoubleValue(), original.toDoubleValue(),
            reason: desc);
      } else if (original.toListValue() != null) {
        List<DartObject> resynthesizedList = resynthesized.toListValue();
        List<DartObject> originalList = original.toListValue();
        expect(resynthesizedList, hasLength(originalList.length));
        for (int i = 0; i < originalList.length; i++) {
          compareConstValues(resynthesizedList[i], originalList[i], desc);
        }
      } else if (original.toMapValue() != null) {
        Map<DartObject, DartObject> resynthesizedMap =
            resynthesized.toMapValue();
        Map<DartObject, DartObject> originalMap = original.toMapValue();
        expect(resynthesizedMap, hasLength(originalMap.length));
        List<DartObject> resynthesizedKeys = resynthesizedMap.keys.toList();
        List<DartObject> originalKeys = originalMap.keys.toList();
        for (int i = 0; i < originalKeys.length; i++) {
          DartObject resynthesizedKey = resynthesizedKeys[i];
          DartObject originalKey = originalKeys[i];
          compareConstValues(resynthesizedKey, originalKey, desc);
          DartObject resynthesizedValue = resynthesizedMap[resynthesizedKey];
          DartObject originalValue = originalMap[originalKey];
          compareConstValues(resynthesizedValue, originalValue, desc);
        }
      } else if (original.toStringValue() != null) {
        expect(resynthesized.toStringValue(), original.toStringValue(),
            reason: desc);
      } else if (original.toSymbolValue() != null) {
        expect(resynthesized.toSymbolValue(), original.toSymbolValue(),
            reason: desc);
      } else if (original.toTypeValue() != null) {
        fail('Not implemented');
      }
    }
  }

  void compareElementAnnotations(ElementAnnotationImpl resynthesized,
      ElementAnnotationImpl original, String desc) {
    expect(resynthesized.element, isNotNull, reason: desc);
    expect(resynthesized.element.kind, original.element.kind, reason: desc);
    expect(resynthesized.element.location, original.element.location,
        reason: desc);
    expect(resynthesized.compilationUnit, isNotNull, reason: desc);
    expect(resynthesized.compilationUnit.location,
        original.compilationUnit.location,
        reason: desc);
    expect(resynthesized.annotationAst, isNotNull, reason: desc);
    compareConstAsts(resynthesized.annotationAst, original.annotationAst, desc);
  }

  void compareElements(Element resynthesized, Element original, String desc) {
    ElementImpl rImpl = getActualElement(resynthesized, desc);
    ElementImpl oImpl = getActualElement(original, desc);
    if (oImpl == null && rImpl == null) {
      return;
    }
    if (oImpl is PrefixElement) {
      // TODO(scheglov) prefixes cannot be resynthesized
      return;
    }
    expect(original, isNotNull);
    expect(resynthesized, isNotNull, reason: desc);
    if (rImpl is DefaultParameterElementImpl && oImpl is ParameterElementImpl) {
      // This is ok provided the resynthesized parameter element doesn't have
      // any evaluation result.
      expect(rImpl.evaluationResult, isNull);
    } else {
      Type rRuntimeType;
      if (rImpl is ConstFieldElementImpl) {
        rRuntimeType = ConstFieldElementImpl;
      } else if (rImpl is FunctionElementImpl) {
        rRuntimeType = FunctionElementImpl;
      } else {
        rRuntimeType = rImpl.runtimeType;
      }
      expect(rRuntimeType, oImpl.runtimeType);
    }
    expect(resynthesized.kind, original.kind);
    expect(resynthesized.location, original.location, reason: desc);
    expect(resynthesized.name, original.name);
    expect(resynthesized.nameOffset, original.nameOffset, reason: desc);
    expect(rImpl.codeOffset, oImpl.codeOffset, reason: desc);
    expect(rImpl.codeLength, oImpl.codeLength, reason: desc);
    expect(resynthesized.documentationComment, original.documentationComment,
        reason: desc);
    expect(resynthesized.docRange, original.docRange, reason: desc);
    compareMetadata(resynthesized.metadata, original.metadata, desc);

    // Validate modifiers.
    for (Modifier modifier in Modifier.persistedValues) {
      bool got = _hasModifier(resynthesized, modifier);
      bool want = _hasModifier(original, modifier);
      expect(got, want,
          reason: 'Mismatch in $desc.$modifier: got $got, want $want');
    }
    for (Modifier modifier in Modifier.transientValues) {
      bool got = rImpl.hasModifier(modifier);
      bool want = false;
      expect(got, false,
          reason: 'Mismatch in $desc.$modifier: got $got, want $want');
    }

    // Validate members.
    if (oImpl is Member) {
      expect(rImpl, new isInstanceOf<Member>(), reason: desc);
    } else {
      expect(rImpl, isNot(new isInstanceOf<Member>()), reason: desc);
    }
  }

  void compareExecutableElements(
      ExecutableElement resynthesized, ExecutableElement original, String desc,
      {bool shallow: false}) {
    compareElements(resynthesized, original, desc);
    compareParameterElementLists(
        resynthesized.parameters, original.parameters, desc);
    if (checkPropagatedTypes || !original.hasImplicitReturnType) {
      compareTypes(
          resynthesized.returnType, original.returnType, '$desc return type');
    }
    if (!shallow) {
      compareTypes(resynthesized.type, original.type, desc);
    }
    expect(resynthesized.typeParameters.length, original.typeParameters.length);
    for (int i = 0; i < resynthesized.typeParameters.length; i++) {
      compareTypeParameterElements(
          resynthesized.typeParameters[i],
          original.typeParameters[i],
          '$desc type parameter ${original.typeParameters[i].name}');
    }
    compareLocalElementsOfExecutable(resynthesized, original, desc);
  }

  void compareExportElements(ExportElementImpl resynthesized,
      ExportElementImpl original, String desc) {
    compareUriReferencedElements(resynthesized, original, desc);
    expect(resynthesized.exportedLibrary.location,
        original.exportedLibrary.location);
    expect(resynthesized.combinators.length, original.combinators.length);
    for (int i = 0; i < resynthesized.combinators.length; i++) {
      compareNamespaceCombinators(
          resynthesized.combinators[i], original.combinators[i]);
    }
  }

  void compareFieldElements(
      FieldElementImpl resynthesized, FieldElementImpl original, String desc) {
    comparePropertyInducingElements(resynthesized, original, desc);
  }

  void compareFunctionElements(
      FunctionElement resynthesized, FunctionElement original, String desc,
      {bool shallow: false}) {
    if (original == null && resynthesized == null) {
      return;
    }
    expect(resynthesized, isNotNull, reason: desc);
    compareExecutableElements(resynthesized, original, desc, shallow: shallow);
    checkPossibleLocalElements(resynthesized, original);
  }

  void compareFunctionTypeAliasElements(
      FunctionTypeAliasElementImpl resynthesized,
      FunctionTypeAliasElementImpl original,
      String desc) {
    compareElements(resynthesized, original, desc);
    compareParameterElementLists(
        resynthesized.parameters, original.parameters, desc);
    compareTypes(
        resynthesized.returnType, original.returnType, '$desc return type');
    compareTypes(resynthesized.type, original.type, desc);
    expect(resynthesized.typeParameters.length, original.typeParameters.length);
    for (int i = 0; i < resynthesized.typeParameters.length; i++) {
      compareTypeParameterElements(
          resynthesized.typeParameters[i],
          original.typeParameters[i],
          '$desc type parameter ${original.typeParameters[i].name}');
    }
  }

  void compareImportElements(ImportElementImpl resynthesized,
      ImportElementImpl original, String desc) {
    compareUriReferencedElements(resynthesized, original, desc);
    expect(resynthesized.importedLibrary.location,
        original.importedLibrary.location,
        reason: '$desc importedLibrary location');
    expect(resynthesized.prefixOffset, original.prefixOffset,
        reason: '$desc prefixOffset');
    if (original.prefix == null) {
      expect(resynthesized.prefix, isNull, reason: '$desc prefix');
    } else {
      comparePrefixElements(
          resynthesized.prefix, original.prefix, original.prefix.name);
    }
    expect(resynthesized.combinators.length, original.combinators.length,
        reason: '$desc combinators');
    for (int i = 0; i < resynthesized.combinators.length; i++) {
      compareNamespaceCombinators(
          resynthesized.combinators[i], original.combinators[i]);
    }
  }

  void compareLabelElements(
      LabelElementImpl resynthesized, LabelElementImpl original, String desc) {
    expect(resynthesized.isOnSwitchMember, original.isOnSwitchMember,
        reason: desc);
    expect(resynthesized.isOnSwitchStatement, original.isOnSwitchStatement,
        reason: desc);
    compareElements(resynthesized, original, desc);
  }

  void compareLocalElementsOfExecutable(ExecutableElement resynthesized,
      ExecutableElement original, String desc) {
    if (original is! Member) {
      List<FunctionElement> rFunctions = resynthesized.functions;
      List<FunctionElement> oFunctions = original.functions;
      expect(rFunctions, hasLength(oFunctions.length));
      for (int i = 0; i < oFunctions.length; i++) {
        compareFunctionElements(rFunctions[i], oFunctions[i],
            '$desc local function ${oFunctions[i].name}');
      }
    }
    if (original is! Member) {
      List<LabelElement> rLabels = resynthesized.labels;
      List<LabelElement> oLabels = original.labels;
      expect(rLabels, hasLength(oLabels.length));
      for (int i = 0; i < oLabels.length; i++) {
        compareLabelElements(
            rLabels[i], oLabels[i], '$desc label ${oLabels[i].name}');
      }
    }
    if (original is! Member) {
      List<LocalVariableElement> rVariables = resynthesized.localVariables;
      List<LocalVariableElement> oVariables = original.localVariables;
      expect(rVariables, hasLength(oVariables.length));
      for (int i = 0; i < oVariables.length; i++) {
        compareVariableElements(rVariables[i], oVariables[i],
            '$desc local variable ${oVariables[i].name}');
      }
    }
  }

  void compareMetadata(List<ElementAnnotation> resynthesized,
      List<ElementAnnotation> original, String desc) {
    expect(resynthesized, hasLength(original.length), reason: desc);
    for (int i = 0; i < original.length; i++) {
      compareElementAnnotations(
          resynthesized[i], original[i], '$desc annotation $i');
    }
  }

  void compareMethodElements(MethodElementImpl resynthesized,
      MethodElementImpl original, String desc) {
    // TODO(paulberry): do we need to deal with
    // MultiplyInheritedMethodElementImpl?
    compareExecutableElements(resynthesized, original, desc);
  }

  void compareNamespaceCombinators(
      NamespaceCombinator resynthesized, NamespaceCombinator original) {
    if (original is ShowElementCombinatorImpl &&
        resynthesized is ShowElementCombinatorImpl) {
      expect(resynthesized.shownNames, original.shownNames,
          reason: 'shownNames');
      expect(resynthesized.offset, original.offset, reason: 'offset');
      expect(resynthesized.end, original.end, reason: 'end');
    } else if (original is HideElementCombinatorImpl &&
        resynthesized is HideElementCombinatorImpl) {
      expect(resynthesized.hiddenNames, original.hiddenNames,
          reason: 'hiddenNames');
    } else if (resynthesized.runtimeType != original.runtimeType) {
      fail(
          'Type mismatch: expected ${original.runtimeType}, got ${resynthesized.runtimeType}');
    } else {
      fail('Unimplemented comparison for ${original.runtimeType}');
    }
  }

  void compareNamespaces(
      Namespace resynthesized, Namespace original, String desc) {
    Map<String, Element> resynthesizedMap = resynthesized.definedNames;
    Map<String, Element> originalMap = original.definedNames;
    expect(resynthesizedMap.keys.toSet(), originalMap.keys.toSet(),
        reason: desc);
    for (String key in originalMap.keys) {
      Element resynthesizedElement = resynthesizedMap[key];
      Element originalElement = originalMap[key];
      compareElements(resynthesizedElement, originalElement, key);
    }
  }

  void compareParameterElementLists(
      List<ParameterElement> resynthesizedParameters,
      List<ParameterElement> originalParameters,
      String desc) {
    expect(resynthesizedParameters.length, originalParameters.length);
    for (int i = 0; i < resynthesizedParameters.length; i++) {
      compareParameterElements(
          resynthesizedParameters[i],
          originalParameters[i],
          '$desc parameter ${originalParameters[i].name}');
    }
  }

  void compareParameterElements(
      ParameterElement resynthesized, ParameterElement original, String desc) {
    compareVariableElements(resynthesized, original, desc);
    compareParameterElementLists(
        resynthesized.parameters, original.parameters, desc);
    expect(resynthesized.parameterKind, original.parameterKind, reason: desc);
    expect(resynthesized.isInitializingFormal, original.isInitializingFormal,
        reason: desc);
    expect(resynthesized is FieldFormalParameterElementImpl,
        original is FieldFormalParameterElementImpl);
    if (resynthesized is FieldFormalParameterElementImpl &&
        original is FieldFormalParameterElementImpl) {
      if (original.field == null) {
        expect(resynthesized.field, isNull, reason: '$desc field');
      } else {
        expect(resynthesized.field, isNotNull, reason: '$desc field');
        compareFieldElements(
            resynthesized.field, original.field, '$desc field');
      }
    }
    expect(resynthesized.defaultValueCode, original.defaultValueCode,
        reason: desc);
    ParameterElementImpl resynthesizedActual =
        getActualElement(resynthesized, desc);
    ParameterElementImpl originalActual = getActualElement(original, desc);
    compareFunctionElements(
        resynthesizedActual.initializer, originalActual.initializer, desc);
  }

  void comparePrefixElements(PrefixElementImpl resynthesized,
      PrefixElementImpl original, String desc) {
    compareElements(resynthesized, original, desc);
  }

  void comparePropertyAccessorElements(
      PropertyAccessorElementImpl resynthesized,
      PropertyAccessorElementImpl original,
      String desc) {
    // TODO(paulberry): do I need to worry about
    // MultiplyInheritedPropertyAccessorElementImpl?
    compareExecutableElements(resynthesized, original, desc);
    expect(resynthesized.variable, isNotNull);
    expect(resynthesized.variable.location, original.variable.location);
  }

  void comparePropertyInducingElements(
      PropertyInducingElementImpl resynthesized,
      PropertyInducingElementImpl original,
      String desc) {
    compareVariableElements(resynthesized, original, desc);
    if (checkPropagatedTypes) {
      compareTypes(resynthesized.propagatedType, original.propagatedType, desc);
    }
    if (original.getter == null) {
      expect(resynthesized.getter, isNull);
    } else {
      expect(resynthesized.getter, isNotNull);
      expect(resynthesized.getter.location, original.getter.location);
    }
    if (original.setter == null) {
      expect(resynthesized.setter, isNull);
    } else {
      expect(resynthesized.setter, isNotNull);
      expect(resynthesized.setter.location, original.setter.location);
    }
  }

  void compareTopLevelVariableElements(
      TopLevelVariableElementImpl resynthesized,
      TopLevelVariableElementImpl original,
      String desc) {
    comparePropertyInducingElements(resynthesized, original, desc);
  }

  void compareTypeImpls(
      TypeImpl resynthesized, TypeImpl original, String desc) {
    expect(resynthesized.element.location, original.element.location,
        reason: desc);
    expect(resynthesized.name, original.name, reason: desc);
  }

  void compareTypeParameterElements(TypeParameterElementImpl resynthesized,
      TypeParameterElementImpl original, String desc) {
    compareElements(resynthesized, original, desc);
    compareTypes(resynthesized.type, original.type, desc);
    compareTypes(resynthesized.bound, original.bound, '$desc bound');
  }

  void compareTypes(DartType resynthesized, DartType original, String desc) {
    if (original == null) {
      expect(resynthesized, isNull, reason: desc);
    } else if (resynthesized is InterfaceTypeImpl &&
        original is InterfaceTypeImpl) {
      compareTypeImpls(resynthesized, original, desc);
      expect(resynthesized.typeArguments.length, original.typeArguments.length);
      for (int i = 0; i < resynthesized.typeArguments.length; i++) {
        compareTypes(resynthesized.typeArguments[i], original.typeArguments[i],
            '$desc type argument ${original.typeArguments[i].name}');
      }
    } else if (resynthesized is TypeParameterTypeImpl &&
        original is TypeParameterTypeImpl) {
      compareTypeImpls(resynthesized, original, desc);
    } else if (resynthesized is DynamicTypeImpl &&
        original is DynamicTypeImpl) {
      expect(resynthesized, same(original));
    } else if (resynthesized is UndefinedTypeImpl &&
        original is UndefinedTypeImpl) {
      expect(resynthesized, same(original));
    } else if (resynthesized is FunctionTypeImpl &&
        original is FunctionTypeImpl) {
      compareTypeImpls(resynthesized, original, desc);
      expect(resynthesized.isInstantiated, original.isInstantiated,
          reason: desc);
      if (original.element.isSynthetic &&
          original.element is FunctionTypeAliasElementImpl &&
          resynthesized.element is FunctionTypeAliasElementImpl) {
        compareFunctionTypeAliasElements(
            resynthesized.element, original.element, desc);
      }
      if (original.element.enclosingElement == null &&
          original.element is FunctionElement) {
        expect(resynthesized.element, new isInstanceOf<FunctionElement>());
        expect(resynthesized.element.enclosingElement, isNull, reason: desc);
        compareFunctionElements(
            resynthesized.element, original.element, '$desc element',
            shallow: true);
        expect(resynthesized.element.type, same(resynthesized));
      }
      expect(resynthesized.typeArguments.length, original.typeArguments.length,
          reason: '$desc typeArguments.length');
      for (int i = 0; i < resynthesized.typeArguments.length; i++) {
        if (resynthesized.typeArguments[i].isDynamic &&
            original.typeArguments[i] is TypeParameterType) {
          // It's ok for type arguments to get converted to `dynamic` if they
          // are not used.
          expect(
              isTypeParameterUsed(
                  original.typeArguments[i], original.element.type),
              isFalse);
        } else {
          compareTypes(
              resynthesized.typeArguments[i],
              original.typeArguments[i],
              '$desc type argument ${original.typeArguments[i].name}');
        }
      }
      if (original.typeParameters == null) {
        expect(resynthesized.typeParameters, isNull, reason: desc);
      } else {
        expect(resynthesized.typeParameters, isNotNull, reason: desc);
        expect(
            resynthesized.typeParameters.length, original.typeParameters.length,
            reason: desc);
        for (int i = 0; i < resynthesized.typeParameters.length; i++) {
          compareTypeParameterElements(resynthesized.typeParameters[i],
              original.typeParameters[i], '$desc type parameter $i');
        }
      }
      expect(resynthesized.typeFormals.length, original.typeFormals.length,
          reason: desc);
      for (int i = 0; i < resynthesized.typeFormals.length; i++) {
        compareTypeParameterElements(resynthesized.typeFormals[i],
            original.typeFormals[i], '$desc bound type parameter $i');
      }
    } else if (resynthesized is VoidTypeImpl && original is VoidTypeImpl) {
      expect(resynthesized, same(original));
    } else if (resynthesized is DynamicTypeImpl &&
        original is UndefinedTypeImpl) {
      // TODO(scheglov) In the strong mode constant variable like
      //  `var V = new Unresolved()` gets `UndefinedTypeImpl`, and it gets
      // `DynamicTypeImpl` in the spec mode.
    } else if (resynthesized is BottomTypeImpl && original is BottomTypeImpl) {
      expect(resynthesized, same(original));
    } else if (resynthesized.runtimeType != original.runtimeType) {
      fail('Type mismatch: expected ${original.runtimeType},'
          ' got ${resynthesized.runtimeType} ($desc)');
    } else {
      fail('Unimplemented comparison for ${original.runtimeType}');
    }
  }

  void compareUriReferencedElements(UriReferencedElementImpl resynthesized,
      UriReferencedElementImpl original, String desc) {
    compareElements(resynthesized, original, desc);
    expect(resynthesized.uri, original.uri, reason: '$desc uri');
    expect(resynthesized.uriOffset, original.uriOffset,
        reason: '$desc uri uriOffset');
    expect(resynthesized.uriEnd, original.uriEnd, reason: '$desc uriEnd');
  }

  void compareVariableElements(
      VariableElement resynthesized, VariableElement original, String desc) {
    compareElements(resynthesized, original, desc);
    compareTypes(resynthesized.type, original.type, desc);
    VariableElementImpl resynthesizedActual =
        getActualElement(resynthesized, desc);
    VariableElementImpl originalActual = getActualElement(original, desc);
    compareFunctionElements(resynthesizedActual.initializer,
        originalActual.initializer, '$desc initializer');
    if (originalActual is ConstVariableElement) {
      Element oEnclosing = original.enclosingElement;
      if (oEnclosing is ClassElement && oEnclosing.isEnum) {
        compareConstValues(
            resynthesized.constantValue, original.constantValue, desc);
      } else {
        Expression initializer = resynthesizedActual.constantInitializer;
        if (variablesWithNotConstInitializers.contains(resynthesized.name)) {
          _assertUnresolvedIdentifier(initializer, desc);
        } else {
          compareConstAsts(initializer, originalActual.constantInitializer,
              '$desc initializer');
        }
      }
    }
    checkPossibleMember(resynthesized, original, desc);
    checkPossibleLocalElements(resynthesized, original);
  }

  DartSdk createDartSdk() => AbstractContextTest.SHARED_MOCK_SDK;

  /**
   * Determine the analysis options that should be used for this test.
   */
  AnalysisOptionsImpl createOptions() =>
      new AnalysisOptionsImpl()..enableGenericMethods = true;

  /**
   * Serialize the given [library] into a summary.  Then create a
   * [TestSummaryResynthesizer] which can deserialize it, along with any
   * references it makes to `dart:core`.
   *
   * Errors will lead to a test failure unless [allowErrors] is `true`.
   */
  TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library,
      {bool allowErrors: false, bool dumpSummaries: false}) {
    if (!allowErrors) {
      assertNoErrors(library.source);
    }
    addLibrary('dart:core');
    addLibrary('dart:async');
    addLibrary('dart:math');
    return encodeLibraryElement(library, dumpSummaries: dumpSummaries);
  }

  /**
   * Convert the library element [library] into a summary, and then create a
   * [TestSummaryResynthesizer] which can deserialize it.
   *
   * Caller is responsible for checking the library for errors, and adding any
   * dependent libraries using [addLibrary].
   */
  TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library,
      {bool dumpSummaries: false}) {
    Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
    LinkedLibrary getLinkedSummaryFor(LibraryElement lib) {
      LibrarySerializationResult serialized = serializeLibrary(
          lib, context.typeProvider, context.analysisOptions.strongMode);
      for (int i = 0; i < serialized.unlinkedUnits.length; i++) {
        unlinkedSummaries[serialized.unitUris[i]] =
            new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer());
      }
      return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer());
    }
    Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{
      library.source.uri.toString(): getLinkedSummaryFor(library)
    };
    for (Source source in otherLibrarySources) {
      LibraryElement original = context.computeLibraryElement(source);
      String uri = source.uri.toString();
      linkedSummaries[uri] = getLinkedSummaryFor(original);
    }
    if (dumpSummaries) {
      unlinkedSummaries.forEach((String path, UnlinkedUnit unit) {
        print('Unlinked $path: ${JSON.encode(canonicalize(unit))}');
      });
      linkedSummaries.forEach((String path, LinkedLibrary lib) {
        print('Linked $path: ${JSON.encode(canonicalize(lib))}');
      });
    }
    return new TestSummaryResynthesizer(
        null, context, unlinkedSummaries, linkedSummaries);
  }

  ElementImpl getActualElement(Element element, String desc) {
    if (element == null) {
      return null;
    } else if (element is ElementImpl) {
      return element;
    } else if (element is ElementHandle) {
      Element actualElement = element.actualElement;
      // A handle should never point to a member, because if it did, then
      // "is Member" checks on the handle would produce the wrong result.
      expect(actualElement, isNot(new isInstanceOf<Member>()), reason: desc);
      return getActualElement(actualElement, desc);
    } else if (element is Member) {
      return getActualElement(element.baseElement, desc);
    } else {
      fail('Unexpected type for resynthesized ($desc):'
          ' ${element.runtimeType}');
      return null;
    }
  }

  /**
   * Determine if [type] makes use of the given [typeParameter].
   */
  bool isTypeParameterUsed(TypeParameterType typeParameter, DartType type) {
    if (type is FunctionType) {
      return isTypeParameterUsed(typeParameter, type.returnType) ||
          type.parameters.any((ParameterElement e) =>
              isTypeParameterUsed(typeParameter, e.type));
    } else if (type is InterfaceType) {
      return type.typeArguments
          .any((DartType t) => isTypeParameterUsed(typeParameter, t));
    } else if (type is TypeParameterType) {
      return type == typeParameter;
    } else {
      expect(type.isDynamic || type.isVoid, isTrue);
      return false;
    }
  }

  @override
  void setUp() {
    super.setUp();
    prepareAnalysisContext(createOptions());
  }

  void _assertUnresolvedIdentifier(Expression initializer, String desc) {
    expect(initializer, new isInstanceOf<SimpleIdentifier>(), reason: desc);
    SimpleIdentifier identifier = initializer;
    expect(identifier.staticElement, isNull, reason: desc);
  }

  List<PropertyAccessorElement> _getSortedPropertyAccessors(
      ClassElement classElement) {
    List<PropertyAccessorElement> accessors = classElement.accessors.toList();
    accessors.sort((a, b) => a.displayName.compareTo(b.displayName));
    return accessors;
  }

  bool _hasModifier(Element element, Modifier modifier) {
    if (modifier == Modifier.ABSTRACT) {
      if (element is ClassElement) {
        return element.isAbstract;
      }
      if (element is ExecutableElement) {
        return element.isAbstract;
      }
      return false;
    } else if (modifier == Modifier.ASYNCHRONOUS) {
      if (element is ExecutableElement) {
        return element.isAsynchronous;
      }
      return false;
    } else if (modifier == Modifier.CONST) {
      if (element is VariableElement) {
        return element.isConst;
      }
      return false;
    } else if (modifier == Modifier.DEFERRED) {
      if (element is ImportElement) {
        return element.isDeferred;
      }
      return false;
    } else if (modifier == Modifier.ENUM) {
      if (element is ClassElement) {
        return element.isEnum;
      }
      return false;
    } else if (modifier == Modifier.EXTERNAL) {
      if (element is ExecutableElement) {
        return element.isExternal;
      }
      return false;
    } else if (modifier == Modifier.FACTORY) {
      if (element is ConstructorElement) {
        return element.isFactory;
      }
      return false;
    } else if (modifier == Modifier.FINAL) {
      if (element is VariableElement) {
        return element.isFinal;
      }
      return false;
    } else if (modifier == Modifier.GENERATOR) {
      if (element is ExecutableElement) {
        return element.isGenerator;
      }
      return false;
    } else if (modifier == Modifier.GETTER) {
      if (element is PropertyAccessorElement) {
        return element.isGetter;
      }
      return false;
    } else if (modifier == Modifier.HAS_EXT_URI) {
      if (element is LibraryElement) {
        return element.hasExtUri;
      }
      return false;
    } else if (modifier == Modifier.IMPLICIT_TYPE) {
      if (element is ExecutableElement) {
        return element.hasImplicitReturnType;
      }
      return false;
    } else if (modifier == Modifier.MIXIN_APPLICATION) {
      if (element is ClassElement) {
        return element.isMixinApplication;
      }
      return false;
    } else if (modifier == Modifier.REFERENCES_SUPER) {
      if (element is ClassElement) {
        return element.hasReferenceToSuper;
      }
      return false;
    } else if (modifier == Modifier.SETTER) {
      if (element is PropertyAccessorElement) {
        return element.isSetter;
      }
      return false;
    } else if (modifier == Modifier.STATIC) {
      if (element is ExecutableElement) {
        return element.isStatic;
      }
      return false;
    } else if (modifier == Modifier.SYNTHETIC) {
      return element.isSynthetic;
    }
    throw new UnimplementedError(
        'Modifier $modifier for ${element?.runtimeType}');
  }
}

@reflectiveTest
class ResynthesizeElementTest extends ResynthesizeTest {
  @override
  LibraryElementImpl checkLibrary(String text,
      {bool allowErrors: false, bool dumpSummaries: false}) {
    Source source = addTestSource(text);
    LibraryElementImpl original = context.computeLibraryElement(source);
    LibraryElementImpl resynthesized = resynthesizeLibraryElement(
        encodeLibrary(original,
            allowErrors: allowErrors, dumpSummaries: dumpSummaries),
        source.uri.toString(),
        original);
    checkLibraryElements(original, resynthesized);
    return resynthesized;
  }

  @override
  SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource) {
    LibraryElement libraryElement =
        context.computeLibraryElement(librarySource);
    return encodeLibrary(libraryElement);
  }

  /**
   * Serialize the given [library] into a summary.  Then create a
   * [TestSummaryResynthesizer] which can deserialize it, along with any
   * references it makes to `dart:core`.
   *
   * Errors will lead to a test failure unless [allowErrors] is `true`.
   */
  TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library,
      {bool allowErrors: false, bool dumpSummaries: false}) {
    if (!allowErrors) {
      assertNoErrors(library.source);
    }
    addLibrary('dart:core');
    addLibrary('dart:async');
    addLibrary('dart:math');
    return encodeLibraryElement(library, dumpSummaries: dumpSummaries);
  }

  /**
   * Convert the library element [library] into a summary, and then create a
   * [TestSummaryResynthesizer] which can deserialize it.
   *
   * Caller is responsible for checking the library for errors, and adding any
   * dependent libraries using [addLibrary].
   */
  TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library,
      {bool dumpSummaries: false}) {
    Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
    LinkedLibrary getLinkedSummaryFor(LibraryElement lib) {
      LibrarySerializationResult serialized = serializeLibrary(
          lib, context.typeProvider, context.analysisOptions.strongMode);
      for (int i = 0; i < serialized.unlinkedUnits.length; i++) {
        unlinkedSummaries[serialized.unitUris[i]] =
            new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer());
      }
      return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer());
    }
    Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{
      library.source.uri.toString(): getLinkedSummaryFor(library)
    };
    for (Source source in otherLibrarySources) {
      LibraryElement original = context.computeLibraryElement(source);
      String uri = source.uri.toString();
      linkedSummaries[uri] = getLinkedSummaryFor(original);
    }
    if (dumpSummaries) {
      unlinkedSummaries.forEach((String path, UnlinkedUnit unit) {
        print('Unlinked $path: ${JSON.encode(canonicalize(unit))}');
      });
      linkedSummaries.forEach((String path, LinkedLibrary lib) {
        print('Linked $path: ${JSON.encode(canonicalize(lib))}');
      });
    }
    return new TestSummaryResynthesizer(
        null, context, unlinkedSummaries, linkedSummaries);
  }

  /**
   * Resynthesize the library element associated with [uri] using
   * [resynthesizer], and verify that it only had to consult one summary in
   * order to do so.  [original] is consulted merely to verify that no
   * unnecessary resynthesis work was performed.
   */
  LibraryElementImpl resynthesizeLibraryElement(
      TestSummaryResynthesizer resynthesizer,
      String uri,
      LibraryElement original) {
    LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri);
    checkMinimalResynthesisWork(resynthesizer, original);
    return resynthesized;
  }

  test_core() {
    addLibrary('dart:async');
    addLibrary('dart:math');
    String uri = 'dart:core';
    LibraryElementImpl original =
        context.computeLibraryElement(context.sourceFactory.forUri(uri));
    LibraryElementImpl resynthesized = resynthesizeLibraryElement(
        encodeLibraryElement(original), uri, original);
    checkLibraryElements(original, resynthesized);
  }
}

@reflectiveTest
abstract class ResynthesizeTest extends AbstractResynthesizeTest {
  LibraryElementImpl checkLibrary(String text,
      {bool allowErrors: false, bool dumpSummaries: false});

  /**
   * Return a [SummaryResynthesizer] to resynthesize the library with the
   * given [librarySource].
   */
  SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource);

  fail_library_hasExtUri() {
    checkLibrary('import "dart-ext:doesNotExist.dart";');
  }

  test_class_abstract() {
    checkLibrary('abstract class C {}');
  }

  test_class_alias() {
    checkLibrary('class C = D with E, F; class D {} class E {} class F {}');
  }

  test_class_alias_abstract() {
    checkLibrary('abstract class C = D with E; class D {} class E {}');
  }

  test_class_alias_documented() {
    checkLibrary('''
// Extra comment so doc comment offset != 0
/**
 * Docs
 */
class C = D with E;

class D {}
class E {}''');
  }

  test_class_alias_with_forwarding_constructors() {
    addLibrarySource(
        '/a.dart',
        '''
class Base {
  Base._priv();
  Base();
  Base.noArgs();
  Base.requiredArg(x);
  Base.positionalArg([x]);
  Base.namedArg({x});
  factory Base.fact() => null;
  factory Base.fact2() = Base.noArgs;
}
''');
    checkLibrary('''
import "a.dart";
class M {}
class MixinApp = Base with M;
''');
  }

  test_class_alias_with_forwarding_constructors_type_substitution() {
    checkLibrary('''
class Base<T> {
  Base.ctor(T t, List<T> l);
}
class M {}
class MixinApp = Base with M;
''');
  }

  test_class_alias_with_forwarding_constructors_type_substitution_complex() {
    checkLibrary('''
class Base<T> {
  Base.ctor(T t, List<T> l);
}
class M {}
class MixinApp<U> = Base<List<U>> with M;
''');
  }

  test_class_alias_with_mixin_members() {
    checkLibrary('''
class C = D with E;
class D {}
class E {
  int get a => null;
  void set b(int i) {}
  void f() {}
  int x;
}''');
  }

  test_class_constructor_const() {
    checkLibrary('class C { const C(); }');
  }

  test_class_constructor_const_external() {
    checkLibrary('class C { external const C(); }');
  }

  test_class_constructor_explicit_named() {
    checkLibrary('class C { C.foo(); }');
  }

  test_class_constructor_explicit_type_params() {
    checkLibrary('class C<T, U> { C(); }');
  }

  test_class_constructor_explicit_unnamed() {
    checkLibrary('class C { C(); }');
  }

  test_class_constructor_external() {
    checkLibrary('class C { external C(); }');
  }

  test_class_constructor_factory() {
    checkLibrary('class C { factory C() => null; }');
  }

  test_class_constructor_field_formal_dynamic_dynamic() {
    checkLibrary('class C { dynamic x; C(dynamic this.x); }');
  }

  test_class_constructor_field_formal_dynamic_typed() {
    checkLibrary('class C { dynamic x; C(int this.x); }');
  }

  test_class_constructor_field_formal_dynamic_untyped() {
    checkLibrary('class C { dynamic x; C(this.x); }');
  }

  test_class_constructor_field_formal_multiple_matching_fields() {
    // This is a compile-time error but it should still analyze consistently.
    checkLibrary('class C { C(this.x); int x; String x; }', allowErrors: true);
  }

  test_class_constructor_field_formal_no_matching_field() {
    // This is a compile-time error but it should still analyze consistently.
    checkLibrary('class C { C(this.x); }', allowErrors: true);
  }

  test_class_constructor_field_formal_typed_dynamic() {
    checkLibrary('class C { num x; C(dynamic this.x); }', allowErrors: true);
  }

  test_class_constructor_field_formal_typed_typed() {
    checkLibrary('class C { num x; C(int this.x); }');
  }

  test_class_constructor_field_formal_typed_untyped() {
    checkLibrary('class C { num x; C(this.x); }');
  }

  test_class_constructor_field_formal_untyped_dynamic() {
    checkLibrary('class C { var x; C(dynamic this.x); }');
  }

  test_class_constructor_field_formal_untyped_typed() {
    checkLibrary('class C { var x; C(int this.x); }');
  }

  test_class_constructor_field_formal_untyped_untyped() {
    checkLibrary('class C { var x; C(this.x); }');
  }

  test_class_constructor_fieldFormal_named_noDefault() {
    checkLibrary('class C { int x; C({this.x}); }');
  }

  test_class_constructor_fieldFormal_named_withDefault() {
    checkLibrary('class C { int x; C({this.x: 42}); }');
  }

  test_class_constructor_fieldFormal_optional_noDefault() {
    checkLibrary('class C { int x; C([this.x]); }');
  }

  test_class_constructor_fieldFormal_optional_withDefault() {
    checkLibrary('class C { int x; C([this.x = 42]); }');
  }

  test_class_constructor_implicit() {
    checkLibrary('class C {}');
  }

  test_class_constructor_implicit_type_params() {
    checkLibrary('class C<T, U> {}');
  }

  test_class_constructor_params() {
    checkLibrary('class C { C(x, y); }');
  }

  test_class_constructors() {
    checkLibrary('class C { C.foo(); C.bar(); }');
  }

  test_class_documented() {
    checkLibrary('''
// Extra comment so doc comment offset != 0
/**
 * Docs
 */
class C {}''');
  }

  test_class_documented_with_references() {
    checkLibrary('''
/**
 * Docs referring to [D] and [E]
 */
class C {}

class D {}
class E {}''');
  }

  test_class_documented_with_windows_line_endings() {
    checkLibrary('/**\r\n * Docs\r\n */\r\nclass C {}');
  }

  test_class_field_const() {
    checkLibrary('class C { static const int i = 0; }');
  }

  test_class_field_implicit_type() {
    checkLibrary('class C { var x; }');
  }

  test_class_field_static() {
    checkLibrary('class C { static int i; }');
  }

  test_class_fields() {
    checkLibrary('class C { int i; int j; }');
  }

  test_class_getter_abstract() {
    checkLibrary('abstract class C { int get x; }');
  }

  test_class_getter_external() {
    checkLibrary('class C { external int get x; }');
  }

  test_class_getter_implicit_return_type() {
    checkLibrary('class C { get x => null; }');
  }

  test_class_getter_static() {
    checkLibrary('class C { static int get x => null; }');
  }

  test_class_getters() {
    checkLibrary('class C { int get x => null; get y => null; }');
  }

  test_class_implicitField_getterFirst() {
    checkLibrary('class C { int get x => 0; void set x(int value) {} }');
  }

  test_class_implicitField_setterFirst() {
    checkLibrary('class C { void set x(int value) {} int get x => 0; }');
  }

  test_class_interfaces() {
    checkLibrary('class C implements D, E {} class D {} class E {}');
  }

  test_class_method_abstract() {
    checkLibrary('abstract class C { f(); }');
  }

  test_class_method_external() {
    checkLibrary('class C { external f(); }');
  }

  test_class_method_params() {
    checkLibrary('class C { f(x, y) {} }');
  }

  test_class_method_static() {
    checkLibrary('class C { static f() {} }');
  }

  test_class_methods() {
    checkLibrary('class C { f() {} g() {} }');
  }

  test_class_mixins() {
    checkLibrary('class C extends Object with D, E {} class D {} class E {}');
  }

  test_class_setter_abstract() {
    checkLibrary('abstract class C { void set x(int value); }');
  }

  test_class_setter_external() {
    checkLibrary('class C { external void set x(int value); }');
  }

  test_class_setter_implicit_param_type() {
    checkLibrary('class C { void set x(value) {} }');
  }

  test_class_setter_implicit_return_type() {
    checkLibrary('class C { set x(int value) {} }');
  }

  test_class_setter_static() {
    checkLibrary('class C { static void set x(int value) {} }');
  }

  test_class_setters() {
    checkLibrary('class C { void set x(int value) {} set y(value) {} }');
  }

  test_class_supertype() {
    checkLibrary('class C extends D {} class D {}');
  }

  test_class_type_parameters() {
    checkLibrary('class C<T, U> {}');
  }

  test_class_type_parameters_bound() {
    checkLibrary('class C<T extends Object, U extends D> {} class D {}');
  }

  test_class_type_parameters_f_bound_complex() {
    checkLibrary('class C<T extends List<U>, U> {}');
  }

  test_class_type_parameters_f_bound_simple() {
    checkLibrary('class C<T extends U, U> {}');
  }

  test_classes() {
    checkLibrary('class C {} class D {}');
  }

  test_closure_executable_with_return_type_from_closure() {
    checkLibrary('''
f() {
  print(() {});
  print(() => () => 0);
}
''');
  }

  test_const_invalid_field_const() {
    variablesWithNotConstInitializers.add('f');
    checkLibrary(
        r'''
class C {
  static const f = 1 + foo();
}
int foo() => 42;
''',
        allowErrors: true);
  }

  test_const_invalid_field_final() {
    variablesWithNotConstInitializers.add('f');
    checkLibrary(
        r'''
class C {
  final f = 1 + foo();
}
int foo() => 42;
''',
        allowErrors: true);
  }

  test_const_invalid_topLevel() {
    variablesWithNotConstInitializers.add('v');
    checkLibrary(
        r'''
const v = 1 + foo();
int foo() => 42;
''',
        allowErrors: true);
  }

  test_const_invokeConstructor_generic_named() {
    checkLibrary(r'''
class C<K, V> {
  const C.named(K k, V v);
}
const V = const C<int, String>.named(1, '222');
''');
  }

  test_const_invokeConstructor_generic_named_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
class C<K, V> {
  const C.named(K k, V v);
}
''');
    checkLibrary(r'''
import 'a.dart';
const V = const C<int, String>.named(1, '222');
''');
  }

  test_const_invokeConstructor_generic_named_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
class C<K, V> {
  const C.named(K k, V v);
}
''');
    checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C<int, String>.named(1, '222');
''');
  }

  test_const_invokeConstructor_generic_noTypeArguments() {
    checkLibrary(r'''
class C<K, V> {
  const C();
}
const V = const C();
''');
  }

  test_const_invokeConstructor_generic_unnamed() {
    checkLibrary(r'''
class C<K, V> {
  const C();
}
const V = const C<int, String>();
''');
  }

  test_const_invokeConstructor_generic_unnamed_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
class C<K, V> {
  const C();
}
''');
    checkLibrary(r'''
import 'a.dart';
const V = const C<int, String>();
''');
  }

  test_const_invokeConstructor_generic_unnamed_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
class C<K, V> {
  const C();
}
''');
    checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C<int, String>();
''');
  }

  test_const_invokeConstructor_named() {
    checkLibrary(r'''
class C {
  const C.named(bool a, int b, int c, {String d, double e});
}
const V = const C.named(true, 1, 2, d: 'ccc', e: 3.4);
''');
  }

  test_const_invokeConstructor_named_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
  const C.named();
}
''');
    checkLibrary(r'''
import 'a.dart';
const V = const C.named();
''');
  }

  test_const_invokeConstructor_named_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
  const C.named();
}
''');
    checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C.named();
''');
  }

  test_const_invokeConstructor_named_unresolved() {
    checkLibrary(
        r'''
class C {}
const V = const C.named();
''',
        allowErrors: true);
  }

  test_const_invokeConstructor_named_unresolved2() {
    checkLibrary(
        r'''
const V = const C.named();
''',
        allowErrors: true);
  }

  test_const_invokeConstructor_named_unresolved3() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
}
''');
    checkLibrary(
        r'''
import 'a.dart' as p;
const V = const p.C.named();
''',
        allowErrors: true);
  }

  test_const_invokeConstructor_named_unresolved4() {
    addLibrarySource('/a.dart', '');
    checkLibrary(
        r'''
import 'a.dart' as p;
const V = const p.C.named();
''',
        allowErrors: true);
  }

  test_const_invokeConstructor_named_unresolved5() {
    checkLibrary(
        r'''
const V = const p.C.named();
''',
        allowErrors: true);
  }

  test_const_invokeConstructor_unnamed() {
    checkLibrary(r'''
class C {
  const C();
}
const V = const C();
''');
  }

  test_const_invokeConstructor_unnamed_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
  const C();
}
''');
    checkLibrary(r'''
import 'a.dart';
const V = const C();
''');
  }

  test_const_invokeConstructor_unnamed_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
  const C();
}
''');
    checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C();
''');
  }

  test_const_invokeConstructor_unnamed_unresolved() {
    checkLibrary(
        r'''
const V = const C();
''',
        allowErrors: true);
  }

  test_const_invokeConstructor_unnamed_unresolved2() {
    addLibrarySource('/a.dart', '');
    checkLibrary(
        r'''
import 'a.dart' as p;
const V = const p.C();
''',
        allowErrors: true);
  }

  test_const_invokeConstructor_unnamed_unresolved3() {
    checkLibrary(
        r'''
const V = const p.C();
''',
        allowErrors: true);
  }

  test_const_length_ofClassConstField() {
    checkLibrary(r'''
class C {
  static const String F = '';
}
const int v = C.F.length;
''');
  }

  test_const_length_ofClassConstField_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
  static const String F = '';
}
''');
    checkLibrary(r'''
import 'a.dart';
const int v = C.F.length;
''');
  }

  test_const_length_ofClassConstField_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
  static const String F = '';
}
''');
    checkLibrary(r'''
import 'a.dart' as p;
const int v = p.C.F.length;
''');
  }

  test_const_length_ofStringLiteral() {
    checkLibrary(r'''
const v = 'abc'.length;
''');
  }

  test_const_length_ofTopLevelVariable() {
    checkLibrary(r'''
const String S = 'abc';
const v = S.length;
''');
  }

  test_const_length_ofTopLevelVariable_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
const String S = 'abc';
''');
    checkLibrary(r'''
import 'a.dart';
const v = S.length;
''');
  }

  test_const_length_ofTopLevelVariable_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
const String S = 'abc';
''');
    checkLibrary(r'''
import 'a.dart' as p;
const v = p.S.length;
''');
  }

  test_const_length_staticMethod() {
    checkLibrary(r'''
class C {
  static int length() => 42;
}
const v = C.length;
''');
  }

  test_const_parameterDefaultValue_initializingFormal_functionTyped() {
    checkLibrary(r'''
class C {
  final x;
  const C({this.x: foo});
}
int foo() => 42;
''');
  }

  test_const_parameterDefaultValue_initializingFormal_named() {
    checkLibrary(r'''
class C {
  final x;
  const C({this.x: 1 + 2});
}
''');
  }

  test_const_parameterDefaultValue_initializingFormal_positional() {
    checkLibrary(r'''
class C {
  final x;
  const C([this.x = 1 + 2]);
}
''');
  }

  test_const_parameterDefaultValue_normal() {
    checkLibrary(r'''
class C {
  const C.positional([p = 1 + 2]);
  const C.named({p: 1 + 2});
  void methodPositional([p = 1 + 2]) {}
  void methodPositionalWithoutDefault([p]) {}
  void methodNamed({p: 1 + 2}) {}
  void methodNamedWithoutDefault({p}) {}
}
''');
  }

  test_const_reference_staticField() {
    checkLibrary(r'''
class C {
  static const int F = 42;
}
const V = C.F;
''');
  }

  test_const_reference_staticField_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
  static const int F = 42;
}
''');
    checkLibrary(r'''
import 'a.dart';
const V = C.F;
''');
  }

  test_const_reference_staticField_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
  static const int F = 42;
}
''');
    checkLibrary(r'''
import 'a.dart' as p;
const V = p.C.F;
''');
  }

  test_const_reference_staticMethod() {
    checkLibrary(r'''
class C {
  static int m(int a, String b) => 42;
}
const V = C.m;
''');
  }

  test_const_reference_staticMethod_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
  static int m(int a, String b) => 42;
}
''');
    checkLibrary(r'''
import 'a.dart';
const V = C.m;
''');
  }

  test_const_reference_staticMethod_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {
  static int m(int a, String b) => 42;
}
''');
    checkLibrary(r'''
import 'a.dart' as p;
const V = p.C.m;
''');
  }

  test_const_reference_topLevelFunction() {
    checkLibrary(r'''
foo() {}
const V = foo;
''');
  }

  test_const_reference_topLevelFunction_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
foo() {}
''');
    checkLibrary(r'''
import 'a.dart';
const V = foo;
''');
  }

  test_const_reference_topLevelFunction_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
foo() {}
''');
    checkLibrary(r'''
import 'a.dart' as p;
const V = p.foo;
''');
  }

  test_const_reference_topLevelVariable() {
    checkLibrary(r'''
const A = 1;
const B = A + 2;
''');
  }

  test_const_reference_topLevelVariable_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
const A = 1;
''');
    checkLibrary(r'''
import 'a.dart';
const B = A + 2;
''');
  }

  test_const_reference_topLevelVariable_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
const A = 1;
''');
    checkLibrary(r'''
import 'a.dart' as p;
const B = p.A + 2;
''');
  }

  test_const_reference_type() {
    checkLibrary(r'''
class C {}
class D<T> {}
enum E {a, b, c}
typedef F(int a, String b);
const vDynamic = dynamic;
const vNull = Null;
const vObject = Object;
const vClass = C;
const vGenericClass = D;
const vEnum = E;
const vFunctionTypeAlias = F;
''');
  }

  test_const_reference_type_functionType() {
    checkLibrary(r'''
typedef F();
class C {
  final f = <F>[];
}
''');
  }

  test_const_reference_type_imported() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {}
enum E {a, b, c}
typedef F(int a, String b);
''');
    checkLibrary(r'''
import 'a.dart';
const vClass = C;
const vEnum = E;
const vFunctionTypeAlias = F;
''');
  }

  test_const_reference_type_imported_withPrefix() {
    addLibrarySource(
        '/a.dart',
        r'''
class C {}
enum E {a, b, c}
typedef F(int a, String b);
''');
    checkLibrary(r'''
import 'a.dart' as p;
const vClass = p.C;
const vEnum = p.E;
const vFunctionTypeAlias = p.F;
''');
  }

  test_const_reference_type_typeParameter() {
    checkLibrary(r'''
class C<T> {
  final f = <T>[];
}
''');
  }

  test_const_reference_unresolved_prefix0() {
    checkLibrary(
        r'''
const V = foo;
''',
        allowErrors: true);
  }

  test_const_reference_unresolved_prefix1() {
    checkLibrary(
        r'''
class C {}
const v = C.foo;
''',
        allowErrors: true);
  }

  test_const_reference_unresolved_prefix2() {
    addLibrarySource(
        '/foo.dart',
        '''
class C {}
''');
    checkLibrary(
        r'''
import 'foo.dart' as p;
const v = p.C.foo;
''',
        allowErrors: true);
  }

  test_const_topLevel_binary() {
    checkLibrary(r'''
const vEqual = 1 == 2;
const vAnd = true && false;
const vOr = false || true;
const vBitXor = 1 ^ 2;
const vBitAnd = 1 & 2;
const vBitOr = 1 | 2;
const vBitShiftLeft = 1 << 2;
const vBitShiftRight = 1 >> 2;
const vAdd = 1 + 2;
const vSubtract = 1 - 2;
const vMiltiply = 1 * 2;
const vDivide = 1 / 2;
const vFloorDivide = 1 ~/ 2;
const vModulo = 1 % 2;
const vGreater = 1 > 2;
const vGreaterEqual = 1 >= 2;
const vLess = 1 < 2;
const vLessEqual = 1 <= 2;
''');
  }

  test_const_topLevel_conditional() {
    checkLibrary(r'''
const vConditional = (1 == 2) ? 11 : 22;
''');
  }

  test_const_topLevel_identical() {
    checkLibrary(r'''
const vIdentical = (1 == 2) ? 11 : 22;
''');
  }

  test_const_topLevel_literal() {
    checkLibrary(r'''
const vNull = null;
const vBoolFalse = false;
const vBoolTrue = true;
const vInt = 1;
const vIntLong = 0x9876543210987654321;
const vDouble = 2.3;
const vString = 'abc';
const vStringConcat = 'aaa' 'bbb';
const vStringInterpolation = 'aaa ${true} ${42} bbb';
const vSymbol = #aaa.bbb.ccc;
''');
  }

  test_const_topLevel_prefix() {
    checkLibrary(r'''
const vNotEqual = 1 != 2;
const vNot = !true;
const vNegate = -1;
const vComplement = ~1;
''');
  }

  test_const_topLevel_typedList() {
    checkLibrary(r'''
const vNull = const <Null>[];
const vDynamic = const <dynamic>[1, 2, 3];
const vInterfaceNoTypeParameters = const <int>[1, 2, 3];
const vInterfaceNoTypeArguments = const <List>[];
const vInterfaceWithTypeArguments = const <List<String>>[];
const vInterfaceWithTypeArguments2 = const <Map<int, List<String>>>[];
''');
  }

  test_const_topLevel_typedList_imported() {
    addLibrarySource('/a.dart', 'class C {}');
    checkLibrary(r'''
import 'a.dart';
const v = const <C>[];
''');
  }

  test_const_topLevel_typedList_importedWithPrefix() {
    addLibrarySource('/a.dart', 'class C {}');
    checkLibrary(r'''
import 'a.dart' as p;
const v = const <p.C>[];
''');
  }

  test_const_topLevel_typedMap() {
    checkLibrary(r'''
const vDynamic1 = const <dynamic, int>{};
const vDynamic2 = const <int, dynamic>{};
const vInterface = const <int, String>{};
const vInterfaceWithTypeArguments = const <int, List<String>>{};
''');
  }

  test_const_topLevel_untypedList() {
    checkLibrary(r'''
const v = const [1, 2, 3];
''');
  }

  test_const_topLevel_untypedMap() {
    checkLibrary(r'''
const v = const {0: 'aaa', 1: 'bbb', 2: 'ccc'};
''');
  }

  test_constExpr_pushReference_field_simpleIdentifier() {
    checkLibrary('''
class C {
  static const a = b;
  static const b = null;
}
''');
  }

  test_constExpr_pushReference_staticMethod_simpleIdentifier() {
    checkLibrary('''
class C {
  static const a = m;
  static m() {}
}
''');
  }

  test_constructor_documented() {
    checkLibrary('''
class C {
  /**
   * Docs
   */
  C();
}''');
  }

  test_constructor_initializers_field() {
    checkLibrary('''
class C {
  final x;
  const C() : x = 42;
}
''');
  }

  test_constructor_initializers_field_notConst() {
    variablesWithNotConstInitializers.add('x');
    checkLibrary(
        '''
class C {
  final x;
  const A() : x = foo();
}
int foo() => 42;
''',
        allowErrors: true);
  }

  test_constructor_initializers_field_withParameter() {
    checkLibrary('''
class C {
  final x;
  const C(int p) : x = 1 + p;
}
''');
  }

  test_constructor_initializers_superInvocation_named() {
    checkLibrary('''
class A {
  const A.aaa(int p);
}
class C extends A {
  const C() : super.aaa(42);
}
''');
  }

  test_constructor_initializers_superInvocation_namedExpression() {
    checkLibrary('''
class A {
  const A.aaa(a, {int b});
}
class C extends A {
  const C() : super.aaa(1, b: 2);
}
''');
  }

  test_constructor_initializers_superInvocation_unnamed() {
    checkLibrary('''
class A {
  const A(int p);
}
class C extends A {
  const C.ccc() : super(42);
}
''');
  }

  test_constructor_initializers_thisInvocation_named() {
    checkLibrary('''
class C {
  const C() : this.named(1, 'bbb');
  const C.named(int a, String b);
}
''');
  }

  test_constructor_initializers_thisInvocation_namedExpression() {
    checkLibrary('''
class C {
  const C() : this.named(1, b: 2);
  const C.named(a, {int b});
}
''');
  }

  test_constructor_initializers_thisInvocation_unnamed() {
    checkLibrary('''
class C {
  const C.named() : this(1, 'bbb');
  const C(int a, String b);
}
''');
  }

  test_constructor_redirected_factory_named() {
    checkLibrary('''
class C {
  factory C() = D.named;
  C._();
}
class D extends C {
  D.named() : super._();
}
''');
  }

  test_constructor_redirected_factory_named_generic() {
    checkLibrary('''
class C<T, U> {
  factory C() = D<U, T>.named;
  C._();
}
class D<T, U> extends C<U, T> {
  D.named() : super._();
}
''');
  }

  test_constructor_redirected_factory_named_imported() {
    addLibrarySource(
        '/foo.dart',
        '''
import 'test.dart';
class D extends C {
  D.named() : super._();
}
''');
    checkLibrary('''
import 'foo.dart';
class C {
  factory C() = D.named;
  C._();
}
''');
  }

  test_constructor_redirected_factory_named_imported_generic() {
    addLibrarySource(
        '/foo.dart',
        '''
import 'test.dart';
class D<T, U> extends C<U, T> {
  D.named() : super._();
}
''');
    checkLibrary('''
import 'foo.dart';
class C<T, U> {
  factory C() = D<U, T>.named;
  C._();
}
''');
  }

  test_constructor_redirected_factory_named_prefixed() {
    addLibrarySource(
        '/foo.dart',
        '''
import 'test.dart';
class D extends C {
  D.named() : super._();
}
''');
    checkLibrary('''
import 'foo.dart' as foo;
class C {
  factory C() = foo.D.named;
  C._();
}
''');
  }

  test_constructor_redirected_factory_named_prefixed_generic() {
    addLibrarySource(
        '/foo.dart',
        '''
import 'test.dart';
class D<T, U> extends C<U, T> {
  D.named() : super._();
}
''');
    checkLibrary('''
import 'foo.dart' as foo;
class C<T, U> {
  factory C() = foo.D<U, T>.named;
  C._();
}
''');
  }

  test_constructor_redirected_factory_unnamed() {
    checkLibrary('''
class C {
  factory C() = D;
  C._();
}
class D extends C {
  D() : super._();
}
''');
  }

  test_constructor_redirected_factory_unnamed_generic() {
    checkLibrary('''
class C<T, U> {
  factory C() = D<U, T>;
  C._();
}
class D<T, U> extends C<U, T> {
  D() : super._();
}
''');
  }

  test_constructor_redirected_factory_unnamed_imported() {
    addLibrarySource(
        '/foo.dart',
        '''
import 'test.dart';
class D extends C {
  D() : super._();
}
''');
    checkLibrary('''
import 'foo.dart';
class C {
  factory C() = D;
  C._();
}
''');
  }

  test_constructor_redirected_factory_unnamed_imported_generic() {
    addLibrarySource(
        '/foo.dart',
        '''
import 'test.dart';
class D<T, U> extends C<U, T> {
  D() : super._();
}
''');
    checkLibrary('''
import 'foo.dart';
class C<T, U> {
  factory C() = D<U, T>;
  C._();
}
''');
  }

  test_constructor_redirected_factory_unnamed_prefixed() {
    addLibrarySource(
        '/foo.dart',
        '''
import 'test.dart';
class D extends C {
  D() : super._();
}
''');
    checkLibrary('''
import 'foo.dart' as foo;
class C {
  factory C() = foo.D;
  C._();
}
''');
  }

  test_constructor_redirected_factory_unnamed_prefixed_generic() {
    addLibrarySource(
        '/foo.dart',
        '''
import 'test.dart';
class D<T, U> extends C<U, T> {
  D() : super._();
}
''');
    checkLibrary('''
import 'foo.dart' as foo;
class C<T, U> {
  factory C() = foo.D<U, T>;
  C._();
}
''');
  }

  test_constructor_redirected_thisInvocation_named() {
    checkLibrary('''
class C {
  C.named();
  C() : this.named();
}
''');
  }

  test_constructor_redirected_thisInvocation_named_generic() {
    checkLibrary('''
class C<T> {
  C.named();
  C() : this.named();
}
''');
  }

  test_constructor_redirected_thisInvocation_unnamed() {
    checkLibrary('''
class C {
  C();
  C.named() : this();
}
''');
  }

  test_constructor_redirected_thisInvocation_unnamed_generic() {
    checkLibrary('''
class C<T> {
  C();
  C.named() : this();
}
''');
  }

  test_constructor_withCycles_const() {
    checkLibrary('''
class C {
  final x;
  const C() : x = const D();
}
class D {
  final x;
  const D() : x = const C();
}
''');
  }

  test_constructor_withCycles_nonConst() {
    checkLibrary('''
class C {
  final x;
  C() : x = new D();
}
class D {
  final x;
  D() : x = new C();
}
''');
  }

  test_defaultValue_refersToGenericClass_constructor() {
    checkLibrary('''
class B<T> {
  const B();
}
class C<T> {
  const C([B<T> b = const B()]);
}
''');
  }

  test_defaultValue_refersToGenericClass_constructor2() {
    checkLibrary('''
abstract class A<T> {}
class B<T> implements A<T> {
  const B();
}
class C<T> implements A<Iterable<T>> {
  const C([A<T> a = const B()]);
}
''');
  }

  test_defaultValue_refersToGenericClass_functionG() {
    checkLibrary('''
class B<T> {
  const B();
}
void foo<T>([B<T> b = const B()]) {}
''');
  }

  test_defaultValue_refersToGenericClass_methodG() {
    checkLibrary('''
class B<T> {
  const B();
}
class C {
  void foo<T>([B<T> b = const B()]) {}
}
''');
  }

  test_defaultValue_refersToGenericClass_methodG_classG() {
    checkLibrary('''
class B<T1, T2> {
  const B();
}
class C<E1> {
  void foo<E2>([B<E1, E2> b = const B()]) {}
}
''');
  }

  test_defaultValue_refersToGenericClass_methodNG() {
    checkLibrary('''
class B<T> {
  const B();
}
class C<T> {
  void foo([B<T> b = const B()]) {}
}
''');
  }

  test_enum_documented() {
    checkLibrary('''
// Extra comment so doc comment offset != 0
/**
 * Docs
 */
enum E { v }''');
  }

  test_enum_value_documented() {
    checkLibrary('''
enum E {
  /**
   * Docs
   */
  v
}''');
  }

  test_enum_values() {
    checkLibrary('enum E { v1, v2 }');
  }

  test_enums() {
    checkLibrary('enum E1 { v1 } enum E2 { v2 }');
  }

  test_executable_parameter_type_typedef() {
    checkLibrary(r'''
typedef F(int p);
main(F f) {}
''');
  }

  test_export_class() {
    addLibrarySource('/a.dart', 'class C {}');
    checkLibrary('export "a.dart";');
  }

  test_export_class_type_alias() {
    addLibrarySource(
        '/a.dart', 'class C {} exends _D with _E; class _D {} class _E {}');
    checkLibrary('export "a.dart";');
  }

  test_export_function() {
    addLibrarySource('/a.dart', 'f() {}');
    checkLibrary('export "a.dart";');
  }

  test_export_getter() {
    addLibrarySource('/a.dart', 'get f() => null;');
    checkLibrary('export "a.dart";');
  }

  test_export_hide() {
    addLibrary('dart:async');
    checkLibrary('export "dart:async" hide Stream, Future;');
  }

  test_export_multiple_combinators() {
    addLibrary('dart:async');
    checkLibrary('export "dart:async" hide Stream show Future;');
  }

  test_export_setter() {
    addLibrarySource('/a.dart', 'void set f(value) {}');
    checkLibrary('export "a.dart";');
  }

  test_export_show() {
    addLibrary('dart:async');
    checkLibrary('export "dart:async" show Future, Stream;');
  }

  test_export_typedef() {
    addLibrarySource('/a.dart', 'typedef F();');
    checkLibrary('export "a.dart";');
  }

  test_export_variable() {
    addLibrarySource('/a.dart', 'var x;');
    checkLibrary('export "a.dart";');
  }

  test_export_variable_const() {
    addLibrarySource('/a.dart', 'const x = 0;');
    checkLibrary('export "a.dart";');
  }

  test_export_variable_final() {
    addLibrarySource('/a.dart', 'final x = 0;');
    checkLibrary('export "a.dart";');
  }

  test_exports() {
    addLibrarySource('/a.dart', 'library a;');
    addLibrarySource('/b.dart', 'library b;');
    checkLibrary('export "a.dart"; export "b.dart";');
  }

  test_field_documented() {
    checkLibrary('''
class C {
  /**
   * Docs
   */
  var x;
}''');
  }

  test_field_formal_param_inferred_type_implicit() {
    checkLibrary('class C extends D { var v; C(this.v); }'
        ' abstract class D { int get v; }');
  }

  test_field_inferred_type_nonStatic_explicit_initialized() {
    checkLibrary('class C { num v = 0; }');
  }

  test_field_inferred_type_nonStatic_implicit_initialized() {
    checkLibrary('class C { var v = 0; }');
  }

  test_field_inferred_type_nonStatic_implicit_uninitialized() {
    checkLibrary(
        'class C extends D { var v; } abstract class D { int get v; }');
  }

  test_field_inferred_type_static_implicit_initialized() {
    checkLibrary('class C { static var v = 0; }');
  }

  test_field_propagatedType_const_noDep() {
    checkLibrary('''
class C {
  static const x = 0;
}''');
  }

  test_field_propagatedType_final_dep_inLib() {
    addLibrarySource('/a.dart', 'final a = 1;');
    checkLibrary('''
import "a.dart";
class C {
  final b = a / 2;
}''');
  }

  test_field_propagatedType_final_dep_inPart() {
    addSource('/a.dart', 'part of lib; final a = 1;');
    checkLibrary('''
library lib;
part "a.dart";
class C {
  final b = a / 2;
}''');
  }

  test_field_propagatedType_final_noDep_instance() {
    checkLibrary('''
class C {
  final x = 0;
}''');
  }

  test_field_propagatedType_final_noDep_static() {
    checkLibrary('''
class C {
  static final x = 0;
}''');
  }

  test_field_static_final_untyped() {
    checkLibrary('class C { static final x = 0; }');
  }

  test_field_untyped() {
    checkLibrary('class C { var x = 0; }');
  }

  test_function_async() {
    checkLibrary(r'''
import 'dart:async';
Future f() async {}
''');
  }

  test_function_asyncStar() {
    checkLibrary(r'''
import 'dart:async';
Stream f() async* {}
''');
  }

  test_function_documented() {
    checkLibrary('''
// Extra comment so doc comment offset != 0
/**
 * Docs
 */
f() {}''');
  }

  test_function_entry_point() {
    checkLibrary('main() {}');
  }

  test_function_entry_point_in_export() {
    addLibrarySource('/a.dart', 'library a; main() {}');
    checkLibrary('export "a.dart";');
  }

  test_function_entry_point_in_export_hidden() {
    addLibrarySource('/a.dart', 'library a; main() {}');
    checkLibrary('export "a.dart" hide main;');
  }

  test_function_entry_point_in_part() {
    addSource('/a.dart', 'part of my.lib; main() {}');
    checkLibrary('library my.lib; part "a.dart";');
  }

  test_function_external() {
    checkLibrary('external f();');
  }

  test_function_parameter_kind_named() {
    checkLibrary('f({x}) {}');
  }

  test_function_parameter_kind_positional() {
    checkLibrary('f([x]) {}');
  }

  test_function_parameter_kind_required() {
    checkLibrary('f(x) {}');
  }

  test_function_parameter_parameters() {
    checkLibrary('f(g(x, y)) {}');
  }

  test_function_parameter_return_type() {
    checkLibrary('f(int g()) {}');
  }

  test_function_parameter_return_type_void() {
    checkLibrary('f(void g()) {}');
  }

  test_function_parameter_type() {
    checkLibrary('f(int i) {}');
  }

  test_function_parameters() {
    checkLibrary('f(x, y) {}');
  }

  test_function_return_type() {
    checkLibrary('int f() => null;');
  }

  test_function_return_type_implicit() {
    checkLibrary('f() => null;');
  }

  test_function_return_type_void() {
    checkLibrary('void f() {}');
  }

  test_function_type_parameter() {
    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
    checkLibrary('T f<T, U>(U u) => null;');
  }

  test_function_type_parameter_with_function_typed_parameter() {
    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
    checkLibrary('void f<T, U>(T x(U u)) {}');
  }

  test_functions() {
    checkLibrary('f() {} g() {}');
  }

  test_generic_gClass_gMethodStatic() {
    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
    checkLibrary('''
class C<T, U> {
  static void m<V, W>(V v, W w) {
    void f<X, Y>(V v, W w, X x, Y y) {
    }
  }
}
''');
  }

  test_getElement_constructor_named() {
    String text = 'class C { C.named(); }';
    Source source = addLibrarySource('/test.dart', text);
    ConstructorElement original = context
        .computeLibraryElement(source)
        .getType('C')
        .getNamedConstructor('named');
    expect(original, isNotNull);
    ConstructorElement resynthesized = validateGetElement(text, original);
    compareConstructorElements(resynthesized, original, 'C.constructor named');
  }

  test_getElement_constructor_unnamed() {
    String text = 'class C { C(); }';
    Source source = addLibrarySource('/test.dart', text);
    ConstructorElement original =
        context.computeLibraryElement(source).getType('C').unnamedConstructor;
    expect(original, isNotNull);
    ConstructorElement resynthesized = validateGetElement(text, original);
    compareConstructorElements(resynthesized, original, 'C.constructor');
  }

  test_getElement_field() {
    String text = 'class C { var f; }';
    Source source = addLibrarySource('/test.dart', text);
    FieldElement original =
        context.computeLibraryElement(source).getType('C').getField('f');
    expect(original, isNotNull);
    FieldElement resynthesized = validateGetElement(text, original);
    compareFieldElements(resynthesized, original, 'C.field f');
  }

  test_getElement_getter() {
    String text = 'class C { get f => null; }';
    Source source = addLibrarySource('/test.dart', text);
    PropertyAccessorElement original =
        context.computeLibraryElement(source).getType('C').getGetter('f');
    expect(original, isNotNull);
    PropertyAccessorElement resynthesized = validateGetElement(text, original);
    comparePropertyAccessorElements(resynthesized, original, 'C.getter f');
  }

  test_getElement_method() {
    String text = 'class C { f() {} }';
    Source source = addLibrarySource('/test.dart', text);
    MethodElement original =
        context.computeLibraryElement(source).getType('C').getMethod('f');
    expect(original, isNotNull);
    MethodElement resynthesized = validateGetElement(text, original);
    compareMethodElements(resynthesized, original, 'C.method f');
  }

  test_getElement_operator() {
    String text = 'class C { operator+(x) => null; }';
    Source source = addLibrarySource('/test.dart', text);
    MethodElement original =
        context.computeLibraryElement(source).getType('C').getMethod('+');
    expect(original, isNotNull);
    MethodElement resynthesized = validateGetElement(text, original);
    compareMethodElements(resynthesized, original, 'C.operator+');
  }

  test_getElement_setter() {
    String text = 'class C { void set f(value) {} }';
    Source source = addLibrarySource('/test.dart', text);
    PropertyAccessorElement original =
        context.computeLibraryElement(source).getType('C').getSetter('f');
    expect(original, isNotNull);
    PropertyAccessorElement resynthesized = validateGetElement(text, original);
    comparePropertyAccessorElements(resynthesized, original, 'C.setter f');
  }

  test_getElement_unit() {
    String text = 'class C { f() {} }';
    Source source = addLibrarySource('/test.dart', text);
    CompilationUnitElement original =
        context.computeLibraryElement(source).definingCompilationUnit;
    expect(original, isNotNull);
    CompilationUnitElement resynthesized = validateGetElement(text, original);
    compareCompilationUnitElements(resynthesized, original);
  }

  test_getter_documented() {
    checkLibrary('''
// Extra comment so doc comment offset != 0
/**
 * Docs
 */
get x => null;''');
  }

  test_getter_external() {
    checkLibrary('external int get x;');
  }

  test_getter_inferred_type_nonStatic_implicit_return() {
    checkLibrary(
        'class C extends D { get f => null; } abstract class D { int get f; }');
  }

  test_getters() {
    checkLibrary('int get x => null; get y => null;');
  }

  test_implicitTopLevelVariable_getterFirst() {
    checkLibrary('int get x => 0; void set x(int value) {}');
  }

  test_implicitTopLevelVariable_setterFirst() {
    checkLibrary('void set x(int value) {} int get x => 0;');
  }

  test_import_deferred() {
    addLibrarySource('/a.dart', 'f() {}');
    checkLibrary('import "a.dart" deferred as p; main() { p.f(); }');
  }

  test_import_hide() {
    addLibrary('dart:async');
    checkLibrary('import "dart:async" hide Stream, Completer; Future f;');
  }

  test_import_multiple_combinators() {
    addLibrary('dart:async');
    checkLibrary('import "dart:async" hide Stream show Future; Future f;');
  }

  test_import_prefixed() {
    addLibrarySource('/a.dart', 'library a; class C {}');
    checkLibrary('import "a.dart" as a; a.C c;');
  }

  test_import_self() {
    LibraryElementImpl resynthesized = checkLibrary('''
import 'test.dart' as p;
class C {}
class D extends p.C {} // Prevent "unused import" warning
''');
    expect(resynthesized.imports, hasLength(2));
    expect(resynthesized.imports[0].importedLibrary.location,
        resynthesized.location);
    expect(resynthesized.imports[1].importedLibrary.isDartCore, true);
  }

  test_import_show() {
    addLibrary('dart:async');
    checkLibrary('''
import "dart:async" show Future, Stream;
Future f;
Stream s;
''');
  }

  test_imports() {
    addLibrarySource('/a.dart', 'library a; class C {}');
    addLibrarySource('/b.dart', 'library b; class D {}');
    checkLibrary('import "a.dart"; import "b.dart"; C c; D d;');
  }

  test_inferred_function_type_for_variable_in_generic_function() {
    // In the code below, `x` has an inferred type of `() => int`, with 2
    // (unused) type parameters from the enclosing top level function.
    checkLibrary('''
f<U, V>() {
  var x = () => 0;
}
''');
  }

  test_inferred_function_type_in_generic_class_constructor() {
    // In the code below, `() => () => 0` has an inferred return type of
    // `() => int`, with 2 (unused) type parameters from the enclosing class.
    checkLibrary('''
class C<U, V> {
  final x;
  C() : x = (() => () => 0);
}
''');
  }

  test_inferred_function_type_in_generic_class_getter() {
    // In the code below, `() => () => 0` has an inferred return type of
    // `() => int`, with 2 (unused) type parameters from the enclosing class.
    checkLibrary('''
class C<U, V> {
  get x => () => () => 0;
}
''');
  }

  test_inferred_function_type_in_generic_class_in_generic_method() {
    // In the code below, `() => () => 0` has an inferred return type of
    // `() => int`, with 3 (unused) type parameters from the enclosing class
    // and method.
    checkLibrary('''
class C<T> {
  f<U, V>() {
    print(() => () => 0);
  }
}
''');
  }

  test_inferred_function_type_in_generic_class_setter() {
    // In the code below, `() => () => 0` has an inferred return type of
    // `() => int`, with 2 (unused) type parameters from the enclosing class.
    checkLibrary('''
class C<U, V> {
  void set x(value) {
    print(() => () => 0);
  }
}
''');
  }

  test_inferred_function_type_in_generic_closure() {
    if (!createOptions().strongMode) {
      // The test below uses generic comment syntax because proper generic
      // method syntax doesn't support generic closures.  So it can only run in
      // strong mode.
      // TODO(paulberry): once proper generic method syntax supports generic
      // closures, rewrite the test below without using generic comment syntax,
      // and remove this hack.  See dartbug.com/25819
      return;
    }
    // In the code below, `<U, V>() => () => 0` has an inferred return type of
    // `() => int`, with 3 (unused) type parameters.
    checkLibrary('''
f<T>() {
  print(/*<U, V>*/() => () => 0);
}
''');
  }

  test_inferred_generic_function_type_in_generic_closure() {
    if (!createOptions().strongMode) {
      // The test below uses generic comment syntax because proper generic
      // method syntax doesn't support generic closures.  So it can only run in
      // strong mode.
      // TODO(paulberry): once proper generic method syntax supports generic
      // closures, rewrite the test below without using generic comment syntax,
      // and remove this hack.  See dartbug.com/25819
      return;
    }
    // In the code below, `<U, V>() => <W, X, Y, Z>() => 0` has an inferred
    // return type of `() => int`, with 7 (unused) type parameters.
    checkLibrary('''
f<T>() {
  print(/*<U, V>*/() => /*<W, X, Y, Z>*/() => 0);
}
''');
  }

  test_inferred_type_is_typedef() {
    checkLibrary('typedef int F(String s);'
        ' class C extends D { var v; }'
        ' abstract class D { F get v; }');
  }

  test_inferred_type_refers_to_bound_type_param() {
    checkLibrary('class C<T> extends D<int, T> { var v; }'
        ' abstract class D<U, V> { Map<V, U> get v; }');
  }

  void test_inferred_type_refers_to_function_typed_param_of_typedef() {
    checkLibrary('''
typedef void F(int g(String s));
h(F f) => null;
var v = h(/*info:INFERRED_TYPE_CLOSURE*/(y) {});
''');
  }

  test_inferred_type_refers_to_function_typed_parameter_type_generic_class() {
    checkLibrary('class C<T, U> extends D<U, int> { void f(int x, g) {} }'
        ' abstract class D<V, W> { void f(int x, W g(V s)); }');
  }

  test_inferred_type_refers_to_function_typed_parameter_type_other_lib() {
    addLibrarySource(
        '/a.dart', 'import "b.dart"; abstract class D extends E {}');
    addLibrarySource(
        '/b.dart', 'abstract class E { void f(int x, int g(String s)); }');
    checkLibrary('import "a.dart"; class C extends D { void f(int x, g) {} }');
  }

  test_inferred_type_refers_to_method_function_typed_parameter_type() {
    checkLibrary('class C extends D { void f(int x, g) {} }'
        ' abstract class D { void f(int x, int g(String s)); }');
  }

  test_inferred_type_refers_to_nested_function_typed_param() {
    checkLibrary('''
f(void g(int x, void h())) => null;
var v = f((x, y) {});
''');
  }

  test_inferred_type_refers_to_nested_function_typed_param_named() {
    checkLibrary('''
f({void g(int x, void h())}) => null;
var v = f(g: (x, y) {});
''');
  }

  test_inferred_type_refers_to_setter_function_typed_parameter_type() {
    checkLibrary('class C extends D { void set f(g) {} }'
        ' abstract class D { void set f(int g(String s)); }');
  }

  void test_inferredType_usesSyntheticFunctionType_functionTypedParam() {
    checkLibrary('''
int f(int x(String y)) => null;
String g(int x(String y)) => null;
var v = [f, g];
''');
  }

  test_initializer_executable_with_return_type_from_closure() {
    checkLibrary('var v = () => 0;');
  }

  test_initializer_executable_with_return_type_from_closure_field() {
    checkLibrary('''
class C {
  var v = () => 0;
}
''');
  }

  test_initializer_executable_with_return_type_from_closure_local() {
    checkLibrary('''
void f() {
  int u = 0;
  var v = () => 0;
}
''');
  }

  test_library() {
    checkLibrary('');
  }

  test_library_documented() {
    checkLibrary('''
// Extra comment so doc comment offset != 0
/**
 * Docs
 */
library foo;''');
  }

  test_library_name_with_spaces() {
    checkLibrary('library foo . bar ;');
  }

  test_library_named() {
    checkLibrary('library foo.bar;');
  }

  test_localFunctions() {
    checkLibrary(r'''
f() {
  f1() {}
  {
    f2() {}
  }
}
''');
  }

  test_localFunctions_inConstructor() {
    checkLibrary(r'''
class C {
  C() {
    f() {}
  }
}
''');
  }

  test_localFunctions_inMethod() {
    checkLibrary(r'''
class C {
  m() {
    f() {}
  }
}
''');
  }

  test_localFunctions_inTopLevelGetter() {
    checkLibrary(r'''
get g {
  f() {}
}
''');
  }

  test_localLabels_inConstructor() {
    checkLibrary(
        r'''
class C {
  C() {
    aaa: while (true) {}
    bbb: switch (42) {
      ccc: case 0:
        break;
    }
  }
}
''',
        allowErrors: true);
  }

  test_localLabels_inMethod() {
    checkLibrary(
        r'''
class C {
  m() {
    aaa: while (true) {}
    bbb: switch (42) {
      ccc: case 0:
        break;
    }
  }
}
''',
        allowErrors: true);
  }

  test_localLabels_inTopLevelFunction() {
    checkLibrary(
        r'''
main() {
  aaa: while (true) {}
  bbb: switch (42) {
    ccc: case 0:
      break;
  }
}
''',
        allowErrors: true);
  }

  test_localVariables_inConstructor() {
    checkLibrary(r'''
class C {
  C() {
    int v;
    f() {}
  }
}
''');
  }

  test_localVariables_inLocalFunction() {
    checkLibrary(r'''
f() {
  f1() {
    int v1 = 1;
  } // 2
  f2() {
    int v1 = 1;
    f3() {
      int v2 = 1;
    }
  }
}
''');
  }

  test_localVariables_inMethod() {
    checkLibrary(r'''
class C {
  m() {
    int v;
  }
}
''');
  }

  test_localVariables_inTopLevelFunction() {
    checkLibrary(r'''
main() {
  int v1 = 1;
  {
    const String v2 = 'bbb';
  }
  Map<int, List<double>> v3;
}
''');
  }

  test_localVariables_inTopLevelGetter() {
    checkLibrary(r'''
get g {
  int v;
}
''');
  }

  test_main_class() {
    checkLibrary('class main {}');
  }

  test_main_class_alias() {
    checkLibrary('class main = C with D; class C {} class D {}');
  }

  test_main_class_alias_via_export() {
    addLibrarySource('/a.dart', 'class main = C with D; class C {} class D {}');
    checkLibrary('export "a.dart";');
  }

  test_main_class_via_export() {
    addLibrarySource('/a.dart', 'class main {}');
    checkLibrary('export "a.dart";');
  }

  test_main_getter() {
    checkLibrary('get main => null;');
  }

  test_main_getter_via_export() {
    addLibrarySource('/a.dart', 'get main => null;');
    checkLibrary('export "a.dart";');
  }

  test_main_typedef() {
    checkLibrary('typedef main();');
  }

  test_main_typedef_via_export() {
    addLibrarySource('/a.dart', 'typedef main();');
    checkLibrary('export "a.dart";');
  }

  test_main_variable() {
    checkLibrary('var main;');
  }

  test_main_variable_via_export() {
    addLibrarySource('/a.dart', 'var main;');
    checkLibrary('export "a.dart";');
  }

  test_member_function_async() {
    checkLibrary(r'''
import 'dart:async';
class C {
  Future f() async {}
}
''');
  }

  test_member_function_asyncStar() {
    checkLibrary(r'''
import 'dart:async';
class C {
  Stream f() async* {}
}
''');
  }

  test_metadata_classDeclaration() {
    checkLibrary('const a = null; @a class C {}');
  }

  test_metadata_classTypeAlias() {
    checkLibrary(
        'const a = null; @a class C = D with E; class D {} class E {}');
  }

  test_metadata_constructor_call_named() {
    checkLibrary('class A { const A.named(); } @A.named() class C {}');
  }

  test_metadata_constructor_call_named_prefixed() {
    addLibrarySource('/foo.dart', 'class A { const A.named(); }');
    checkLibrary('import "foo.dart" as foo; @foo.A.named() class C {}');
  }

  test_metadata_constructor_call_unnamed() {
    checkLibrary('class A { const A(); } @A() class C {}');
  }

  test_metadata_constructor_call_unnamed_prefixed() {
    addLibrarySource('/foo.dart', 'class A { const A(); }');
    checkLibrary('import "foo.dart" as foo; @foo.A() class C {}');
  }

  test_metadata_constructor_call_with_args() {
    checkLibrary('class A { const A(x); } @A(null) class C {}');
  }

  test_metadata_constructorDeclaration_named() {
    checkLibrary('const a = null; class C { @a C.named(); }');
  }

  test_metadata_constructorDeclaration_unnamed() {
    checkLibrary('const a = null; class C { @a C(); }');
  }

  test_metadata_enumDeclaration() {
    checkLibrary('const a = null; @a enum E { v }');
  }

  test_metadata_exportDirective() {
    addLibrarySource('/foo.dart', '');
    checkLibrary('@a export "foo.dart"; const a = null;');
  }

  test_metadata_fieldDeclaration() {
    checkLibrary('const a = null; class C { @a int x; }');
  }

  test_metadata_fieldFormalParameter() {
    checkLibrary('const a = null; class C { var x; C(@a this.x); }');
  }

  test_metadata_fieldFormalParameter_withDefault() {
    checkLibrary('const a = null; class C { var x; C([@a this.x = null]); }');
  }

  test_metadata_functionDeclaration_function() {
    checkLibrary('const a = null; @a f() {}');
  }

  test_metadata_functionDeclaration_getter() {
    checkLibrary('const a = null; @a get f => null;');
  }

  test_metadata_functionDeclaration_setter() {
    checkLibrary('const a = null; @a set f(value) {}');
  }

  test_metadata_functionTypeAlias() {
    checkLibrary('const a = null; @a typedef F();');
  }

  test_metadata_functionTypedFormalParameter() {
    checkLibrary('const a = null; f(@a g()) {}');
  }

  test_metadata_functionTypedFormalParameter_withDefault() {
    checkLibrary('const a = null; f([@a g() = null]) {}');
  }

  test_metadata_importDirective() {
    addLibrarySource('/foo.dart', 'const b = null;');
    checkLibrary('@a import "foo.dart"; const a = b;');
  }

  test_metadata_libraryDirective() {
    checkLibrary('@a library L; const a = null;');
  }

  test_metadata_methodDeclaration_getter() {
    checkLibrary('const a = null; class C { @a get m => null; }');
  }

  test_metadata_methodDeclaration_method() {
    checkLibrary('const a = null; class C { @a m() {} }');
  }

  test_metadata_methodDeclaration_setter() {
    checkLibrary('const a = null; class C { @a set m(value) {} }');
  }

  test_metadata_partDirective() {
    addSource('/foo.dart', 'part of L;');
    checkLibrary('library L; @a part "foo.dart"; const a = null;');
  }

  test_metadata_prefixed_variable() {
    addLibrarySource('/a.dart', 'const b = null;');
    checkLibrary('import "a.dart" as a; @a.b class C {}');
  }

  test_metadata_simpleFormalParameter() {
    checkLibrary('const a = null; f(@a x) {}');
  }

  test_metadata_simpleFormalParameter_withDefault() {
    checkLibrary('const a = null; f([@a x = null]) {}');
  }

  test_metadata_topLevelVariableDeclaration() {
    checkLibrary('const a = null; @a int v;');
  }

  test_metadata_typeParameter_ofClass() {
    checkLibrary('const a = null; class C<@a T> {}');
  }

  test_metadata_typeParameter_ofClassTypeAlias() {
    checkLibrary(
        'const a = null; class C<@a T> = D with E; class D {} class E {}');
  }

  test_metadata_typeParameter_ofFunction() {
    checkLibrary('const a = null; f<@a T>() {}');
  }

  test_metadata_typeParameter_ofTypedef() {
    checkLibrary('const a = null; typedef F<@a T>();');
  }

  test_method_documented() {
    checkLibrary('''
class C {
  /**
   * Docs
   */
  f() {}
}''');
  }

  test_method_inferred_type_nonStatic_implicit_param() {
    checkLibrary('class C extends D { void f(value) {} }'
        ' abstract class D { void f(int value); }');
  }

  test_method_inferred_type_nonStatic_implicit_return() {
    checkLibrary(
        'class C extends D { f() => null; } abstract class D { int f(); }');
  }

  test_method_parameter_parameters() {
    checkLibrary('class C { f(g(x, y)) {} }');
  }

  test_method_parameter_parameters_in_generic_class() {
    checkLibrary('class C<A, B> { f(A g(B x)) {} }');
  }

  test_method_parameter_return_type() {
    checkLibrary('class C { f(int g()) {} }');
  }

  test_method_parameter_return_type_void() {
    checkLibrary('class C { f(void g()) {} }');
  }

  test_method_type_parameter() {
    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
    checkLibrary('class C { T f<T, U>(U u) => null; }');
  }

  test_method_type_parameter_in_generic_class() {
    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
    checkLibrary('class C<T, U> { V f<V, W>(T t, U u, W w) => null; }');
  }

  test_method_type_parameter_with_function_typed_parameter() {
    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
    checkLibrary('class C { void f<T, U>(T x(U u)) {} }');
  }

  test_nested_generic_functions_in_generic_class_with_function_typed_params() {
    checkLibrary('''
class C<T, U> {
  void g<V, W>() {
    void h<X, Y>(void p(T t, U u, V v, W w, X x, Y y)) {
    }
  }
}
''');
  }

  test_nested_generic_functions_in_generic_class_with_local_variables() {
    checkLibrary('''
class C<T, U> {
  void g<V, W>() {
    void h<X, Y>() {
      T t;
      U u;
      V v;
      W w;
      X x;
      Y y;
    }
  }
}
''');
  }

  test_nested_generic_functions_with_function_typed_param() {
    checkLibrary('''
void f<T, U>() {
  void g<V, W>() {
    void h<X, Y>(void p(T t, U u, V v, W w, X x, Y y)) {
    }
  }
}
''');
  }

  test_nested_generic_functions_with_local_variables() {
    checkLibrary('''
void f<T, U>() {
  void g<V, W>() {
    void h<X, Y>() {
      T t;
      U u;
      V v;
      W w;
      X x;
      Y y;
    }
  }
}
''');
  }

  test_operator() {
    checkLibrary('class C { C operator+(C other) => null; }');
  }

  test_operator_equal() {
    checkLibrary('class C { bool operator==(Object other) => false; }');
  }

  test_operator_external() {
    checkLibrary('class C { external C operator+(C other); }');
  }

  test_operator_greater_equal() {
    checkLibrary('class C { bool operator>=(C other) => false; }');
  }

  test_operator_index() {
    checkLibrary('class C { bool operator[](int i) => null; }');
  }

  test_operator_index_set() {
    checkLibrary('class C { void operator[]=(int i, bool v) {} }');
  }

  test_operator_less_equal() {
    checkLibrary('class C { bool operator<=(C other) => false; }');
  }

  test_parameterTypeNotInferred_constructor() {
    // Strong mode doesn't do type inference on constructor parameters, so it's
    // ok that we don't store inferred type info for them in summaries.
    checkLibrary('''
class C {
  C.positional([x = 1]);
  C.named({x: 1});
}
''');
  }

  test_parameterTypeNotInferred_initializingFormal() {
    // Strong mode doesn't do type inference on initializing formals, so it's
    // ok that we don't store inferred type info for them in summaries.
    checkLibrary('''
class C {
  var x;
  C.positional([this.x = 1]);
  C.named({this.x: 1});
}
''');
  }

  test_parameterTypeNotInferred_staticMethod() {
    // Strong mode doesn't do type inference on parameters of static methods,
    // so it's ok that we don't store inferred type info for them in summaries.
    checkLibrary('''
class C {
  static void positional([x = 1]) {}
  static void named({x: 1}) {}
}
''');
  }

  test_parameterTypeNotInferred_topLevelFunction() {
    // Strong mode doesn't do type inference on parameters of top level
    // functions, so it's ok that we don't store inferred type info for them in
    // summaries.
    checkLibrary('''
void positional([x = 1]) {}
void named({x: 1}) {}
''');
  }

  test_parts() {
    addSource('/a.dart', 'part of my.lib;');
    addSource('/b.dart', 'part of my.lib;');
    checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
  }

  test_propagated_type_refers_to_closure() {
    checkLibrary('''
void f() {
  var x = () => 0;
  var y = x;
}
''');
  }

  test_setter_documented() {
    checkLibrary('''
// Extra comment so doc comment offset != 0
/**
 * Docs
 */
void set x(value) {}''');
  }

  test_setter_external() {
    checkLibrary('external void set x(int value);');
  }

  test_setter_inferred_type_nonStatic_implicit_param() {
    checkLibrary('class C extends D { void set f(value) {} }'
        ' abstract class D { void set f(int value); }');
  }

  test_setter_inferred_type_static_implicit_return() {
    checkLibrary('class C { static set f(int value) {} }');
  }

  test_setter_inferred_type_top_level_implicit_return() {
    checkLibrary('set f(int value) {}');
  }

  test_setters() {
    checkLibrary('void set x(int value) {} set y(value) {}');
  }

  test_syntheticFunctionType_genericClosure() {
    if (!createOptions().strongMode) {
      // The test below uses generic comment syntax because proper generic
      // method syntax doesn't support generic closures.  So it can only run in
      // strong mode.
      // TODO(paulberry): once proper generic method syntax supports generic
      // closures, rewrite the test below without using generic comment syntax,
      // and remove this hack.  See dartbug.com/25819
      return;
    }
    checkLibrary('''
final v = f() ? /*<T>*/(T t) => 0 : /*<T>*/(T t) => 1;
bool f() => true;
''');
  }

  test_syntheticFunctionType_genericClosure_inGenericFunction() {
    if (!createOptions().strongMode) {
      // The test below uses generic comment syntax because proper generic
      // method syntax doesn't support generic closures.  So it can only run in
      // strong mode.
      // TODO(paulberry): once proper generic method syntax supports generic
      // closures, rewrite the test below without using generic comment syntax,
      // and remove this hack.  See dartbug.com/25819
      return;
    }
    checkLibrary('''
void f<T, U>(bool b) {
  final v = b ? /*<V>*/(T t, U u, V v) => 0 : /*<V>*/(T t, U u, V v) => 1;
}
''');
  }

  test_syntheticFunctionType_inGenericClass() {
    checkLibrary('''
class C<T, U> {
  var v = f() ? (T t, U u) => 0 : (T t, U u) => 1;
}
bool f() => false;
''');
  }

  test_syntheticFunctionType_inGenericFunction() {
    checkLibrary('''
void f<T, U>(bool b) {
  var v = b ? (T t, U u) => 0 : (T t, U u) => 1;
}
''');
  }

  test_syntheticFunctionType_noArguments() {
    checkLibrary('''
final v = f() ? () => 0 : () => 1;
bool f() => true;
''');
  }

  test_syntheticFunctionType_withArguments() {
    checkLibrary('''
final v = f() ? (int x, String y) => 0 : (int x, String y) => 1;
bool f() => true;
''');
  }

  test_type_arguments_explicit_dynamic_dynamic() {
    checkLibrary('Map<dynamic, dynamic> m;');
  }

  test_type_arguments_explicit_dynamic_int() {
    checkLibrary('Map<dynamic, int> m;');
  }

  test_type_arguments_explicit_String_dynamic() {
    checkLibrary('Map<String, dynamic> m;');
  }

  test_type_arguments_explicit_String_int() {
    checkLibrary('Map<String, int> m;');
  }

  test_type_arguments_implicit() {
    checkLibrary('Map m;');
  }

  test_type_dynamic() {
    checkLibrary('dynamic d;');
  }

  test_type_reference_lib_to_lib() {
    checkLibrary('class C {} enum E { v } typedef F(); C c; E e; F f;');
  }

  test_type_reference_lib_to_part() {
    addSource('/a.dart', 'part of l; class C {} enum E { v } typedef F();');
    checkLibrary('library l; part "a.dart"; C c; E e; F f;');
  }

  test_type_reference_part_to_lib() {
    addSource('/a.dart', 'part of l; C c; E e; F f;');
    checkLibrary(
        'library l; part "a.dart"; class C {} enum E { v } typedef F();');
  }

  test_type_reference_part_to_other_part() {
    addSource('/a.dart', 'part of l; class C {} enum E { v } typedef F();');
    addSource('/b.dart', 'part of l; C c; E e; F f;');
    checkLibrary('library l; part "a.dart"; part "b.dart";');
  }

  test_type_reference_part_to_part() {
    addSource('/a.dart',
        'part of l; class C {} enum E { v } typedef F(); C c; E e; F f;');
    checkLibrary('library l; part "a.dart";');
  }

  test_type_reference_to_class() {
    checkLibrary('class C {} C c;');
  }

  test_type_reference_to_class_with_type_arguments() {
    checkLibrary('class C<T, U> {} C<int, String> c;');
  }

  test_type_reference_to_class_with_type_arguments_implicit() {
    checkLibrary('class C<T, U> {} C c;');
  }

  test_type_reference_to_enum() {
    checkLibrary('enum E { v } E e;');
  }

  test_type_reference_to_import() {
    addLibrarySource('/a.dart', 'class C {} enum E { v }; typedef F();');
    checkLibrary('import "a.dart"; C c; E e; F f;');
  }

  test_type_reference_to_import_export() {
    addLibrarySource('/a.dart', 'export "b.dart";');
    addLibrarySource('/b.dart', 'class C {} enum E { v } typedef F();');
    checkLibrary('import "a.dart"; C c; E e; F f;');
  }

  test_type_reference_to_import_export_export() {
    addLibrarySource('/a.dart', 'export "b.dart";');
    addLibrarySource('/b.dart', 'export "c.dart";');
    addLibrarySource('/c.dart', 'class C {} enum E { v } typedef F();');
    checkLibrary('import "a.dart"; C c; E e; F f;');
  }

  test_type_reference_to_import_export_export_in_subdirs() {
    addLibrarySource('/a/a.dart', 'export "b/b.dart";');
    addLibrarySource('/a/b/b.dart', 'export "../c/c.dart";');
    addLibrarySource('/a/c/c.dart', 'class C {} enum E { v } typedef F();');
    checkLibrary('import "a/a.dart"; C c; E e; F f;');
  }

  test_type_reference_to_import_export_in_subdirs() {
    addLibrarySource('/a/a.dart', 'export "b/b.dart";');
    addLibrarySource('/a/b/b.dart', 'class C {} enum E { v } typedef F();');
    checkLibrary('import "a/a.dart"; C c; E e; F f;');
  }

  test_type_reference_to_import_part() {
    addLibrarySource('/a.dart', 'library l; part "b.dart";');
    addSource('/b.dart', 'part of l; class C {} enum E { v } typedef F();');
    checkLibrary('import "a.dart"; C c; E e; F f;');
  }

  test_type_reference_to_import_part2() {
    addLibrarySource('/a.dart', 'library l; part "p1.dart"; part "p2.dart";');
    addSource('/p1.dart', 'part of l; class C1 {}');
    addSource('/p2.dart', 'part of l; class C2 {}');
    checkLibrary('import "a.dart"; C1 c1; C2 c2;');
  }

  test_type_reference_to_import_part_in_subdir() {
    addLibrarySource('/a/b.dart', 'library l; part "c.dart";');
    addSource('/a/c.dart', 'part of l; class C {} enum E { v } typedef F();');
    checkLibrary('import "a/b.dart"; C c; E e; F f;');
  }

  test_type_reference_to_import_relative() {
    addLibrarySource('/a.dart', 'class C {} enum E { v } typedef F();');
    checkLibrary('import "a.dart"; C c; E e; F f;');
  }

  test_type_reference_to_typedef() {
    checkLibrary('typedef F(); F f;');
  }

  test_type_reference_to_typedef_with_type_arguments() {
    checkLibrary('typedef U F<T, U>(T t); F<int, String> f;');
  }

  test_type_reference_to_typedef_with_type_arguments_implicit() {
    checkLibrary('typedef U F<T, U>(T t); F f;');
  }

  test_type_unresolved() {
    checkLibrary('C c;', allowErrors: true);
  }

  test_type_unresolved_prefixed() {
    checkLibrary('import "dart:core" as core; core.C c;', allowErrors: true);
  }

  test_typedef_documented() {
    checkLibrary('''
// Extra comment so doc comment offset != 0
/**
 * Docs
 */
typedef F();''');
  }

  test_typedef_parameter_parameters() {
    checkLibrary('typedef F(g(x, y));');
  }

  test_typedef_parameter_parameters_in_generic_class() {
    checkLibrary('typedef F<A, B>(A g(B x));');
  }

  test_typedef_parameter_return_type() {
    checkLibrary('typedef F(int g());');
  }

  test_typedef_parameter_type() {
    checkLibrary('typedef F(int i);');
  }

  test_typedef_parameter_type_generic() {
    checkLibrary('typedef F<T>(T t);');
  }

  test_typedef_parameters() {
    checkLibrary('typedef F(x, y);');
  }

  test_typedef_return_type() {
    checkLibrary('typedef int F();');
  }

  test_typedef_return_type_generic() {
    checkLibrary('typedef T F<T>();');
  }

  test_typedef_return_type_implicit() {
    checkLibrary('typedef F();');
  }

  test_typedef_return_type_void() {
    checkLibrary('typedef void F();');
  }

  test_typedef_type_parameters() {
    checkLibrary('typedef U F<T, U>(T t);');
  }

  test_typedef_type_parameters_bound() {
    checkLibrary('typedef U F<T extends Object, U extends D>(T t); class D {}');
  }

  test_typedef_type_parameters_f_bound_complex() {
    checkLibrary('typedef U F<T extends List<U>, U>(T t);');
  }

  test_typedef_type_parameters_f_bound_simple() {
    checkLibrary('typedef U F<T extends U, U>(T t);');
  }

  test_typedefs() {
    checkLibrary('f() {} g() {}');
  }

  test_unused_type_parameter() {
    checkLibrary('''
class C<T> {
  void f() {}
}
C<int> c;
var v = c.f;
''');
  }

  test_variable_const() {
    checkLibrary('const int i = 0;');
  }

  test_variable_documented() {
    checkLibrary('''
// Extra comment so doc comment offset != 0
/**
 * Docs
 */
var x;''');
  }

  test_variable_final() {
    checkLibrary('final int x = 0;');
  }

  test_variable_final_top_level_untyped() {
    checkLibrary('final v = 0;');
  }

  test_variable_getterInLib_setterInPart() {
    addSource('/a.dart', 'part of my.lib; void set x(int _) {}');
    checkLibrary('library my.lib; part "a.dart"; int get x => 42;');
  }

  test_variable_getterInPart_setterInLib() {
    addSource('/a.dart', 'part of my.lib; int get x => 42;');
    checkLibrary('library my.lib; part "a.dart"; void set x(int _) {}');
  }

  test_variable_getterInPart_setterInPart() {
    addSource('/a.dart', 'part of my.lib; int get x => 42;');
    addSource('/b.dart', 'part of my.lib; void set x(int _) {}');
    checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
  }

  test_variable_implicit_type() {
    checkLibrary('var x;');
  }

  test_variable_inferred_type_implicit_initialized() {
    checkLibrary('var v = 0;');
  }

  test_variable_propagatedType_const_noDep() {
    checkLibrary('const i = 0;');
  }

  test_variable_propagatedType_final_dep_inLib() {
    addLibrarySource('/a.dart', 'final a = 1;');
    checkLibrary('import "a.dart"; final b = a / 2;');
  }

  test_variable_propagatedType_final_dep_inPart() {
    addSource('/a.dart', 'part of lib; final a = 1;');
    checkLibrary('library lib; part "a.dart"; final b = a / 2;');
  }

  test_variable_propagatedType_final_noDep() {
    checkLibrary('final i = 0;');
  }

  test_variable_propagatedType_implicit_dep() {
    // The propagated type is defined in a library that is not imported.
    addLibrarySource('/a.dart', 'class C {}');
    addLibrarySource('/b.dart', 'import "a.dart"; C f() => null;');
    checkLibrary('import "b.dart"; final x = f();');
  }

  test_variable_setterInPart_getterInPart() {
    addSource('/a.dart', 'part of my.lib; void set x(int _) {}');
    addSource('/b.dart', 'part of my.lib; int get x => 42;');
    checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
  }

  test_variables() {
    checkLibrary('int i; int j;');
  }

  /**
   * Encode the library containing [original] into a summary and then use
   * [TestSummaryResynthesizer.getElement] to retrieve just the original
   * element from the resynthesized summary.
   */
  Element validateGetElement(String text, Element original) {
    SummaryResynthesizer resynthesizer =
        encodeDecodeLibrarySource(original.library.source);
    ElementLocationImpl location = original.location;
    Element result = resynthesizer.getElement(location);
    checkMinimalResynthesisWork(resynthesizer, original.library);
    // Check that no other summaries needed to be resynthesized to resynthesize
    // the library element.
    expect(resynthesizer.resynthesisCount, 1);
    expect(result.location, location);
    return result;
  }
}

class TestSummaryResynthesizer extends SummaryResynthesizer {
  final Map<String, UnlinkedUnit> unlinkedSummaries;
  final Map<String, LinkedLibrary> linkedSummaries;

  /**
   * The set of uris for which unlinked summaries have been requested using
   * [getUnlinkedSummary].
   */
  final Set<String> unlinkedSummariesRequested = new Set<String>();

  /**
   * The set of uris for which linked summaries have been requested using
   * [getLinkedSummary].
   */
  final Set<String> linkedSummariesRequested = new Set<String>();

  TestSummaryResynthesizer(SummaryResynthesizer parent, AnalysisContext context,
      this.unlinkedSummaries, this.linkedSummaries)
      : super(parent, context, context.typeProvider, context.sourceFactory,
            context.analysisOptions.strongMode);

  @override
  LinkedLibrary getLinkedSummary(String uri) {
    linkedSummariesRequested.add(uri);
    LinkedLibrary serializedLibrary = linkedSummaries[uri];
    if (serializedLibrary == null) {
      fail('Unexpectedly tried to get linked summary for $uri');
    }
    return serializedLibrary;
  }

  @override
  UnlinkedUnit getUnlinkedSummary(String uri) {
    unlinkedSummariesRequested.add(uri);
    UnlinkedUnit serializedUnit = unlinkedSummaries[uri];
    if (serializedUnit == null) {
      fail('Unexpectedly tried to get unlinked summary for $uri');
    }
    return serializedUnit;
  }

  @override
  bool hasLibrarySummary(String uri) {
    return true;
  }
}
