// 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 analyzer.test.src.task.dart_test;

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart'
    show AnalysisOptions, AnalysisOptionsImpl, CacheState;
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/src/task/strong/ast_properties.dart' as strong_ast;
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
import 'package:unittest/unittest.dart';

import '../../generated/resolver_test_case.dart';
import '../../generated/test_support.dart';
import '../../reflective_tests.dart';
import '../../utils.dart';
import '../context/abstract_context.dart';
import '../context/mock_sdk.dart';

main() {
  initializeTestEnvironment();
  runReflectiveTests(BuildCompilationUnitElementTaskTest);
  runReflectiveTests(BuildDirectiveElementsTaskTest);
  runReflectiveTests(BuildEnumMemberElementsTaskTest);
  runReflectiveTests(BuildExportNamespaceTaskTest);
  runReflectiveTests(BuildLibraryElementTaskTest);
  runReflectiveTests(BuildPublicNamespaceTaskTest);
  runReflectiveTests(BuildSourceExportClosureTaskTest);
  runReflectiveTests(BuildTypeProviderTaskTest);
  runReflectiveTests(BuildTypeProviderTaskTest_noAsync);
  runReflectiveTests(ComputeConstantDependenciesTaskTest);
  runReflectiveTests(ComputeConstantValueTaskTest);
  runReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest);
  runReflectiveTests(ComputeLibraryCycleTaskTest);
  runReflectiveTests(ComputePropagableVariableDependenciesTaskTest);
  runReflectiveTests(ContainingLibrariesTaskTest);
  runReflectiveTests(DartErrorsTaskTest);
  runReflectiveTests(EvaluateUnitConstantsTaskTest);
  runReflectiveTests(GatherUsedImportedElementsTaskTest);
  runReflectiveTests(GatherUsedLocalElementsTaskTest);
  runReflectiveTests(GenerateHintsTaskTest);
  runReflectiveTests(GenerateLintsTaskTest);
  runReflectiveTests(InferInstanceMembersInUnitTaskTest);
  runReflectiveTests(InferStaticVariableTypesInUnitTaskTest);
  runReflectiveTests(InferStaticVariableTypeTaskTest);
  runReflectiveTests(LibraryErrorsReadyTaskTest);
  runReflectiveTests(LibraryUnitErrorsTaskTest);
  runReflectiveTests(ParseDartTaskTest);
  runReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
  runReflectiveTests(PropagateVariableTypesInUnitTaskTest);
  runReflectiveTests(PropagateVariableTypeTaskTest);
  runReflectiveTests(ResolveDirectiveElementsTaskTest);
  runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
  runReflectiveTests(ResolveLibraryReferencesTaskTest);
  runReflectiveTests(ResolveLibraryTaskTest);
  runReflectiveTests(ResolveLibraryTypeNamesTaskTest);
  runReflectiveTests(ResolveTopLevelUnitTypeBoundsTaskTest);
  runReflectiveTests(ResolveUnitTaskTest);
  runReflectiveTests(ResolveUnitTypeNamesTaskTest);
  runReflectiveTests(ResolveVariableReferencesTaskTest);
  runReflectiveTests(ScanDartTaskTest);
  runReflectiveTests(StrongModeInferenceTest);
  runReflectiveTests(StrongModeVerifyUnitTaskTest);
  runReflectiveTests(VerifyUnitTaskTest);
}

isInstanceOf isBuildCompilationUnitElementTask =
    new isInstanceOf<BuildCompilationUnitElementTask>();
isInstanceOf isBuildDirectiveElementsTask =
    new isInstanceOf<BuildDirectiveElementsTask>();
isInstanceOf isBuildEnumMemberElementsTask =
    new isInstanceOf<BuildEnumMemberElementsTask>();
isInstanceOf isBuildExportNamespaceTask =
    new isInstanceOf<BuildExportNamespaceTask>();
isInstanceOf isBuildLibraryElementTask =
    new isInstanceOf<BuildLibraryElementTask>();
isInstanceOf isBuildPublicNamespaceTask =
    new isInstanceOf<BuildPublicNamespaceTask>();
isInstanceOf isBuildSourceExportClosureTask =
    new isInstanceOf<BuildSourceExportClosureTask>();
isInstanceOf isBuildTypeProviderTask =
    new isInstanceOf<BuildTypeProviderTask>();
isInstanceOf isComputeConstantDependenciesTask =
    new isInstanceOf<ComputeConstantDependenciesTask>();
isInstanceOf isComputeConstantValueTask =
    new isInstanceOf<ComputeConstantValueTask>();
isInstanceOf isComputeInferableStaticVariableDependenciesTask =
    new isInstanceOf<ComputeInferableStaticVariableDependenciesTask>();
isInstanceOf isComputePropagableVariableDependenciesTask =
    new isInstanceOf<ComputePropagableVariableDependenciesTask>();
isInstanceOf isContainingLibrariesTask =
    new isInstanceOf<ContainingLibrariesTask>();
isInstanceOf isDartErrorsTask = new isInstanceOf<DartErrorsTask>();
isInstanceOf isEvaluateUnitConstantsTask =
    new isInstanceOf<EvaluateUnitConstantsTask>();
isInstanceOf isGatherUsedImportedElementsTask =
    new isInstanceOf<GatherUsedImportedElementsTask>();
isInstanceOf isGatherUsedLocalElementsTask =
    new isInstanceOf<GatherUsedLocalElementsTask>();
isInstanceOf isGenerateHintsTask = new isInstanceOf<GenerateHintsTask>();
isInstanceOf isGenerateLintsTask = new isInstanceOf<GenerateLintsTask>();
isInstanceOf isInferInstanceMembersInUnitTask =
    new isInstanceOf<InferInstanceMembersInUnitTask>();
isInstanceOf isInferStaticVariableTypesInUnitTask =
    new isInstanceOf<InferStaticVariableTypesInUnitTask>();
isInstanceOf isInferStaticVariableTypeTask =
    new isInstanceOf<InferStaticVariableTypeTask>();
isInstanceOf isLibraryErrorsReadyTask =
    new isInstanceOf<LibraryErrorsReadyTask>();
isInstanceOf isLibraryUnitErrorsTask =
    new isInstanceOf<LibraryUnitErrorsTask>();
isInstanceOf isParseDartTask = new isInstanceOf<ParseDartTask>();
isInstanceOf isPartiallyResolveUnitReferencesTask =
    new isInstanceOf<PartiallyResolveUnitReferencesTask>();
isInstanceOf isPropagateVariableTypesInUnitTask =
    new isInstanceOf<PropagateVariableTypesInUnitTask>();
isInstanceOf isPropagateVariableTypeTask =
    new isInstanceOf<PropagateVariableTypeTask>();
isInstanceOf isResolveDirectiveElementsTask =
    new isInstanceOf<ResolveDirectiveElementsTask>();
isInstanceOf isResolveLibraryReferencesTask =
    new isInstanceOf<ResolveLibraryReferencesTask>();
isInstanceOf isResolveLibraryTask = new isInstanceOf<ResolveLibraryTask>();
isInstanceOf isResolveLibraryTypeNamesTask =
    new isInstanceOf<ResolveLibraryTypeNamesTask>();
isInstanceOf isResolveTopLevelUnitTypeBoundsTask =
    new isInstanceOf<ResolveTopLevelUnitTypeBoundsTask>();
isInstanceOf isResolveUnitTask = new isInstanceOf<ResolveUnitTask>();
isInstanceOf isResolveUnitTypeNamesTask =
    new isInstanceOf<ResolveUnitTypeNamesTask>();
isInstanceOf isResolveVariableReferencesTask =
    new isInstanceOf<ResolveVariableReferencesTask>();
isInstanceOf isScanDartTask = new isInstanceOf<ScanDartTask>();
isInstanceOf isStrongModeVerifyUnitTask =
    new isInstanceOf<StrongModeVerifyUnitTask>();
isInstanceOf isVerifyUnitTask = new isInstanceOf<VerifyUnitTask>();

final LintCode _testLintCode = new LintCode('test lint', 'test lint code');

@reflectiveTest
class BuildCompilationUnitElementTaskTest extends _AbstractDartTaskTest {
  Source source;
  LibrarySpecificUnit target;

  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT1);
    expect(outputs[RESOLVED_UNIT1], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT1], isTrue);
  }

  test_perform_find_constants() {
    _performBuildTask('''
const x = 1;
class C {
  static const y = 1;
  const C([p = 1]);
}
@x
f() {
  const z = 1;
}
''');
    CompilationUnit unit = outputs[RESOLVED_UNIT1];
    CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT];
    Annotation annotation = unit.declarations
        .firstWhere((m) => m is FunctionDeclaration)
        .metadata[0];
    List<ConstantEvaluationTarget> expectedConstants = [
      unitElement.accessors.firstWhere((e) => e.isGetter).variable,
      unitElement.types[0].fields[0],
      unitElement.functions[0].localVariables[0],
      unitElement.types[0].constructors[0],
      annotation.elementAnnotation,
      unitElement.types[0].constructors[0].parameters[0]
    ];
    expect(
        outputs[COMPILATION_UNIT_CONSTANTS].toSet(), expectedConstants.toSet());
  }

  test_perform_library() {
    _performBuildTask(r'''
library lib;
import 'lib2.dart';
export 'lib3.dart';
part 'part.dart';
final x = '';
class A {
  static final y = 0;
}
class B = Object with A;
''');
    expect(outputs, hasLength(4));
    expect(outputs[COMPILATION_UNIT_CONSTANTS], isNotNull);
    expect(outputs[COMPILATION_UNIT_ELEMENT], isNotNull);
    expect(outputs[RESOLVED_UNIT1], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT1], isTrue);
  }

  test_perform_reuseElement() {
    _performBuildTask(r'''
library lib;
class A {}
class B = Object with A;
''');
    CompilationUnit unit = outputs[RESOLVED_UNIT1];
    CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT];
    expect(unit, isNotNull);
    expect(unitElement, isNotNull);
    // invalidate RESOLVED_UNIT1
    CacheEntry cacheEntry = analysisCache.get(target);
    cacheEntry.setState(RESOLVED_UNIT1, CacheState.INVALID);
    // compute again
    computeResult(target, RESOLVED_UNIT1,
        matcher: isBuildCompilationUnitElementTask);
    expect(outputs[COMPILATION_UNIT_ELEMENT], same(unitElement));
    expect(outputs[RESOLVED_UNIT1], isNot(same(unit)));
  }

  void _performBuildTask(String content) {
    source = newSource('/test.dart', content);
    target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT1,
        matcher: isBuildCompilationUnitElementTask);
  }
}

@reflectiveTest
class BuildDirectiveElementsTaskTest extends _AbstractDartTaskTest {
  /**
   * Verify that the given [element] has exactly one annotation, and that its
   * [ElementAnnotationImpl] is unresolved and points back to [element].
   *
   * The compilation unit stored in the [ElementAnnotationImpl] should be
   * [compilationUnit].
   */
  void checkMetadata(Element element, CompilationUnitElement compilationUnit) {
    expect(element.metadata, hasLength(1));
    expect(element.metadata[0], new isInstanceOf<ElementAnnotationImpl>());
    ElementAnnotationImpl elementAnnotation = element.metadata[0];
    expect(elementAnnotation.element, isNull); // Not yet resolved
    expect(elementAnnotation.compilationUnit, isNotNull);
    expect(elementAnnotation.compilationUnit, compilationUnit);
  }

  test_perform() {
    List<Source> sources = newSources({
      '/libA.dart': '''
library libA;
import 'libB.dart';
export 'libC.dart';
''',
      '/libB.dart': '''
library libB;
''',
      '/libC.dart': '''
library libC;
'''
    });
    Source sourceA = sources[0];
    Source sourceB = sources[1];
    Source sourceC = sources[2];
    // perform task
    computeResult(sourceA, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // prepare outputs
    LibraryElement libraryElementA = outputs[LIBRARY_ELEMENT2];
    LibraryElement libraryElementB = _getImportLibraryInput(sourceB);
    LibraryElement libraryElementC = _getExportLibraryInput(sourceC);
    // no errors
    _assertErrorsWithCodes([]);
    // validate directives
    CompilationUnit libraryUnitA = context
        .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA))
        .getValue(RESOLVED_UNIT1);
    {
      ImportDirective importNode = libraryUnitA.directives[1];
      ImportElement importElement = importNode.element;
      expect(importElement, isNotNull);
      expect(importElement.importedLibrary, libraryElementB);
      expect(importElement.prefix, isNull);
      expect(importElement.nameOffset, 14);
      expect(importElement.uriOffset, 21);
      expect(importElement.uriEnd, 32);
    }
    {
      ExportDirective exportNode = libraryUnitA.directives[2];
      ExportElement exportElement = exportNode.element;
      expect(exportElement, isNotNull);
      expect(exportElement.exportedLibrary, libraryElementC);
      expect(exportElement.nameOffset, 34);
      expect(exportElement.uriOffset, 41);
      expect(exportElement.uriEnd, 52);
    }
    // validate LibraryElement
    expect(libraryElementA.hasExtUri, isFalse);
    // has an artificial "dart:core" import
    {
      List<ImportElement> imports = libraryElementA.imports;
      expect(imports, hasLength(2));
      expect(imports[1].importedLibrary.isDartCore, isTrue);
      expect(imports[1].isSynthetic, isTrue);
    }
  }

  test_perform_combinators() {
    List<Source> sources = newSources({
      '/libA.dart': '''
library libA;
import 'libB.dart' show A, B hide C, D;
''',
      '/libB.dart': '''
library libB;
'''
    });
    Source sourceA = sources[0];
    // perform task
    computeResult(sourceA, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // prepare outputs
    CompilationUnit libraryUnitA = context
        .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA))
        .getValue(RESOLVED_UNIT1);
    // no errors
    _assertErrorsWithCodes([]);
    // validate directives
    ImportDirective importNode = libraryUnitA.directives[1];
    ImportElement importElement = importNode.element;
    List<NamespaceCombinator> combinators = importElement.combinators;
    expect(combinators, hasLength(2));
    {
      ShowElementCombinator combinator = combinators[0];
      expect(combinator.offset, 33);
      expect(combinator.end, 42);
      expect(combinator.shownNames, ['A', 'B']);
    }
    {
      HideElementCombinator combinator = combinators[1];
      expect(combinator.hiddenNames, ['C', 'D']);
    }
  }

  test_perform_dartCoreContext() {
    List<Source> sources = newSources({'/libA.dart': ''});
    Source source = sources[0];
    // perform task
    computeResult(source, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // prepare outputs
    LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2];
    // verify that dart:core has SDK context
    {
      LibraryElement coreLibrary = libraryElement.importedLibraries[0];
      DartSdk dartSdk = context.sourceFactory.dartSdk;
      expect(coreLibrary.context, same(dartSdk.context));
    }
  }

  test_perform_error_exportOfNonLibrary() {
    List<Source> sources = newSources({
      '/libA.dart': '''
library libA;
export 'part.dart';
''',
      '/part.dart': '''
part of notLib;
'''
    });
    Source sourceA = sources[0];
    // perform task
    computeResult(sourceA, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // validate errors
    _assertErrorsWithCodes([CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]);
  }

  test_perform_error_importOfNonLibrary() {
    List<Source> sources = newSources({
      '/libA.dart': '''
library libA;
import 'part.dart';
''',
      '/part.dart': '''
part of notLib;
'''
    });
    Source sourceA = sources[0];
    // perform task
    computeResult(sourceA, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // validate errors
    _assertErrorsWithCodes([CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]);
  }

  test_perform_explicitDartCoreImport() {
    List<Source> sources = newSources({
      '/lib.dart': '''
library lib;
import 'dart:core' show List;
'''
    });
    Source source = sources[0];
    // perform task
    computeResult(source, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // prepare outputs
    LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2];
    // has an explicit "dart:core" import
    {
      List<ImportElement> imports = libraryElement.imports;
      expect(imports, hasLength(1));
      expect(imports[0].importedLibrary.isDartCore, isTrue);
      expect(imports[0].isSynthetic, isFalse);
    }
  }

  test_perform_hasExtUri() {
    List<Source> sources = newSources({
      '/lib.dart': '''
import 'dart-ext:doesNotExist.dart';
'''
    });
    Source source = sources[0];
    // perform task
    computeResult(source, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // prepare outputs
    LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2];
    expect(libraryElement.hasExtUri, isTrue);
  }

  test_perform_importPrefix() {
    List<Source> sources = newSources({
      '/libA.dart': '''
library libA;
import 'libB.dart' as pref;
import 'libC.dart' as pref;
''',
      '/libB.dart': '''
library libB;
''',
      '/libC.dart': '''
library libC;
'''
    });
    Source sourceA = sources[0];
    Source sourceB = sources[1];
    // perform task
    computeResult(sourceA, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // prepare outputs
    CompilationUnit libraryUnitA = context
        .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA))
        .getValue(RESOLVED_UNIT1);
    // validate directives
    ImportDirective importNodeB = libraryUnitA.directives[1];
    SimpleIdentifier prefixNodeB = importNodeB.prefix;
    ImportElement importElementB = importNodeB.element;
    PrefixElement prefixElement = importElementB.prefix;
    expect(importElementB, isNotNull);
    expect(importElementB.importedLibrary, _getImportLibraryInput(sourceB));
    expect(prefixElement, isNotNull);
    expect(importElementB.prefixOffset, prefixElement.nameOffset);
    expect(prefixNodeB.staticElement, prefixElement);
    // PrefixElement "pref" is shared
    ImportDirective importNodeC = libraryUnitA.directives[2];
    SimpleIdentifier prefixNodeC = importNodeC.prefix;
    ImportElement importElementC = importNodeC.element;
    expect(prefixNodeC.staticElement, prefixElement);
    expect(importElementC.prefix, prefixElement);
  }

  test_perform_metadata() {
    List<Source> sources = newSources({
      '/libA.dart': '''
@a library libA;
@b import 'libB.dart';
@c export 'libC.dart';
@d part 'part.dart';''',
      '/libB.dart': 'library libB;',
      '/libC.dart': 'library libC;',
      '/part.dart': 'part of libA;'
    });
    Source sourceA = sources[0];
    // perform task
    computeResult(sourceA, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // Get outputs
    LibraryElement libraryA =
        context.getCacheEntry(sourceA).getValue(LIBRARY_ELEMENT2);
    // Validate metadata
    checkMetadata(libraryA, libraryA.definingCompilationUnit);
    checkMetadata(libraryA.imports[0], libraryA.definingCompilationUnit);
    checkMetadata(libraryA.exports[0], libraryA.definingCompilationUnit);
    checkMetadata(libraryA.parts[0], libraryA.definingCompilationUnit);
  }

  test_perform_metadata_partOf() {
    // We don't record annotations on `part of` directives because the element
    // associated with a `part of` directive is the library, and the convention
    // is to annotate the library at the site of the `library` declaration.
    List<Source> sources = newSources({
      '/libA.dart': '''
library libA;
part 'part.dart';''',
      '/part.dart': '@a part of libA;'
    });
    Source sourceA = sources[0];
    Source sourcePart = sources[1];
    // perform task
    computeResult(sourceA, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // Get outputs
    LibraryElement libraryA =
        context.getCacheEntry(sourceA).getValue(LIBRARY_ELEMENT2);
    CompilationUnit part = context
        .getCacheEntry(new LibrarySpecificUnit(sourceA, sourcePart))
        .getValue(RESOLVED_UNIT1);
    // Validate metadata
    expect(part.directives[0], new isInstanceOf<PartOfDirective>());
    expect(part.directives[0].element, same(libraryA));
    expect(part.directives[0].element.metadata, isEmpty);
  }

  void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) {
    _fillErrorListener(BUILD_DIRECTIVES_ERRORS);
    errorListener.assertErrorsWithCodes(expectedErrorCodes);
  }

  _getExportLibraryInput(Source source) {
    var key = BuildDirectiveElementsTask.EXPORTS_LIBRARY_ELEMENT_INPUT_NAME;
    return task.inputs[key][source];
  }

  _getImportLibraryInput(Source source) {
    var key = BuildDirectiveElementsTask.IMPORTS_LIBRARY_ELEMENT_INPUT_NAME;
    return task.inputs[key][source];
  }
}

@reflectiveTest
class BuildEnumMemberElementsTaskTest extends _AbstractDartTaskTest {
  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT3);
    expect(outputs[RESOLVED_UNIT3], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT3], isTrue);
  }

  test_perform() {
    Source source = newSource(
        '/test.dart',
        '''
enum MyEnum {
  A, B
}
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT3,
        matcher: isBuildEnumMemberElementsTask);
    CompilationUnit unit = outputs[RESOLVED_UNIT3];
    // validate Element
    ClassElement enumElement = unit.element.getEnum('MyEnum');
    List<FieldElement> fields = enumElement.fields;
    expect(fields, hasLength(4));
    {
      FieldElementImpl index = fields[0];
      expect(index, isNotNull);
      expect(index.name, 'index');
      expect(index.isStatic, isFalse);
      expect(index.evaluationResult, isNull);
      _assertGetter(index);
    }
    {
      ConstFieldElementImpl values = fields[1];
      expect(values, isNotNull);
      expect(values.name, 'values');
      expect(values.isStatic, isTrue);
      expect(values.evaluationResult, isNotNull);
      _assertGetter(values);
    }
    {
      ConstFieldElementImpl constant = fields[2];
      expect(constant, isNotNull);
      expect(constant.name, 'A');
      expect(constant.isStatic, isTrue);
      expect(constant.evaluationResult, isNotNull);
      _assertGetter(constant);
    }
    {
      ConstFieldElementImpl constant = fields[3];
      expect(constant, isNotNull);
      expect(constant.name, 'B');
      expect(constant.isStatic, isTrue);
      expect(constant.evaluationResult, isNotNull);
      _assertGetter(constant);
    }
    // validate nodes
    EnumDeclaration enumNode = unit.declarations[0];
    expect(enumNode.name.staticElement, same(enumElement));
    expect(enumNode.constants[0].element, same(enumElement.getField('A')));
    expect(enumNode.constants[1].element, same(enumElement.getField('B')));
  }

  static void _assertGetter(FieldElement field) {
    PropertyAccessorElement getter = field.getter;
    expect(getter, isNotNull);
    expect(getter.variable, same(field));
    expect(getter.type, isNotNull);
  }
}

@reflectiveTest
class BuildExportNamespaceTaskTest extends _AbstractDartTaskTest {
  test_perform_entryPoint() {
    Source sourceA = newSource(
        '/a.dart',
        '''
library lib_a;
export 'b.dart';
''');
    Source sourceB = newSource(
        '/b.dart',
        '''
library lib_b;
main() {}
''');
    computeResult(sourceA, LIBRARY_ELEMENT4,
        matcher: isBuildExportNamespaceTask);
    // validate
    LibraryElement library = outputs[LIBRARY_ELEMENT4];
    FunctionElement entryPoint = library.entryPoint;
    expect(entryPoint, isNotNull);
    expect(entryPoint.source, sourceB);
  }

  test_perform_hideCombinator() {
    Source sourceA = newSource(
        '/a.dart',
        '''
library lib_a;
export 'b.dart' hide B1;
class A1 {}
class A2 {}
class _A3 {}
''');
    newSource(
        '/b.dart',
        '''
library lib_b;
class B1 {}
class B2 {}
class B3 {}
class _B4 {}
''');
    newSource(
        '/c.dart',
        '''
library lib_c;
class C1 {}
class C2 {}
class C3 {}
''');
    computeResult(sourceA, LIBRARY_ELEMENT4,
        matcher: isBuildExportNamespaceTask);
    // validate
    LibraryElement library = outputs[LIBRARY_ELEMENT4];
    Namespace namespace = library.exportNamespace;
    Iterable<String> definedKeys = namespace.definedNames.keys;
    expect(definedKeys, unorderedEquals(['A1', 'A2', 'B2', 'B3']));
  }

  test_perform_showCombinator() {
    Source sourceA = newSource(
        '/a.dart',
        '''
library lib_a;
export 'b.dart' show B1;
class A1 {}
class A2 {}
class _A3 {}
''');
    newSource(
        '/b.dart',
        '''
library lib_b;
class B1 {}
class B2 {}
class _B3 {}
''');
    computeResult(sourceA, LIBRARY_ELEMENT4,
        matcher: isBuildExportNamespaceTask);
    // validate
    LibraryElement library = outputs[LIBRARY_ELEMENT4];
    Namespace namespace = library.exportNamespace;
    Iterable<String> definedKeys = namespace.definedNames.keys;
    expect(definedKeys, unorderedEquals(['A1', 'A2', 'B1']));
  }

  test_perform_showCombinator_setter() {
    Source sourceA = newSource(
        '/a.dart',
        '''
library lib_a;
export 'b.dart' show topLevelB;
class A {}
''');
    newSource(
        '/b.dart',
        '''
library lib_b;
int topLevelB;
''');
    computeResult(sourceA, LIBRARY_ELEMENT4,
        matcher: isBuildExportNamespaceTask);
    // validate
    LibraryElement library = outputs[LIBRARY_ELEMENT4];
    Namespace namespace = library.exportNamespace;
    Iterable<String> definedKeys = namespace.definedNames.keys;
    expect(definedKeys, unorderedEquals(['A', 'topLevelB', 'topLevelB=']));
  }
}

@reflectiveTest
class BuildLibraryElementTaskTest extends _AbstractDartTaskTest {
  Source librarySource;
  CompilationUnit libraryUnit;
  CompilationUnitElement libraryUnitElement;
  List<CompilationUnit> partUnits;

  LibraryElement libraryElement;

  test_perform() {
    _performBuildTask({
      '/lib.dart': '''
library lib;
part 'part1.dart';
part 'part2.dart';
''',
      '/part1.dart': '''
part of lib;
''',
      '/part2.dart': '''
part of lib;
'''
    });
    expect(outputs, hasLength(3));
    // simple outputs
    expect(outputs[BUILD_LIBRARY_ERRORS], isEmpty);
    expect(outputs[IS_LAUNCHABLE], isFalse);
    // LibraryElement output
    expect(libraryElement, isNotNull);
    expect(libraryElement.entryPoint, isNull);
    expect(libraryElement.source, same(librarySource));
    expect(libraryElement.definingCompilationUnit, libraryUnitElement);
    expect(libraryElement.parts,
        unorderedEquals([partUnits[0].element, partUnits[1].element]));
    // LibraryElement references
    expect((libraryUnit.directives[0] as LibraryDirective).element,
        same(libraryElement));
    expect((partUnits[0].directives[0] as PartOfDirective).element,
        same(libraryElement));
    expect((partUnits[1].directives[0] as PartOfDirective).element,
        same(libraryElement));
    // CompilationUnitElement(s)
    CompilationUnitElement firstPart;
    CompilationUnitElement secondPart;
    if (partUnits[0].element.uri == 'part1.dart') {
      firstPart = partUnits[0].element;
      secondPart = partUnits[1].element;
    } else {
      firstPart = partUnits[1].element;
      secondPart = partUnits[0].element;
    }
    expect(firstPart.uri, 'part1.dart');
    expect(firstPart.uriOffset, 18);
    expect(firstPart.uriEnd, 30);
    expect(
        (libraryUnit.directives[1] as PartDirective).element, same(firstPart));

    expect(secondPart.uri, 'part2.dart');
    expect(secondPart.uriOffset, 37);
    expect(secondPart.uriEnd, 49);
    expect(
        (libraryUnit.directives[2] as PartDirective).element, same(secondPart));
  }

  test_perform_error_missingLibraryDirectiveWithPart_hasCommon() {
    _performBuildTask({
      '/lib.dart': '''
part 'partA.dart';
part 'partB.dart';
''',
      '/partA.dart': '''
part of my_lib;
        ''',
      '/partB.dart': '''
part of my_lib;
'''
    });
    _assertErrorsWithCodes(
        [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
    AnalysisError error = errorListener.errors[0];
    expect(error.getProperty(ErrorProperty.PARTS_LIBRARY_NAME), 'my_lib');
  }

  test_perform_error_missingLibraryDirectiveWithPart_noCommon() {
    _performBuildTask({
      '/lib.dart': '''
part 'partA.dart';
part 'partB.dart';
''',
      '/partA.dart': '''
part of libA;
        ''',
      '/partB.dart': '''
part of libB;
'''
    });
    _assertErrorsWithCodes(
        [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
    AnalysisError error = errorListener.errors[0];
    expect(error.getProperty(ErrorProperty.PARTS_LIBRARY_NAME), isNull);
  }

  test_perform_error_partDoesNotExist() {
    _performBuildTask({
      '/lib.dart': '''
library lib;
part 'part.dart';
'''
    });
    // we already report URI_DOES_NOT_EXIST, no need to report other errors
    _assertErrorsWithCodes([]);
  }

  test_perform_error_partOfDifferentLibrary() {
    _performBuildTask({
      '/lib.dart': '''
library lib;
part 'part.dart';
''',
      '/part.dart': '''
part of someOtherLib;
'''
    });
    _assertErrorsWithCodes([StaticWarningCode.PART_OF_DIFFERENT_LIBRARY]);
  }

  test_perform_error_partOfNonPart() {
    _performBuildTask({
      '/lib.dart': '''
library lib;
part 'part.dart';
''',
      '/part.dart': '''
// no part of
'''
    });
    _assertErrorsWithCodes([CompileTimeErrorCode.PART_OF_NON_PART]);
  }

  test_perform_invalidUri_part() {
    _performBuildTask({
      '/lib.dart': '''
library lib;
part '//////////';
'''
    });
    expect(libraryElement.parts, isEmpty);
  }

  test_perform_isLaunchable_inDefiningUnit() {
    _performBuildTask({
      '/lib.dart': '''
library lib;
main() {
}
'''
    });
    expect(outputs[IS_LAUNCHABLE], isTrue);
    expect(libraryElement.entryPoint, isNotNull);
  }

  test_perform_isLaunchable_inPartUnit() {
    _performBuildTask({
      '/lib.dart': '''
library lib;
part 'part.dart';
''',
      '/part.dart': '''
part of lib;
main() {
}
'''
    });
    expect(outputs[IS_LAUNCHABLE], isTrue);
    expect(libraryElement.entryPoint, isNotNull);
  }

  test_perform_noSuchFilePart() {
    _performBuildTask({
      '/lib.dart': '''
library lib;
part 'no-such-file.dart';
'''
    });
    expect(libraryElement.parts, hasLength(1));
    CompilationUnitElement part = libraryElement.parts[0];
    expect(part, isNotNull);
    expect(part.source, isNotNull);
    expect(part.library, same(libraryElement));
    expect(context.exists(part.source), isFalse);
  }

  test_perform_patchTopLevelAccessors() {
    _performBuildTask({
      '/lib.dart': '''
library lib;
part 'part1.dart';
part 'part2.dart';
''',
      '/part1.dart': '''
part of lib;
int get test => 0;
''',
      '/part2.dart': '''
part of lib;
void set test(_) {}
'''
    });
    CompilationUnitElement unitElement1 = partUnits
        .singleWhere((u) => u.element.name.endsWith('part1.dart'))
        .element;
    CompilationUnitElement unitElement2 = partUnits
        .singleWhere((u) => u.element.name.endsWith('part2.dart'))
        .element;
    PropertyAccessorElement getter = unitElement1.accessors[0];
    PropertyAccessorElement setter = unitElement2.accessors[0];
    PropertyInducingElement variable = getter.variable;
    expect(getter.isGetter, isTrue);
    expect(setter.isSetter, isTrue);
    expect(variable, isNotNull);
    expect(setter.variable, same(variable));
    expect(unitElement1.topLevelVariables, [variable]);
    expect(unitElement2.topLevelVariables, [variable]);
  }

  void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) {
    _fillErrorListener(BUILD_LIBRARY_ERRORS);
    errorListener.assertErrorsWithCodes(expectedErrorCodes);
  }

  void _performBuildTask(Map<String, String> sourceMap) {
    List<Source> sources = newSources(sourceMap);
    Source libSource = sources.first;
    computeResult(libSource, LIBRARY_ELEMENT1,
        matcher: isBuildLibraryElementTask);
    libraryUnit = context
        .getCacheEntry(new LibrarySpecificUnit(libSource, libSource))
        .getValue(RESOLVED_UNIT1);
    libraryUnitElement = libraryUnit.element;
    librarySource = libraryUnitElement.source;
    libraryElement = outputs[LIBRARY_ELEMENT1];
    partUnits = task.inputs[BuildLibraryElementTask.PARTS_UNIT_INPUT]
        as List<CompilationUnit>;
  }
}

@reflectiveTest
class BuildPublicNamespaceTaskTest extends _AbstractDartTaskTest {
  test_perform() {
    List<Source> sources = newSources({
      '/lib.dart': '''
library lib;
part 'part.dart';
a() {}
_b() {}
''',
      '/part.dart': '''
part of lib;
_c() {}
d() {}
'''
    });
    computeResult(sources.first, LIBRARY_ELEMENT3,
        matcher: isBuildPublicNamespaceTask);
    // validate
    LibraryElement library = outputs[LIBRARY_ELEMENT3];
    Namespace namespace = library.publicNamespace;
    expect(namespace.definedNames.keys, unorderedEquals(['a', 'd']));
  }
}

@reflectiveTest
class BuildSourceExportClosureTaskTest extends _AbstractDartTaskTest {
  List<Source> getExportSourceClosure(Map<ResultDescriptor, dynamic> outputs) {
    return outputs[EXPORT_SOURCE_CLOSURE] as List<Source>;
  }

  test_perform_exportClosure() {
    Source sourceA = newSource(
        '/a.dart',
        '''
library lib_a;
export 'b.dart';
''');
    Source sourceB = newSource(
        '/b.dart',
        '''
library lib_b;
export 'c.dart';
''');
    Source sourceC = newSource(
        '/c.dart',
        '''
library lib_c;
export 'a.dart';
''');
    Source sourceD = newSource(
        '/d.dart',
        '''
library lib_d;
''');
    // a.dart
    {
      computeResult(sourceA, EXPORT_SOURCE_CLOSURE,
          matcher: isBuildSourceExportClosureTask);
      List<Source> closure = getExportSourceClosure(outputs);
      expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
    }
    // c.dart
    {
      computeResult(sourceC, EXPORT_SOURCE_CLOSURE,
          matcher: isBuildSourceExportClosureTask);
      List<Source> closure = getExportSourceClosure(outputs);
      expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
    }
    // d.dart
    {
      computeResult(sourceD, EXPORT_SOURCE_CLOSURE,
          matcher: isBuildSourceExportClosureTask);
      List<Source> closure = getExportSourceClosure(outputs);
      expect(closure, unorderedEquals([sourceD]));
    }
  }
}

@reflectiveTest
class BuildTypeProviderTaskTest extends _AbstractDartTaskTest {
  test_perform() {
    computeResult(AnalysisContextTarget.request, TYPE_PROVIDER,
        matcher: isBuildTypeProviderTask);
    // validate
    TypeProvider typeProvider = outputs[TYPE_PROVIDER];
    expect(typeProvider, isNotNull);
    expect(typeProvider.boolType, isNotNull);
    expect(typeProvider.intType, isNotNull);
    expect(typeProvider.futureType, isNotNull);
  }
}

@reflectiveTest
class BuildTypeProviderTaskTest_noAsync extends _AbstractDartTaskTest {
  DartSdk createDartSdk() => new MockSdk(dartAsync: false);

  void prepareAnalysisContext([AnalysisOptions options]) {
    AnalysisOptionsImpl newOptions = new AnalysisOptionsImpl();
    newOptions.enableAsync = false;
    super.prepareAnalysisContext(newOptions);
  }

  test_perform_noAsync() {
    expect(context, isNotNull);
    computeResult(AnalysisContextTarget.request, TYPE_PROVIDER,
        matcher: isBuildTypeProviderTask);
    // validate
    TypeProvider typeProvider = outputs[TYPE_PROVIDER];
    expect(typeProvider, isNotNull);
    expect(typeProvider.boolType, isNotNull);
    expect(typeProvider.intType, isNotNull);
    expect(typeProvider.futureType, isNotNull);
  }
}

@reflectiveTest
class ComputeConstantDependenciesTaskTest extends _AbstractDartTaskTest {
  Annotation findClassAnnotation(CompilationUnit unit, String className) {
    for (CompilationUnitMember member in unit.declarations) {
      if (member is ClassDeclaration && member.name.name == className) {
        expect(member.metadata, hasLength(1));
        return member.metadata[0];
      }
    }
    fail('Annotation not found');
    return null;
  }

  test_annotation_with_args() {
    Source source = newSource(
        '/test.dart',
        '''
const x = 1;
@D(x) class C {}
class D { const D(value); }
''');
    // First compute the resolved unit for the source.
    LibrarySpecificUnit librarySpecificUnit =
        new LibrarySpecificUnit(source, source);
    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
    CompilationUnit unit = outputs[RESOLVED_UNIT1];
    // Find the elements for x and D's constructor, and the annotation on C.
    List<PropertyAccessorElement> accessors = unit.element.accessors;
    Element x = accessors
        .firstWhere((PropertyAccessorElement accessor) =>
            accessor.isGetter && accessor.name == 'x')
        .variable;
    List<ClassElement> types = unit.element.types;
    Element constructorForD =
        types.firstWhere((ClassElement cls) => cls.name == 'D').constructors[0];
    Annotation annotation = findClassAnnotation(unit, 'C');
    // Now compute the dependencies for the annotation, and check that it is
    // the set [x, constructorForD].
    // TODO(paulberry): test librarySource != source
    computeResult(annotation.elementAnnotation, CONSTANT_DEPENDENCIES,
        matcher: isComputeConstantDependenciesTask);
    expect(
        outputs[CONSTANT_DEPENDENCIES].toSet(), [x, constructorForD].toSet());
  }

  test_annotation_with_nonConstArg() {
    Source source = newSource(
        '/test.dart',
        '''
class A {
  const A(x);
}
class C {
  @A(const [(_) => null])
  String s;
}
''');
    // First compute the resolved unit for the source.
    LibrarySpecificUnit librarySpecificUnit =
        new LibrarySpecificUnit(source, source);
    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
    CompilationUnit unit = outputs[RESOLVED_UNIT1];
    // Find the annotation on the field.
    ClassDeclaration classC = unit.declarations[1];
    Annotation annotation = classC.members[0].metadata[0];
    // Now compute the dependencies for the annotation, and check that it is
    // the right size.
    computeResult(annotation.elementAnnotation, CONSTANT_DEPENDENCIES,
        matcher: isComputeConstantDependenciesTask);
    expect(outputs[CONSTANT_DEPENDENCIES], hasLength(1));
  }

  test_annotation_without_args() {
    Source source = newSource(
        '/test.dart',
        '''
const x = 1;
@x class C {}
''');
    // First compute the resolved unit for the source.
    LibrarySpecificUnit librarySpecificUnit =
        new LibrarySpecificUnit(source, source);
    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
    CompilationUnit unit = outputs[RESOLVED_UNIT1];
    // Find the element for x and the annotation on C.
    List<PropertyAccessorElement> accessors = unit.element.accessors;
    Element x = accessors
        .firstWhere((PropertyAccessorElement accessor) =>
            accessor.isGetter && accessor.name == 'x')
        .variable;
    Annotation annotation = findClassAnnotation(unit, 'C');
    // Now compute the dependencies for the annotation, and check that it is
    // the list [x].
    computeResult(annotation.elementAnnotation, CONSTANT_DEPENDENCIES,
        matcher: isComputeConstantDependenciesTask);
    expect(outputs[CONSTANT_DEPENDENCIES], [x]);
  }

  test_enumConstant() {
    Source source = newSource(
        '/test.dart',
        '''
enum E {A, B, C}
''');
    // First compute the resolved unit for the source.
    LibrarySpecificUnit librarySpecificUnit =
        new LibrarySpecificUnit(source, source);
    computeResult(librarySpecificUnit, RESOLVED_UNIT3);
    CompilationUnit unit = outputs[RESOLVED_UNIT3];
    // Find the element for 'A'
    EnumDeclaration enumDeclaration = unit.declarations[0];
    EnumConstantDeclaration constantDeclaration = enumDeclaration.constants[0];
    FieldElement constantElement = constantDeclaration.element;
    // Now compute the dependencies for the constant and check that there are
    // none.
    computeResult(constantElement, CONSTANT_DEPENDENCIES,
        matcher: isComputeConstantDependenciesTask);
    expect(outputs[CONSTANT_DEPENDENCIES], isEmpty);
  }

  test_perform() {
    Source source = newSource(
        '/test.dart',
        '''
const x = y;
const y = 1;
''');
    // First compute the resolved unit for the source.
    LibrarySpecificUnit librarySpecificUnit =
        new LibrarySpecificUnit(source, source);
    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
    CompilationUnit unit = outputs[RESOLVED_UNIT1];
    // Find the elements for the constants x and y.
    List<PropertyAccessorElement> accessors = unit.element.accessors;
    Element x = accessors
        .firstWhere((PropertyAccessorElement accessor) =>
            accessor.isGetter && accessor.name == 'x')
        .variable;
    Element y = accessors
        .firstWhere((PropertyAccessorElement accessor) =>
            accessor.isGetter && accessor.name == 'y')
        .variable;
    // Now compute the dependencies for x, and check that it is the list [y].
    computeResult(x, CONSTANT_DEPENDENCIES,
        matcher: isComputeConstantDependenciesTask);
    expect(outputs[CONSTANT_DEPENDENCIES], [y]);
  }
}

@reflectiveTest
class ComputeConstantValueTaskTest extends _AbstractDartTaskTest {
  EvaluationResultImpl computeClassAnnotation(
      Source source, CompilationUnit unit, String className) {
    for (CompilationUnitMember member in unit.declarations) {
      if (member is ClassDeclaration && member.name.name == className) {
        expect(member.metadata, hasLength(1));
        Annotation annotation = member.metadata[0];
        ElementAnnotationImpl target = annotation.elementAnnotation;
        computeResult(target, CONSTANT_VALUE,
            matcher: isComputeConstantValueTask);
        expect(outputs[CONSTANT_VALUE], same(target));
        EvaluationResultImpl evaluationResult =
            (annotation.elementAnnotation as ElementAnnotationImpl)
                .evaluationResult;
        return evaluationResult;
      }
    }
    fail('Annotation not found');
    return null;
  }

  test_annotation_non_const_constructor() {
    // Calling a non-const constructor from an annotation that is illegal, but
    // shouldn't crash analysis.
    Source source = newSource(
        '/test.dart',
        '''
class A {
  final int i;
  A(this.i);
}

@A(5)
class C {}
''');
    // First compute the resolved unit for the source.
    CompilationUnit unit = _resolveSource(source);
    // Compute the constant value of the annotation on C.
    EvaluationResultImpl evaluationResult =
        computeClassAnnotation(source, unit, 'C');
    // And check that it has no value stored in it.
    expect(evaluationResult, isNotNull);
    expect(evaluationResult.value, isNull);
  }

  test_annotation_with_args() {
    Source source = newSource(
        '/test.dart',
        '''
const x = 1;
@D(x) class C {}
class D {
  const D(this.value);
  final value;
}
''');
    // First compute the resolved unit for the source.
    CompilationUnit unit = _resolveSource(source);
    // Compute the constant value of the annotation on C.
    EvaluationResultImpl evaluationResult =
        computeClassAnnotation(source, unit, 'C');
    // And check that it has the expected value.
    expect(evaluationResult, isNotNull);
    expect(evaluationResult.value, isNotNull);
    expect(evaluationResult.value.type, isNotNull);
    expect(evaluationResult.value.type.name, 'D');
    expect(evaluationResult.value.fields, contains('value'));
    expect(evaluationResult.value.fields['value'].toIntValue(), 1);
  }

  test_annotation_without_args() {
    Source source = newSource(
        '/test.dart',
        '''
const x = 1;
@x class C {}
''');
    // First compute the resolved unit for the source.
    CompilationUnit unit = _resolveSource(source);
    // Compute the constant value of the annotation on C.
    EvaluationResultImpl evaluationResult =
        computeClassAnnotation(source, unit, 'C');
    // And check that it has the expected value.
    expect(evaluationResult, isNotNull);
    expect(evaluationResult.value, isNotNull);
    expect(evaluationResult.value.toIntValue(), 1);
  }

  test_circular_reference() {
    _checkCircularities(
        'x',
        ['y'],
        '''
const x = y + 1;
const y = x + 1;
''');
  }

  test_circular_reference_one_element() {
    // See dartbug.com/23490.
    _checkCircularities('x', [], 'const x = x;');
  }

  test_circular_reference_strongly_connected_component() {
    // When there is a circularity, all elements in the strongly connected
    // component should be marked as having an error.
    _checkCircularities(
        'a',
        ['b', 'c', 'd'],
        '''
const a = b;
const b = c + d;
const c = a;
const d = a;
''');
  }

  test_const_constructor_calls_implicit_super_constructor_implicitly() {
    // Note: the situation below is a compile-time error (since the synthetic
    // constructor for Base is non-const), but we need to handle it without
    // throwing an exception.
    EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
        'x',
        '''
class Base {}
class Derived extends Base {
  const Derived();
}
const x = const Derived();
''');
    expect(evaluationResult, isNotNull);
  }

  test_dependency() {
    EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
        'x',
        '''
const x = y + 1;
const y = 1;
''');
    expect(evaluationResult, isNotNull);
    expect(evaluationResult.value, isNotNull);
    expect(evaluationResult.value.toIntValue(), 2);
  }

  test_external_const_factory() {
    EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
        'x',
        '''
const x = const C.foo();

class C extends B {
  external const factory C.foo();
}

class B {}
''');
    expect(evaluationResult, isNotNull);
  }

  test_simple_constant() {
    EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
        'x',
        '''
const x = 1;
''');
    expect(evaluationResult, isNotNull);
    expect(evaluationResult.value, isNotNull);
    expect(evaluationResult.value.toIntValue(), 1);
  }

  void _checkCircularities(
      String variableName, List<String> otherVariables, String content) {
    // Evaluating the first constant should produce an error.
    CompilationUnit unit = _resolveUnit(content);
    _expectCircularityError(_evaluateConstant(unit, variableName));
    // And all the other constants involved in the strongly connected component
    // should be set to the same error state.
    for (String otherVariableName in otherVariables) {
      PropertyInducingElement otherVariableElement =
          AstFinder.getTopLevelVariableElement(unit, otherVariableName);
      _expectCircularityError(
          (otherVariableElement as TopLevelVariableElementImpl)
              .evaluationResult);
    }
  }

  EvaluationResultImpl _computeTopLevelVariableConstValue(
      String variableName, String content) {
    return _evaluateConstant(_resolveUnit(content), variableName);
  }

  EvaluationResultImpl _evaluateConstant(
      CompilationUnit unit, String variableName) {
    // Find the element for the given constant.
    PropertyInducingElement variableElement =
        AstFinder.getTopLevelVariableElement(unit, variableName);
    // Now compute the value of the constant.
    computeResult(variableElement, CONSTANT_VALUE,
        matcher: isComputeConstantValueTask);
    expect(outputs[CONSTANT_VALUE], same(variableElement));
    EvaluationResultImpl evaluationResult =
        (variableElement as TopLevelVariableElementImpl).evaluationResult;
    return evaluationResult;
  }

  void _expectCircularityError(EvaluationResultImpl evaluationResult) {
    expect(evaluationResult, isNotNull);
    expect(evaluationResult.value, isNull);
    expect(evaluationResult.errors, hasLength(1));
    expect(evaluationResult.errors[0].errorCode,
        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT);
  }

  CompilationUnit _resolveSource(Source source) {
    LibrarySpecificUnit librarySpecificUnit =
        new LibrarySpecificUnit(source, source);
    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
    CompilationUnit unit = outputs[RESOLVED_UNIT1];
    return unit;
  }

  CompilationUnit _resolveUnit(String content) =>
      _resolveSource(newSource('/test.dart', content));
}

@reflectiveTest
class ComputeInferableStaticVariableDependenciesTaskTest
    extends _AbstractDartTaskTest {
  @override
  void setUp() {
    super.setUp();
    // Variable dependencies are only available in strong mode.
    enableStrongMode();
  }

  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT7);
    expect(outputs[RESOLVED_UNIT7], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT7], isTrue);
  }

  test_perform() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
const a = b;
const b = 0;
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    TopLevelVariableElement elementA = unit.element.topLevelVariables[0];
    TopLevelVariableElement elementB = unit.element.topLevelVariables[1];

    computeResult(elementA, INFERABLE_STATIC_VARIABLE_DEPENDENCIES,
        matcher: isComputeInferableStaticVariableDependenciesTask);
    expect(outputs, hasLength(1));
    List<VariableElement> dependencies = outputs[
        INFERABLE_STATIC_VARIABLE_DEPENDENCIES] as List<VariableElement>;
    expect(dependencies, unorderedEquals([elementB]));
  }
}

@reflectiveTest
class ComputeLibraryCycleTaskTest extends _AbstractDartTaskTest {
  List<LibraryElement> getLibraryCycle(Map<ResultDescriptor, dynamic> outputs) {
    return outputs[LIBRARY_CYCLE] as List<LibraryElement>;
  }

  List<CompilationUnitElement> getLibraryCycleDependencies(
      Map<ResultDescriptor, dynamic> outputs) {
    return outputs[LIBRARY_CYCLE_DEPENDENCIES] as List<CompilationUnitElement>;
  }

  List<CompilationUnitElement> getLibraryCycleUnits(
      Map<ResultDescriptor, dynamic> outputs) {
    return outputs[LIBRARY_CYCLE_UNITS] as List<CompilationUnitElement>;
  }

  @override
  void setUp() {
    super.setUp();
    enableStrongMode();
  }

  void test_library_cycle_incremental() {
    enableStrongMode();
    Source lib1Source = newSource(
        '/my_lib1.dart',
        '''
library my_lib1;
''');
    Source lib2Source = newSource(
        '/my_lib2.dart',
        '''
library my_lib2;
import 'my_lib1.dart';
''');
    Source lib3Source = newSource(
        '/my_lib3.dart',
        '''
library my_lib3;
import 'my_lib2.dart';
''');
    AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
    AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
    AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);

    computeResult(lib1Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(1));
    computeResult(lib2Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(1));
    computeResult(lib3Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(1));

    // create a cycle
    context.setContents(
        lib1Source,
        '''
library my_lib1;
import 'my_lib3.dart';
''');
    _expectInvalid(lib1Target);
    _expectInvalid(lib2Target);
    _expectInvalid(lib3Target);

    computeResult(lib1Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(3));
    computeResult(lib2Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(3));
    computeResult(lib3Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(3));

    // break the cycle again
    context.setContents(
        lib1Source,
        '''
library my_lib1;
''');
    _expectInvalid(lib1Target);
    _expectInvalid(lib2Target);
    _expectInvalid(lib3Target);

    computeResult(lib1Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(1));
    computeResult(lib2Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(1));
    computeResult(lib3Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(1));
  }

  void test_library_cycle_incremental_partial() {
    enableStrongMode();
    Source lib1Source = newSource(
        '/my_lib1.dart',
        '''
library my_lib1;
''');
    Source lib2Source = newSource(
        '/my_lib2.dart',
        '''
library my_lib2;
import 'my_lib1.dart';
''');
    Source lib3Source = newSource(
        '/my_lib3.dart',
        '''
library my_lib3;
import 'my_lib2.dart';
''');
    AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
    AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
    AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);

    computeResult(lib1Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(1));
    computeResult(lib2Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(1));
    // lib3 is not reachable, so we have not yet computed its library
    // cycles

    // complete the cycle, via lib3
    context.setContents(
        lib1Source,
        '''
library my_lib1;
import 'my_lib3.dart';
''');
    _expectInvalid(lib1Target);
    _expectInvalid(lib2Target);
    _expectInvalid(lib3Target);

    // Ensure that invalidation correctly invalidated everything reachable
    // through lib3
    computeResult(lib1Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(3));
    computeResult(lib2Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(3));
    computeResult(lib3Target, LIBRARY_CYCLE);
    expect(outputs[LIBRARY_CYCLE], hasLength(3));
  }

  void test_library_cycle_linear() {
    List<Source> sources = newSources({
      '/a.dart': '''
''',
      '/b.dart': '''
import 'a.dart';
  '''
    });
    List<Map<ResultDescriptor, dynamic>> results =
        computeLibraryResultsMap(sources, LIBRARY_CYCLE);
    List<LibraryElement> component0 = getLibraryCycle(results[0]);
    List<LibraryElement> component1 = getLibraryCycle(results[1]);
    expect(component0, hasLength(1));
    expect(component1, hasLength(1));

    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results[0]);
    List<CompilationUnitElement> units1 = getLibraryCycleUnits(results[1]);
    expect(units0, hasLength(1));
    expect(units1, hasLength(1));

    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results[0]);
    List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results[1]);
    expect(dep0, hasLength(1)); // dart:core
    expect(dep1, hasLength(2)); // dart:core, a.dart
  }

  void test_library_cycle_loop() {
    List<Source> sources = newSources({
      '/a.dart': '''
  import 'c.dart';
''',
      '/b.dart': '''
  import 'a.dart';
  ''',
      '/c.dart': '''
  import 'b.dart';
  '''
    });
    List<Map<ResultDescriptor, dynamic>> results =
        computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
    List<LibraryElement> component0 = getLibraryCycle(results[0]);
    List<LibraryElement> component1 = getLibraryCycle(results[1]);
    List<LibraryElement> component2 = getLibraryCycle(results[2]);

    expect(component0, hasLength(3));
    expect(component1, hasLength(3));
    expect(component2, hasLength(3));

    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results[0]);
    List<CompilationUnitElement> units1 = getLibraryCycleUnits(results[1]);
    List<CompilationUnitElement> units2 = getLibraryCycleUnits(results[2]);
    expect(units0, hasLength(3));
    expect(units1, hasLength(3));
    expect(units2, hasLength(3));

    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results[0]);
    List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results[1]);
    List<CompilationUnitElement> dep2 = getLibraryCycleDependencies(results[2]);
    expect(dep0, hasLength(1)); // dart:core
    expect(dep1, hasLength(1)); // dart:core
    expect(dep2, hasLength(1)); // dart:core
  }

  void test_library_cycle_override_inference_incremental() {
    enableStrongMode();
    Source lib1Source = newSource(
        '/my_lib1.dart',
        '''
library my_lib1;
import 'my_lib3.dart';
''');
    Source lib2Source = newSource(
        '/my_lib2.dart',
        '''
library my_lib2;
import 'my_lib1.dart';
''');
    Source lib3Source = newSource(
        '/my_lib3.dart',
        '''
library my_lib3;
import 'my_lib2.dart';

class A {
  int foo(int x) => null;
}
class B extends A {
  foo(x) => null;
}
''');
    AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
    AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
    AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);

    computeResult(lib1Target, RESOLVED_UNIT);
    computeResult(lib2Target, RESOLVED_UNIT);
    computeResult(lib3Target, RESOLVED_UNIT);
    CompilationUnit unit = outputs[RESOLVED_UNIT];
    ClassElement b = unit.declarations[1].element;
    expect(b.getMethod('foo').returnType.toString(), 'int');

    // add a dummy edit.
    context.setContents(
        lib1Source,
        '''
library my_lib1;
import 'my_lib3.dart';
var foo = 123;
''');
    _expectInvalid(lib1Target);
    _expectInvalid(lib2Target);
    _expectInvalid(lib3Target);

    computeResult(lib1Target, RESOLVED_UNIT);
    computeResult(lib2Target, RESOLVED_UNIT);
    computeResult(lib3Target, RESOLVED_UNIT);
    unit = outputs[RESOLVED_UNIT];
    b = unit.declarations[1].element;
    expect(b.getMethod('foo').returnType.toString(), 'int',
        reason: 'edit should not affect member inference');
  }

  void test_library_cycle_self_loop() {
    List<Source> sources = newSources({
      '/a.dart': '''
  import 'a.dart';
'''
    });
    List<Map<ResultDescriptor, dynamic>> results =
        computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
    List<LibraryElement> component0 = getLibraryCycle(results[0]);
    expect(component0, hasLength(1));

    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results[0]);
    expect(units0, hasLength(1));

    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results[0]);
    expect(dep0, hasLength(1)); // dart:core
  }

  void test_library_cycle_singleton() {
    Source source = newSource(
        '/test.dart',
        '''
import 'dart:core';
''');
    computeResult(new LibrarySpecificUnit(source, source), LIBRARY_CYCLE);
    List<LibraryElement> component = getLibraryCycle(outputs);
    List<CompilationUnitElement> units = getLibraryCycleUnits(outputs);
    List<CompilationUnitElement> deps = getLibraryCycleDependencies(outputs);
    expect(component, hasLength(1));
    expect(units, hasLength(1));
    expect(deps, hasLength(1));
  }

  void test_library_cycle_tree() {
    List<Source> sources = newSources({
      '/a.dart': '''
''',
      '/b.dart': '''
  ''',
      '/c.dart': '''
  import 'a.dart';
  import 'b.dart';
  '''
    });
    List<Map<ResultDescriptor, dynamic>> results =
        computeLibraryResultsMap(sources, LIBRARY_CYCLE);
    List<LibraryElement> component0 = getLibraryCycle(results[0]);
    List<LibraryElement> component1 = getLibraryCycle(results[1]);
    List<LibraryElement> component2 = getLibraryCycle(results[2]);
    expect(component0, hasLength(1));
    expect(component1, hasLength(1));
    expect(component2, hasLength(1));

    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results[0]);
    List<CompilationUnitElement> units1 = getLibraryCycleUnits(results[1]);
    List<CompilationUnitElement> units2 = getLibraryCycleUnits(results[2]);
    expect(units0, hasLength(1));
    expect(units1, hasLength(1));
    expect(units2, hasLength(1));

    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results[0]);
    List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results[1]);
    List<CompilationUnitElement> dep2 = getLibraryCycleDependencies(results[2]);
    expect(dep0, hasLength(1)); // dart:core
    expect(dep1, hasLength(1)); // dart:core,
    expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart
  }

  void test_library_double_loop() {
    List<Source> sources = newSources({
      '/a.dart': '''
  import 'b.dart';
''',
      '/b.dart': '''
  import 'a.dart';
  ''',
      '/c.dart': '''
  import 'd.dart' as foo;
  import 'a.dart' as bar;
  export 'b.dart';
  ''',
      '/d.dart': '''
  import 'c.dart' as foo;
  import 'b.dart' as bar;
  export 'a.dart';
  '''
    });
    List<Map<ResultDescriptor, dynamic>> results =
        computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
    List<LibraryElement> component0 = getLibraryCycle(results[0]);
    List<LibraryElement> component1 = getLibraryCycle(results[1]);
    List<LibraryElement> component2 = getLibraryCycle(results[2]);
    List<LibraryElement> component3 = getLibraryCycle(results[3]);

    expect(component0, hasLength(2));
    expect(component1, hasLength(2));
    expect(component2, hasLength(2));
    expect(component3, hasLength(2));

    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results[0]);
    List<CompilationUnitElement> units1 = getLibraryCycleUnits(results[1]);
    List<CompilationUnitElement> units2 = getLibraryCycleUnits(results[2]);
    List<CompilationUnitElement> units3 = getLibraryCycleUnits(results[3]);
    expect(units0, hasLength(2));
    expect(units1, hasLength(2));
    expect(units2, hasLength(2));
    expect(units3, hasLength(2));

    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results[0]);
    List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results[1]);
    List<CompilationUnitElement> dep2 = getLibraryCycleDependencies(results[2]);
    List<CompilationUnitElement> dep3 = getLibraryCycleDependencies(results[3]);
    expect(dep0, hasLength(1)); // dart:core
    expect(dep1, hasLength(1)); // dart:core
    expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart
    expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart
  }

  void test_library_double_loop_parts() {
    List<Source> sources = newSources({
      '/a.dart': '''
  import 'b.dart';
  part 'aa.dart';
  part 'ab.dart';
''',
      '/b.dart': '''
  import 'a.dart';
''',
      '/aa.dart': '''
''',
      '/ab.dart': '''
''',
      '/c.dart': '''
  import 'd.dart' as foo;
  import 'a.dart' as bar;
  export 'b.dart';
''',
      '/d.dart': '''
  import 'c.dart' as foo;
  import 'b.dart' as bar;
  export 'a.dart';
  part 'da.dart';
  part 'db.dart';
''',
      '/da.dart': '''
''',
      '/db.dart': '''
'''
    });
    computeResult(
        new LibrarySpecificUnit(sources[0], sources[0]), LIBRARY_CYCLE);
    Map<ResultDescriptor, dynamic> results0 = outputs;
    computeResult(
        new LibrarySpecificUnit(sources[1], sources[1]), LIBRARY_CYCLE);
    Map<ResultDescriptor, dynamic> results1 = outputs;
    computeResult(
        new LibrarySpecificUnit(sources[0], sources[2]), LIBRARY_CYCLE);
    Map<ResultDescriptor, dynamic> results2 = outputs;
    computeResult(
        new LibrarySpecificUnit(sources[0], sources[3]), LIBRARY_CYCLE);
    Map<ResultDescriptor, dynamic> results3 = outputs;
    computeResult(
        new LibrarySpecificUnit(sources[4], sources[4]), LIBRARY_CYCLE);
    Map<ResultDescriptor, dynamic> results4 = outputs;
    computeResult(
        new LibrarySpecificUnit(sources[5], sources[5]), LIBRARY_CYCLE);
    Map<ResultDescriptor, dynamic> results5 = outputs;
    computeResult(
        new LibrarySpecificUnit(sources[5], sources[6]), LIBRARY_CYCLE);
    Map<ResultDescriptor, dynamic> results6 = outputs;
    computeResult(
        new LibrarySpecificUnit(sources[5], sources[7]), LIBRARY_CYCLE);
    Map<ResultDescriptor, dynamic> results7 = outputs;

    List<LibraryElement> component0 = getLibraryCycle(results0);
    List<LibraryElement> component1 = getLibraryCycle(results1);
    List<LibraryElement> component2 = getLibraryCycle(results2);
    List<LibraryElement> component3 = getLibraryCycle(results3);
    List<LibraryElement> component4 = getLibraryCycle(results4);
    List<LibraryElement> component5 = getLibraryCycle(results5);
    List<LibraryElement> component6 = getLibraryCycle(results6);
    List<LibraryElement> component7 = getLibraryCycle(results7);

    expect(component0, hasLength(2));
    expect(component1, hasLength(2));
    expect(component2, hasLength(2));
    expect(component3, hasLength(2));
    expect(component4, hasLength(2));
    expect(component5, hasLength(2));
    expect(component6, hasLength(2));
    expect(component7, hasLength(2));

    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results0);
    List<CompilationUnitElement> units1 = getLibraryCycleUnits(results1);
    List<CompilationUnitElement> units2 = getLibraryCycleUnits(results2);
    List<CompilationUnitElement> units3 = getLibraryCycleUnits(results3);
    List<CompilationUnitElement> units4 = getLibraryCycleUnits(results4);
    List<CompilationUnitElement> units5 = getLibraryCycleUnits(results5);
    List<CompilationUnitElement> units6 = getLibraryCycleUnits(results6);
    List<CompilationUnitElement> units7 = getLibraryCycleUnits(results7);
    expect(units0, hasLength(4));
    expect(units1, hasLength(4));
    expect(units2, hasLength(4));
    expect(units3, hasLength(4));
    expect(units4, hasLength(4));
    expect(units5, hasLength(4));
    expect(units6, hasLength(4));
    expect(units7, hasLength(4));

    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results0);
    List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results1);
    List<CompilationUnitElement> dep2 = getLibraryCycleDependencies(results2);
    List<CompilationUnitElement> dep3 = getLibraryCycleDependencies(results3);
    List<CompilationUnitElement> dep4 = getLibraryCycleDependencies(results4);
    List<CompilationUnitElement> dep5 = getLibraryCycleDependencies(results5);
    List<CompilationUnitElement> dep6 = getLibraryCycleDependencies(results6);
    List<CompilationUnitElement> dep7 = getLibraryCycleDependencies(results7);
    expect(dep0, hasLength(1)); // dart:core
    expect(dep1, hasLength(1)); // dart:core
    expect(dep2, hasLength(1)); // dart:core
    expect(dep3, hasLength(1)); // dart:core
    expect(dep4, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
    expect(dep5, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
    expect(dep6, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
    expect(dep7, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
  }

  void _expectInvalid(LibrarySpecificUnit target) {
    CacheEntry entry = context.getCacheEntry(target);
    expect(entry.getState(LIBRARY_CYCLE), CacheState.INVALID);
  }
}

@reflectiveTest
class ComputePropagableVariableDependenciesTaskTest
    extends _AbstractDartTaskTest {
  List<VariableElement> getPropagableVariableDependencies(
      Map<ResultDescriptor, dynamic> outputs) {
    return outputs[PROPAGABLE_VARIABLE_DEPENDENCIES] as List<VariableElement>;
  }

  test_perform_instanceField() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
class A {
  final a = a1 + a2 + a3 + a4 + B.b1 + B.b2 + B.b3 + B.b4;
  static const a1 = 1;
  final a2 = 2;
  final a3;
  var   a4 = 4;
}
class B {
  static const b1 = 1;
  static final b2 = 2;
  static final b3;
  static var   b4 = 4;
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    FieldElement elementA = AstFinder.getFieldInClassElement(unit, 'A', 'a');
    // compute
    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
        matcher: isComputePropagableVariableDependenciesTask);
    // verify
    expect(outputs, hasLength(1));
    List<VariableElement> dependencies =
        getPropagableVariableDependencies(outputs);
    expect(
        dependencies,
        unorderedEquals([
          AstFinder.getFieldInClassElement(unit, 'A', 'a1'),
          AstFinder.getFieldInClassElement(unit, 'A', 'a2'),
          AstFinder.getFieldInClassElement(unit, 'B', 'b1'),
          AstFinder.getFieldInClassElement(unit, 'B', 'b2')
        ]));
  }

  test_perform_topLevel() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
const a = d1 + d2 + d3 + d4;
const d1 = 1;
final d2 = 2;
final d3;
var   d4 = 4;
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    TopLevelVariableElement elementA =
        AstFinder.getTopLevelVariableElement(unit, 'a');
    // compute
    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
        matcher: isComputePropagableVariableDependenciesTask);
    // verify
    expect(outputs, hasLength(1));
    List<VariableElement> dependencies =
        getPropagableVariableDependencies(outputs);
    expect(
        dependencies,
        unorderedEquals([
          AstFinder.getTopLevelVariableElement(unit, 'd1'),
          AstFinder.getTopLevelVariableElement(unit, 'd2')
        ]));
  }

  test_perform_topLevel_ignoreLocal() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
final a = () {
  const b = 2;
  const c = 3;
  return b + c;
}() + d;
final d = 4;
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    TopLevelVariableElement elementA =
        AstFinder.getTopLevelVariableElement(unit, 'a');
    // compute
    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
        matcher: isComputePropagableVariableDependenciesTask);
    // verify
    expect(outputs, hasLength(1));
    List<VariableElement> dependencies =
        getPropagableVariableDependencies(outputs);
    expect(dependencies,
        unorderedEquals([AstFinder.getTopLevelVariableElement(unit, 'd')]));
  }

  test_perform_topLevel_withoutSpaceAfterType() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
const List<int>a=[b, c];
const b = 1;
const c = 2;
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    TopLevelVariableElement elementA =
        AstFinder.getTopLevelVariableElement(unit, 'a');
    // compute
    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
        matcher: isComputePropagableVariableDependenciesTask);
    // verify
    expect(outputs, hasLength(1));
    List<VariableElement> dependencies =
        getPropagableVariableDependencies(outputs);
    expect(
        dependencies,
        unorderedEquals([
          AstFinder.getTopLevelVariableElement(unit, 'b'),
          AstFinder.getTopLevelVariableElement(unit, 'c')
        ]));
  }
}

@reflectiveTest
class ContainingLibrariesTaskTest extends _AbstractDartTaskTest {
  List<Source> getContainingLibraries(Map<ResultDescriptor, dynamic> outputs) {
    return outputs[CONTAINING_LIBRARIES] as List<Source>;
  }

  test_perform_definingCompilationUnit() {
    AnalysisTarget library = newSource('/test.dart', 'library test;');
    computeResult(library, INCLUDED_PARTS);
    computeResult(library, CONTAINING_LIBRARIES,
        matcher: isContainingLibrariesTask);
    expect(outputs, hasLength(1));
    List<Source> containingLibraries = getContainingLibraries(outputs);
    expect(containingLibraries, unorderedEquals([library]));
  }

  test_perform_partInMultipleLibraries() {
    AnalysisTarget library1 =
        newSource('/lib1.dart', 'library test; part "part.dart";');
    AnalysisTarget library2 =
        newSource('/lib2.dart', 'library test; part "part.dart";');
    AnalysisTarget part = newSource('/part.dart', 'part of test;');
    computeResult(library1, INCLUDED_PARTS);
    computeResult(library2, INCLUDED_PARTS);
    computeResult(part, SOURCE_KIND);
    computeResult(part, CONTAINING_LIBRARIES,
        matcher: isContainingLibrariesTask);
    expect(outputs, hasLength(1));
    List<Source> containingLibraries = getContainingLibraries(outputs);
    expect(containingLibraries, unorderedEquals([library1, library2]));
  }

  test_perform_partInSingleLibrary() {
    AnalysisTarget library =
        newSource('/lib.dart', 'library test; part "part.dart";');
    AnalysisTarget part = newSource('/part.dart', 'part of test;');
    computeResult(library, INCLUDED_PARTS);
    computeResult(part, SOURCE_KIND);
    computeResult(part, CONTAINING_LIBRARIES,
        matcher: isContainingLibrariesTask);
    expect(outputs, hasLength(1));
    List<Source> containingLibraries = getContainingLibraries(outputs);
    expect(containingLibraries, unorderedEquals([library]));
  }
}

@reflectiveTest
class DartErrorsTaskTest extends _AbstractDartTaskTest {
  List<AnalysisError> getDartErrors(Map<ResultDescriptor, dynamic> outputs) {
    return outputs[DART_ERRORS] as List<AnalysisError>;
  }

  test_perform_definingCompilationUnit() {
    AnalysisTarget library =
        newSource('/test.dart', 'library test; import "dart:math";');
    computeResult(library, INCLUDED_PARTS);
    computeResult(library, DART_ERRORS, matcher: isDartErrorsTask);
    expect(outputs, hasLength(1));
    List<AnalysisError> errors = getDartErrors(outputs);
    expect(errors, hasLength(1));
  }

  test_perform_partInSingleLibrary() {
    AnalysisTarget library = newSource(
        '/lib.dart', 'library test; import "dart:math"; part "part.dart";');
    AnalysisTarget part =
        newSource('/part.dart', 'part of test; class A extends A {}');
    computeResult(library, INCLUDED_PARTS);
    computeResult(library, DART_ERRORS);
    computeResult(part, DART_ERRORS, matcher: isDartErrorsTask);
    expect(outputs, hasLength(1));
    List<AnalysisError> errors = getDartErrors(outputs);
    // This should contain only the errors in the part file, not the ones in the
    // library.
    expect(errors, hasLength(1));
  }
}

@reflectiveTest
class EvaluateUnitConstantsTaskTest extends _AbstractDartTaskTest {
  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT13);
    expect(outputs[RESOLVED_UNIT13], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT13], isTrue);
  }

  test_perform() {
    Source source = newSource(
        '/test.dart',
        '''
class C {
  const C();
}

@x
f() {}

const x = const C();
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT13,
        matcher: isEvaluateUnitConstantsTask);
    CompilationUnit unit = outputs[RESOLVED_UNIT13];
    CompilationUnitElement unitElement = unit.element;
    expect(
        (unitElement.types[0].constructors[0] as ConstructorElementImpl)
            .isCycleFree,
        isTrue);
    expect(
        (unitElement.functions[0].metadata[0] as ElementAnnotationImpl)
            .evaluationResult,
        isNotNull);
    expect(
        (unitElement.topLevelVariables[0] as TopLevelVariableElementImpl)
            .evaluationResult,
        isNotNull);
  }
}

@reflectiveTest
class GatherUsedImportedElementsTaskTest extends _AbstractDartTaskTest {
  UsedImportedElements usedElements;
  Set<String> usedElementNames;

  test_perform_inBody() {
    newSource(
        '/a.dart',
        r'''
library lib_a;
class A {}
''');
    newSource(
        '/b.dart',
        r'''
library lib_b;
class B {}
''');
    Source source = newSource(
        '/test.dart',
        r'''
import 'a.dart';
import 'b.dart';
main() {
  new A();
}''');
    _computeUsedElements(source);
    // validate
    expect(usedElementNames, unorderedEquals(['A']));
  }

  test_perform_inComment_exportDirective() {
    Source source = newSource(
        '/test.dart',
        r'''
import 'dart:async';
/// Use [Future].
export 'dart:math';
''');
    _computeUsedElements(source);
    expect(usedElementNames, unorderedEquals(['Future']));
  }

  test_perform_inComment_importDirective() {
    Source source = newSource(
        '/test.dart',
        r'''
import 'dart:async';
/// Use [Future].
import 'dart:math';
''');
    _computeUsedElements(source);
    expect(usedElementNames, unorderedEquals(['Future']));
  }

  test_perform_inComment_libraryDirective() {
    Source source = newSource(
        '/test.dart',
        r'''
/// Use [Future].
library test;
import 'dart:async';
''');
    _computeUsedElements(source);
    expect(usedElementNames, unorderedEquals(['Future']));
  }

  test_perform_inComment_topLevelFunction() {
    Source source = newSource(
        '/test.dart',
        r'''
import 'dart:async';
/// Use [Future].
main() {}
''');
    _computeUsedElements(source);
    expect(usedElementNames, unorderedEquals(['Future']));
  }

  void _computeUsedElements(Source source) {
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, USED_IMPORTED_ELEMENTS,
        matcher: isGatherUsedImportedElementsTask);
    usedElements = outputs[USED_IMPORTED_ELEMENTS];
    usedElementNames = usedElements.elements.map((e) => e.name).toSet();
  }
}

@reflectiveTest
class GatherUsedLocalElementsTaskTest extends _AbstractDartTaskTest {
  UsedLocalElements usedElements;
  Set<String> usedElementNames;

  test_perform_forPart_afterLibraryUpdate() {
    Source libSource = newSource(
        '/my_lib.dart',
        '''
library my_lib;
part 'my_part.dart';
foo() => null;
class _LocalClass {}
''');
    Source partSource = newSource(
        '/my_part.dart',
        '''
part of my_lib;
bar() {
  print(_LocalClass);
}
''');
    AnalysisTarget libTarget = new LibrarySpecificUnit(libSource, libSource);
    AnalysisTarget partTarget = new LibrarySpecificUnit(libSource, partSource);
    computeResult(libTarget, USED_LOCAL_ELEMENTS);
    computeResult(partTarget, USED_LOCAL_ELEMENTS);
    // _LocalClass is used in my_part.dart
    {
      UsedLocalElements usedElements =
          analysisCache.getValue(partTarget, USED_LOCAL_ELEMENTS);
      expect(usedElements.elements, contains(predicate((Element e) {
        return e.displayName == '_LocalClass';
      })));
    }
    // change my_lib.dart and recompute
    context.setContents(
        libSource,
        '''
library my_lib;
part 'my_part.dart';
String foo() => null;
class _LocalClass {}
''');
    computeResult(libTarget, USED_LOCAL_ELEMENTS);
    computeResult(partTarget, USED_LOCAL_ELEMENTS);
    // _LocalClass should still be used in my_part.dart
    {
      UsedLocalElements usedElements =
          analysisCache.getValue(partTarget, USED_LOCAL_ELEMENTS);
      expect(usedElements.elements, contains(predicate((Element e) {
        return e.displayName == '_LocalClass';
      })));
    }
  }

  test_perform_localVariable() {
    Source source = newSource(
        '/test.dart',
        r'''
main() {
  var v1 = 1;
  var v2 = 2;
  print(v2);
}''');
    _computeUsedElements(source);
    // validate
    expect(usedElementNames, unorderedEquals(['v2']));
  }

  test_perform_method() {
    Source source = newSource(
        '/test.dart',
        r'''
class A {
  _m1() {}
  _m2() {}
}

main(A a, p) {
  a._m2();
  p._m3();
}
''');
    _computeUsedElements(source);
    // validate
    expect(usedElementNames, unorderedEquals(['A', 'a', 'p', '_m2']));
    expect(usedElements.members, unorderedEquals(['_m2', '_m3']));
  }

  void _computeUsedElements(Source source) {
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, USED_LOCAL_ELEMENTS,
        matcher: isGatherUsedLocalElementsTask);
    usedElements = outputs[USED_LOCAL_ELEMENTS];
    usedElementNames = usedElements.elements.map((e) => e.name).toSet();
  }
}

@reflectiveTest
class GenerateHintsTaskTest extends _AbstractDartTaskTest {
  test_perform_bestPractices_missingReturn() {
    Source source = newSource(
        '/test.dart',
        '''
int main() {
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.MISSING_RETURN]);
  }

  test_perform_dart2js() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    options.dart2jsHint = true;
    prepareAnalysisContext(options);
    Source source = newSource(
        '/test.dart',
        '''
main(p) {
  if (p is double) {
    print('double');
  }
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.IS_DOUBLE]);
  }

  test_perform_deadCode() {
    Source source = newSource(
        '/test.dart',
        '''
main() {
  if (false) {
    print('how?');
  }
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.DEAD_CODE]);
  }

  test_perform_disabled() {
    context.analysisOptions =
        new AnalysisOptionsImpl.from(context.analysisOptions)..hint = false;
    Source source = newSource(
        '/test.dart',
        '''
int main() {
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertNoErrors();
  }

  test_perform_imports_duplicateImport() {
    newSource(
        '/a.dart',
        r'''
library lib_a;
class A {}
''');
    Source source = newSource(
        '/test.dart',
        r'''
import 'a.dart';
import 'a.dart';
main() {
  new A();
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.DUPLICATE_IMPORT]);
  }

  test_perform_imports_unusedImport_one() {
    newSource(
        '/a.dart',
        r'''
library lib_a;
class A {}
''');
    newSource(
        '/b.dart',
        r'''
library lib_b;
class B {}
''');
    Source source = newSource(
        '/test.dart',
        r'''
import 'a.dart';
import 'b.dart';
main() {
  new A();
}''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_IMPORT]);
  }

  test_perform_imports_unusedImport_zero() {
    newSource(
        '/a.dart',
        r'''
library lib_a;
class A {}
''');
    Source source = newSource(
        '/test.dart',
        r'''
import 'a.dart';
main() {
  new A();
}''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertNoErrors();
  }

  test_perform_overrideVerifier() {
    Source source = newSource(
        '/test.dart',
        '''
class A {}
class B {
  @override
  m() {}
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertErrorsWithCodes(
        <ErrorCode>[HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]);
  }

  test_perform_todo() {
    Source source = newSource(
        '/test.dart',
        '''
main() {
  // TODO(developer) foo bar
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[TodoCode.TODO]);
  }

  test_perform_unusedLocalElements_class() {
    Source source = newSource(
        '/test.dart',
        '''
class _A {}
class _B {}
main() {
  new _A();
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_ELEMENT]);
  }

  test_perform_unusedLocalElements_localVariable() {
    Source source = newSource(
        '/test.dart',
        '''
main() {
  var v = 42;
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener
        .assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_LOCAL_VARIABLE]);
  }

  test_perform_unusedLocalElements_method() {
    Source source = newSource(
        '/my_lib.dart',
        '''
library my_lib;
part 'my_part.dart';
class A {
  _ma() {}
  _mb() {}
  _mc() {}
}
''');
    newSource(
        '/my_part.dart',
        '''
part of my_lib;

f(A a) {
  a._mb();
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, HINTS, matcher: isGenerateHintsTask);
    // validate
    _fillErrorListener(HINTS);
    errorListener.assertErrorsWithCodes(
        <ErrorCode>[HintCode.UNUSED_ELEMENT, HintCode.UNUSED_ELEMENT]);
  }
}

@reflectiveTest
class GenerateLintsTaskTest extends _AbstractDartTaskTest {
  void enableLints() {
    AnalysisOptionsImpl options = context.analysisOptions;
    options.lint = true;
    context.analysisOptions = options;
  }

  @override
  void setUp() {
    super.setUp();
    enableLints();
    setLints(context, [new GenerateLintsTaskTest_TestLinter()]);
  }

  @override
  void tearDown() {
    setLints(context, []);
    super.tearDown();
  }

  test_camel_case_types() {
    Source source = newSource(
        '/test.dart',
        '''
class a { }
''');

    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, LINTS, matcher: isGenerateLintsTask);
    // validate
    _fillErrorListener(LINTS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[_testLintCode]);
  }
}

class GenerateLintsTaskTest_AstVisitor extends SimpleAstVisitor {
  Linter linter;
  GenerateLintsTaskTest_AstVisitor(this.linter);

  @override
  visitClassDeclaration(ClassDeclaration node) {
    if (!new RegExp(r'^([_]*)([A-Z]+[a-z0-9]*)+$')
        .hasMatch(node.name.toString())) {
      linter.reporter.reportErrorForNode(_testLintCode, node, []);
    }
  }
}

class GenerateLintsTaskTest_TestLinter extends Linter {
  @override
  String get name => 'GenerateLintsTaskTest_TestLinter';

  @override
  AstVisitor getVisitor() => new GenerateLintsTaskTest_AstVisitor(this);
}

@reflectiveTest
class InferInstanceMembersInUnitTaskTest extends _AbstractDartTaskTest {
  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT11);
    expect(outputs[RESOLVED_UNIT11], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
  }

  void test_perform() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
class A {
  X f;
  Y m(Z x) {}
}
class B extends A {
  var f;
  m(x) {}
}
class X {}
class Y {}
class Z {}
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
        matcher: isInferInstanceMembersInUnitTask);
    CompilationUnit unit = outputs[RESOLVED_UNIT11];
    VariableDeclaration field = AstFinder.getFieldInClass(unit, 'B', 'f');
    MethodDeclaration method = AstFinder.getMethodInClass(unit, 'B', 'm');
    DartType typeX = AstFinder.getClass(unit, 'X').element.type;
    DartType typeY = AstFinder.getClass(unit, 'Y').element.type;
    DartType typeZ = AstFinder.getClass(unit, 'Z').element.type;

    expect(field.element.type, typeX);
    expect(method.element.returnType, typeY);
    expect(method.element.parameters[0].type, typeZ);
  }

  void test_perform_cross_library_const() {
    enableStrongMode();
    AnalysisTarget firstSource = newSource(
        '/first.dart',
        '''
library first;

const a = 'hello';
''');
    AnalysisTarget secondSource = newSource(
        '/second.dart',
        '''
import 'first.dart';

const b = a;
class M {
   String c = a;
}
''');
    computeResult(
        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11,
        matcher: isInferInstanceMembersInUnitTask);
    CompilationUnit firstUnit = outputs[RESOLVED_UNIT11];
    computeResult(
        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
    CompilationUnit secondUnit = outputs[RESOLVED_UNIT11];

    VariableDeclaration variableA =
        AstFinder.getTopLevelVariable(firstUnit, 'a');
    VariableDeclaration variableB =
        AstFinder.getTopLevelVariable(secondUnit, 'b');
    VariableDeclaration variableC =
        AstFinder.getFieldInClass(secondUnit, 'M', 'c');
    InterfaceType stringType = context.typeProvider.stringType;

    expect(variableA.element.type, stringType);
    expect(variableB.element.type, stringType);
    expect(variableB.initializer.staticType, stringType);
    expect(variableC.element.type, stringType);
    expect(variableC.initializer.staticType, stringType);
  }

  void test_perform_reresolution() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
const topLevel = '';
class C {
  String field = topLevel;
}
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
    CompilationUnit unit = outputs[RESOLVED_UNIT11];
    VariableDeclaration topLevelDecl =
        AstFinder.getTopLevelVariable(unit, 'topLevel');
    VariableDeclaration fieldDecl =
        AstFinder.getFieldInClass(unit, 'C', 'field');
    VariableElement topLevel = topLevelDecl.name.staticElement;
    VariableElement field = fieldDecl.name.staticElement;

    InterfaceType stringType = context.typeProvider.stringType;
    expect(topLevel.type, stringType);
    expect(field.type, stringType);
    expect(fieldDecl.initializer.staticType, stringType);
  }
}

@reflectiveTest
class InferStaticVariableTypesInUnitTaskTest extends _AbstractDartTaskTest {
  @override
  void setUp() {
    super.setUp();
    enableStrongMode();
  }

  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT9);
    expect(outputs[RESOLVED_UNIT9], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
  }

  void test_perform_const_field() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
class M {
  static const X = "";
}
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
        matcher: isInferStaticVariableTypesInUnitTask);
    CompilationUnit unit = outputs[RESOLVED_UNIT9];
    VariableDeclaration declaration = AstFinder.getFieldInClass(unit, 'M', 'X');
    InterfaceType stringType = context.typeProvider.stringType;
    expect(declaration.element.type, stringType);
  }

  test_perform_hasParseError() {
    Source source = newSource(
        '/test.dart',
        r'''
@(i $=
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT9);
    expect(outputs[RESOLVED_UNIT9], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
  }

  void test_perform_nestedDeclarations() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
var f = (int x) {
  int squared(int value) => value * value;
  var xSquared = squared(x);
  return xSquared;
};
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
        matcher: isInferStaticVariableTypesInUnitTask);
  }

  void test_perform_recursive() {
    enableStrongMode();
    AnalysisTarget firstSource = newSource(
        '/first.dart',
        '''
import 'second.dart';

var a = new M();
var c = b;
''');
    AnalysisTarget secondSource = newSource(
        '/second.dart',
        '''
import 'first.dart';

var b = a;
class M {}
''');
    computeResult(
        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9,
        matcher: isInferStaticVariableTypesInUnitTask);
    CompilationUnit firstUnit = outputs[RESOLVED_UNIT9];
    computeResult(
        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9);
    CompilationUnit secondUnit = outputs[RESOLVED_UNIT9];

    VariableDeclaration variableA =
        AstFinder.getTopLevelVariable(firstUnit, 'a');
    VariableDeclaration variableB =
        AstFinder.getTopLevelVariable(secondUnit, 'b');
    VariableDeclaration variableC =
        AstFinder.getTopLevelVariable(firstUnit, 'c');
    ClassDeclaration classM = AstFinder.getClass(secondUnit, 'M');
    DartType typeM = classM.element.type;

    expect(variableA.element.type, typeM);
    expect(variableB.element.type, typeM);
    expect(variableB.initializer.staticType, typeM);
    expect(variableC.element.type, typeM);
    expect(variableC.initializer.staticType, typeM);
  }

  void test_perform_simple() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
var X = 1;

var Y = () {
  return 1 + X;
};
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
        matcher: isInferStaticVariableTypesInUnitTask);
    CompilationUnit unit = outputs[RESOLVED_UNIT9];
    TopLevelVariableDeclaration declaration = unit.declarations[1];
    FunctionExpression function =
        declaration.variables.variables[0].initializer;
    BlockFunctionBody body = function.body;
    ReturnStatement statement = body.block.statements[0];
    Expression expression = statement.expression;
    InterfaceType intType = context.typeProvider.intType;
    expect(expression.staticType, intType);
  }
}

@reflectiveTest
class InferStaticVariableTypeTaskTest extends _AbstractDartTaskTest {
  void test_getDeclaration_staticField() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
class C {
  var field = '';
}
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    VariableDeclaration declaration =
        AstFinder.getFieldInClass(unit, 'C', 'field');
    VariableElement variable = declaration.name.staticElement;
    InferStaticVariableTypeTask inferTask =
        new InferStaticVariableTypeTask(task.context, variable);
    expect(inferTask.getDeclaration(unit), declaration);
  }

  void test_getDeclaration_topLevel() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
var topLevel = '';
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    VariableDeclaration declaration =
        AstFinder.getTopLevelVariable(unit, 'topLevel');
    VariableElement variable = declaration.name.staticElement;
    InferStaticVariableTypeTask inferTask =
        new InferStaticVariableTypeTask(task.context, variable);
    expect(inferTask.getDeclaration(unit), declaration);
  }

  void test_perform() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test3.dart',
        '''
var topLevel3 = '';
class C {
  var field3 = topLevel3;
}
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    VariableDeclaration topLevelDecl =
        AstFinder.getTopLevelVariable(unit, 'topLevel3');
    VariableDeclaration fieldDecl =
        AstFinder.getFieldInClass(unit, 'C', 'field3');
    VariableElement topLevel = topLevelDecl.name.staticElement;
    VariableElement field = fieldDecl.name.staticElement;

    computeResult(field, INFERRED_STATIC_VARIABLE,
        matcher: isInferStaticVariableTypeTask);
    InterfaceType stringType = context.typeProvider.stringType;
    expect(topLevel.type, stringType);
    expect(field.type, stringType);
    expect(fieldDecl.initializer.staticType, stringType);
  }

  void test_perform_const() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
const topLevel = "hello";
class C {
  var field = topLevel;
}
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    VariableElement topLevel =
        AstFinder.getTopLevelVariable(unit, 'topLevel').name.staticElement;
    VariableElement field =
        AstFinder.getFieldInClass(unit, 'C', 'field').name.staticElement;

    computeResult(field, INFERRED_STATIC_VARIABLE,
        matcher: isInferStaticVariableTypeTask);
    InterfaceType stringType = context.typeProvider.stringType;
    expect(topLevel.type, stringType);
    expect(field.type, stringType);
  }

  void test_perform_cycle() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
var piFirst = true;
var pi = piFirst ? 3.14 : tau / 2;
var tau = piFirst ? pi * 2 : 6.28;
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    VariableElement piFirst =
        AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
    VariableElement pi =
        AstFinder.getTopLevelVariable(unit, 'pi').name.staticElement;
    VariableElement tau =
        AstFinder.getTopLevelVariable(unit, 'tau').name.staticElement;

    computeResult(piFirst, INFERRED_STATIC_VARIABLE,
        matcher: isInferStaticVariableTypeTask);
    expect(piFirst.type, context.typeProvider.boolType);
    expect(pi.type.isDynamic, isTrue);
    expect(tau.type.isDynamic, isTrue);
  }

  void test_perform_error() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
var a = '' / null;
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    VariableElement a =
        AstFinder.getTopLevelVariable(unit, 'a').name.staticElement;

    computeResult(a, INFERRED_STATIC_VARIABLE,
        matcher: isInferStaticVariableTypeTask);
    expect(a.type.isDynamic, isTrue);
  }

  void test_perform_null() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
var a = null;
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    VariableElement a =
        AstFinder.getTopLevelVariable(unit, 'a').name.staticElement;

    computeResult(a, INFERRED_STATIC_VARIABLE,
        matcher: isInferStaticVariableTypeTask);
    expect(a.type.isDynamic, isTrue);
  }
}

@reflectiveTest
class LibraryErrorsReadyTaskTest extends _AbstractDartTaskTest {
  test_perform() {
    Source library = newSource(
        '/lib.dart',
        r'''
library lib;
part 'part1.dart';
part 'part2.dart';
X v1;
''');
    Source part1 = newSource(
        '/part1.dart',
        r'''
part of lib;
X v2;
''');
    Source part2 = newSource(
        '/part2.dart',
        r'''
part of lib;
X v3;
''');
    computeResult(library, LIBRARY_ERRORS_READY,
        matcher: isLibraryErrorsReadyTask);
    expect(outputs, hasLength(1));
    bool ready = outputs[LIBRARY_ERRORS_READY];
    expect(ready, isTrue);
    expect(context.getErrors(library).errors, hasLength(1));
    expect(context.getErrors(part1).errors, hasLength(1));
    expect(context.getErrors(part2).errors, hasLength(1));
  }
}

@reflectiveTest
class LibraryUnitErrorsTaskTest extends _AbstractDartTaskTest {
  List<AnalysisError> getLibraryUnitErrors(
      Map<ResultDescriptor, dynamic> outputs) {
    return outputs[LIBRARY_UNIT_ERRORS] as List<AnalysisError>;
  }

  test_perform_definingCompilationUnit() {
    AnalysisTarget library =
        newSource('/test.dart', 'library test; import "dart:math";');
    computeResult(
        new LibrarySpecificUnit(library, library), LIBRARY_UNIT_ERRORS,
        matcher: isLibraryUnitErrorsTask);
    expect(outputs, hasLength(1));
    List<AnalysisError> errors = getLibraryUnitErrors(outputs);
    expect(errors, hasLength(1));
  }

  test_perform_partInSingleLibrary() {
    AnalysisTarget library =
        newSource('/lib.dart', 'library test; part "part.dart";');
    AnalysisTarget part = newSource('/part.dart', 'part of test;');
    computeResult(new LibrarySpecificUnit(library, part), LIBRARY_UNIT_ERRORS,
        matcher: isLibraryUnitErrorsTask);
    expect(outputs, hasLength(1));
    List<AnalysisError> errors = getLibraryUnitErrors(outputs);
    expect(errors, hasLength(0));
  }
}

@reflectiveTest
class ParseDartTaskTest extends _AbstractDartTaskTest {
  Source source;

  test_perform() {
    _performParseTask(r'''
part of lib;
class B {}''');
    expect(outputs, hasLength(10));
    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
    _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
    expect(outputs[INCLUDED_PARTS], hasLength(0));
    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
    expect(outputs[PARSE_ERRORS], hasLength(0));
    expect(outputs[PARSED_UNIT], isNotNull);
    expect(outputs[SOURCE_KIND], SourceKind.PART);
    expect(outputs[UNITS], hasLength(1));
    expect(outputs[REFERENCED_SOURCES], hasLength(2));
  }

  test_perform_computeSourceKind_noDirectives_hasContainingLibrary() {
    // Parse "lib.dart" to let the context know that "test.dart" is included.
    computeResult(
        newSource(
            '/lib.dart',
            r'''
library lib;
part 'test.dart';
'''),
        PARSED_UNIT);
    // If there are no the "part of" directive, then it is not a part.
    _performParseTask('');
    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
  }

  test_perform_computeSourceKind_noDirectives_noContainingLibrary() {
    _performParseTask('');
    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
  }

  test_perform_doesNotExist() {
    _performParseTask(null);
    expect(outputs, hasLength(10));
    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
    _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
    expect(outputs[INCLUDED_PARTS], hasLength(0));
    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
    expect(outputs[PARSE_ERRORS], hasLength(0));
    expect(outputs[PARSED_UNIT], isNotNull);
    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
    expect(outputs[UNITS], hasLength(1));
    expect(outputs[REFERENCED_SOURCES], hasLength(2));
  }

  test_perform_enableAsync_false() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    options.enableAsync = false;
    prepareAnalysisContext(options);
    _performParseTask(r'''
import 'dart:async';
class B {void foo() async {}}''');
    expect(outputs, hasLength(10));
    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
    expect(outputs[INCLUDED_PARTS], hasLength(0));
    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
    expect(outputs[PARSE_ERRORS], hasLength(1));
    expect(outputs[PARSED_UNIT], isNotNull);
    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
    expect(outputs[UNITS], hasLength(1));
    expect(outputs[REFERENCED_SOURCES], hasLength(3));
  }

  test_perform_enableAsync_true() {
    _performParseTask(r'''
import 'dart:async';
class B {void foo() async {}}''');
    expect(outputs, hasLength(10));
    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
    expect(outputs[INCLUDED_PARTS], hasLength(0));
    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
    expect(outputs[PARSE_ERRORS], hasLength(0));
    expect(outputs[PARSED_UNIT], isNotNull);
    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
    expect(outputs[UNITS], hasLength(1));
    expect(outputs[REFERENCED_SOURCES], hasLength(3));
  }

  test_perform_flushTokenStream() {
    _performParseTask(r'''
class Test {}
''');
    expect(analysisCache.getState(source, TOKEN_STREAM), CacheState.FLUSHED);
  }

  test_perform_invalidDirectives() {
    _performParseTask(r'''
library lib;
import '/does/not/exist.dart';
import '://invaliduri.dart';
export '${a}lib3.dart';
part 'part.dart';
class A {}''');
    expect(outputs, hasLength(10));
    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
    expect(outputs[INCLUDED_PARTS], hasLength(1));
    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(2));
    expect(outputs[PARSE_ERRORS], hasLength(2));
    expect(outputs[PARSED_UNIT], isNotNull);
    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
    expect(outputs[UNITS], hasLength(2));
    expect(outputs[REFERENCED_SOURCES], hasLength(4));
  }

  test_perform_library() {
    _performParseTask(r'''
library lib;
import 'lib2.dart';
export 'lib3.dart';
part 'part.dart';
class A {''');
    expect(outputs, hasLength(10));
    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
    expect(outputs[EXPORTED_LIBRARIES], hasLength(1));
    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
    expect(outputs[INCLUDED_PARTS], hasLength(1));
    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(2));
    expect(outputs[PARSE_ERRORS], hasLength(1));
    expect(outputs[PARSED_UNIT], isNotNull);
    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
    expect(outputs[UNITS], hasLength(2));
    expect(outputs[REFERENCED_SOURCES], hasLength(5));
  }

  test_perform_library_selfReferenceAsPart() {
    _performParseTask(r'''
library lib;
part 'test.dart';
''');
    expect(outputs[INCLUDED_PARTS], unorderedEquals(<Source>[source]));
  }

  test_perform_part() {
    _performParseTask(r'''
part of lib;
class B {}''');
    expect(outputs, hasLength(10));
    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
    _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
    expect(outputs[INCLUDED_PARTS], hasLength(0));
    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
    expect(outputs[PARSE_ERRORS], hasLength(0));
    expect(outputs[PARSED_UNIT], isNotNull);
    expect(outputs[SOURCE_KIND], SourceKind.PART);
    expect(outputs[UNITS], hasLength(1));
    expect(outputs[REFERENCED_SOURCES], hasLength(2));
  }

  void _performParseTask(String content) {
    if (content == null) {
      source = resourceProvider.getFile('/test.dart').createSource();
    } else {
      source = newSource('/test.dart', content);
    }
    computeResult(source, PARSED_UNIT, matcher: isParseDartTask);
  }

  static void _assertHasCore(dynamic sourceList, int lenght) {
    List<Source> sources = sourceList as List<Source>;
    expect(sources, hasLength(lenght));
    expect(sources, contains(predicate((Source s) {
      return s.fullName.endsWith('core.dart');
    })));
  }
}

@reflectiveTest
class PartiallyResolveUnitReferencesTaskTest extends _AbstractDartTaskTest {
  test_perform_propagable() {
    enableStrongMode();
    Source source = newSource(
        '/test.dart',
        '''
const t1 = 1;
final t2 = 2;
var   t3 = 3;
final t4;
class C {
  static const fs1 = 1;
  static final fs2 = 2;
  static var   fs3 = 3;
  static final fs4;
  const fi1 = 1;
  final fi2 = 2;
  var   fi3 = 3;
  final fi4;
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, PROPAGABLE_VARIABLES_IN_UNIT,
        matcher: isPartiallyResolveUnitReferencesTask);
    // PROPAGABLE_VARIABLES_IN_UNIT
    List<VariableElement> variables =
        outputs[PROPAGABLE_VARIABLES_IN_UNIT] as List<VariableElement>;
    expect(variables.map((v) => v.displayName),
        unorderedEquals(['t1', 't2', 'fs1', 'fs2', 'fi1', 'fi2']));
  }

  test_perform_strong_importExport() {
    newSource(
        '/a.dart',
        '''
library a;
class A<T> {
  T m() {}
}
''');
    newSource(
        '/b.dart',
        '''
library b;
export 'a.dart';
''');
    Source sourceC = newSource(
        '/c.dart',
        '''
library c;
import 'b.dart';
main() {
  new A<int>().m();
}
''');
    computeResult(new LibrarySpecificUnit(sourceC, sourceC), RESOLVED_UNIT7,
        matcher: isPartiallyResolveUnitReferencesTask);
    // validate
    expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(0));
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    expect(unit, isNotNull);

    FunctionDeclaration mainFunction = unit.declarations[0];
    expect(mainFunction.element, isNotNull);
    BlockFunctionBody body = mainFunction.functionExpression.body;
    List<Statement> statements = body.block.statements;
    ExpressionStatement statement = statements[0];
    MethodInvocation invocation = statement.expression;
    MethodElement methodElement = invocation.methodName.staticElement;
    expect(methodElement, isNull);
  }

  test_perform_strong_inferable() {
    enableStrongMode();
    Source source = newSource(
        '/test.dart',
        '''
int a = b;
int b = c;
var d = 0;
class A {}
class C {
  static final f = '';
  var g = 0;
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT7,
        matcher: isPartiallyResolveUnitReferencesTask);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    // INFERABLE_STATIC_VARIABLES_IN_UNIT
    {
      List<VariableElement> variables =
          outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] as List<VariableElement>;
      expect(variables, hasLength(4));
      expect(variables.map((v) => v.displayName),
          unorderedEquals(['a', 'b', 'd', 'f']));
    }
    // Test the state of the AST
    TopLevelVariableDeclaration a = unit.declarations[0];
    VariableDeclaration variableA = a.variables.variables[0];
    SimpleIdentifier initializer = variableA.initializer;
    expect(initializer.staticElement, isNotNull);
  }

  test_perform_strong_notResolved() {
    enableStrongMode();
    Source source = newSource(
        '/test.dart',
        '''
int A;
f1() {
  A;
}
var f2 = () {
  A;
  void f3() {
    A;
  }
}
class C {
  C() {
    A;
  }
  m() {
    A;
  }
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT7,
        matcher: isPartiallyResolveUnitReferencesTask);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    NodeList<CompilationUnitMember> declarations = unit.declarations;

    void expectReference(BlockFunctionBody body, bool isResolved) {
      ExpressionStatement statement = body.block.statements[0];
      SimpleIdentifier reference = statement.expression;
      expect(reference.staticElement, isResolved ? isNotNull : isNull);
    }
    //
    // The reference to 'A' in 'f1' should not be resolved.
    //
    FunctionDeclaration f1 = declarations[1];
    expectReference(f1.functionExpression.body, false);
    //
    // The references to 'A' in 'f2' should be resolved.
    //
    TopLevelVariableDeclaration f2 = declarations[2];
    FunctionExpression expression2 = f2.variables.variables[0].initializer;
    BlockFunctionBody body2 = expression2.body;
    expectReference(body2, true);

    FunctionDeclarationStatement statement2 = body2.block.statements[1];
    BlockFunctionBody innerBody =
        statement2.functionDeclaration.functionExpression.body;
    expectReference(innerBody, true);
    //
    // The references to 'A' in 'C' should not be resolved.
    //
    ClassDeclaration c = declarations[3];
    NodeList<ClassMember> members = c.members;

    ConstructorDeclaration constructor = members[0];
    expectReference(constructor.body, false);

    MethodDeclaration method = members[1];
    expectReference(method.body, false);
  }
}

@reflectiveTest
class PropagateVariableTypesInUnitTaskTest extends _AbstractDartTaskTest {
  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT8);
    expect(outputs[RESOLVED_UNIT8], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
  }

  void test_perform_cycle() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
final piFirst = true;
final pi = piFirst ? 3.14 : tau / 2;
final tau = piFirst ? pi * 2 : 6.28;
''');
    // compute
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
        matcher: isPropagateVariableTypesInUnitTask);
    CompilationUnit unit = outputs[RESOLVED_UNIT8];
    // verify
    TopLevelVariableElement piFirst =
        AstFinder.getTopLevelVariableElement(unit, 'piFirst');
    TopLevelVariableElement pi =
        AstFinder.getTopLevelVariableElement(unit, 'pi');
    TopLevelVariableElement tau =
        AstFinder.getTopLevelVariableElement(unit, 'tau');
    expect(piFirst.propagatedType, context.typeProvider.boolType);
    expect(pi.propagatedType, isNull);
    expect(tau.propagatedType, isNull);
  }

  void test_perform_topLevel() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
//final a = b + c.length;
final a = b;
final b = 1;
final c = '2';
''');
    // compute
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
        matcher: isPropagateVariableTypesInUnitTask);
    CompilationUnit unit = outputs[RESOLVED_UNIT8];
    // verify
    InterfaceType intType = context.typeProvider.intType;
    InterfaceType stringType = context.typeProvider.stringType;
    expect(AstFinder.getTopLevelVariableElement(unit, 'a').propagatedType,
        intType);
    expect(AstFinder.getTopLevelVariableElement(unit, 'b').propagatedType,
        intType);
    expect(AstFinder.getTopLevelVariableElement(unit, 'c').propagatedType,
        stringType);
  }
}

@reflectiveTest
class PropagateVariableTypeTaskTest extends _AbstractDartTaskTest {
  void test_perform_cycle() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
final piFirst = true;
final pi = piFirst ? 3.14 : tau / 2;
final tau = piFirst ? pi * 2 : 6.28;
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    TopLevelVariableElement piFirst =
        AstFinder.getTopLevelVariableElement(unit, 'piFirst');
    TopLevelVariableElement pi =
        AstFinder.getTopLevelVariableElement(unit, 'pi');
    TopLevelVariableElement tau =
        AstFinder.getTopLevelVariableElement(unit, 'tau');
    // compute
    computeResult(piFirst, PROPAGATED_VARIABLE,
        matcher: isPropagateVariableTypeTask);
    expect(piFirst.propagatedType, context.typeProvider.boolType);
    expect(pi.propagatedType, isNull);
    expect(tau.propagatedType, isNull);
  }

  void test_perform_null() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
var a = null;
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    TopLevelVariableElement a = AstFinder.getTopLevelVariableElement(unit, 'a');
    // compute
    computeResult(a, PROPAGATED_VARIABLE, matcher: isPropagateVariableTypeTask);
    expect(a.propagatedType, isNull);
  }

  void test_perform_topLevel() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
final a = b + c.length;
final b = 1;
final c = '2';
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
    CompilationUnit unit = outputs[RESOLVED_UNIT7];
    TopLevelVariableElement elementA =
        AstFinder.getTopLevelVariableElement(unit, 'a');
    TopLevelVariableElement elementB =
        AstFinder.getTopLevelVariableElement(unit, 'b');
    TopLevelVariableElement elementC =
        AstFinder.getTopLevelVariableElement(unit, 'c');
    // compute
    computeResult(elementA, PROPAGATED_VARIABLE,
        matcher: isPropagateVariableTypeTask);
    InterfaceType intType = context.typeProvider.intType;
    InterfaceType stringType = context.typeProvider.stringType;
    expect(elementA.propagatedType, intType);
    expect(elementB.propagatedType, intType);
    expect(elementC.propagatedType, stringType);
  }
}

@reflectiveTest
class ResolveDirectiveElementsTaskTest extends _AbstractDartTaskTest {
  test_perform() {
    List<Source> sources = newSources({
      '/libA.dart': '''
library libA;
import 'libB.dart';
export 'libC.dart';
''',
      '/libB.dart': '''
library libB;
''',
      '/libC.dart': '''
library libC;
'''
    });
    Source sourceA = sources[0];
    LibrarySpecificUnit targetA = new LibrarySpecificUnit(sourceA, sourceA);
    // build directive elements
    computeResult(sourceA, LIBRARY_ELEMENT2,
        matcher: isBuildDirectiveElementsTask);
    // prepare outputs
    LibraryElement libraryElementA = outputs[LIBRARY_ELEMENT2];
    LibraryElement libraryElementB = libraryElementA.imports[0].importedLibrary;
    LibraryElement libraryElementC = libraryElementA.exports[0].exportedLibrary;
    // clear elements in directive ASTs
    {
      CompilationUnit unitA = context.getResult(targetA, RESOLVED_UNIT1);
      unitA.directives[1].element = null;
      unitA.directives[2].element = null;
    }
    // resolve directive ASTs
    computeResult(targetA, RESOLVED_UNIT2,
        matcher: isResolveDirectiveElementsTask);
    // validate that directive ASTs have elements
    CompilationUnit unitA = context.getResult(targetA, RESOLVED_UNIT2);
    {
      ImportDirective importNode = unitA.directives[1];
      ImportElement importElement = importNode.element;
      expect(importElement, isNotNull);
      expect(importElement.importedLibrary, libraryElementB);
    }
    {
      ExportDirective exportNode = unitA.directives[2];
      ExportElement exportElement = exportNode.element;
      expect(exportElement, isNotNull);
      expect(exportElement.exportedLibrary, libraryElementC);
    }
  }
}

@reflectiveTest
class ResolveInstanceFieldsInUnitTaskTest extends _AbstractDartTaskTest {
  @override
  void setUp() {
    super.setUp();
    enableStrongMode();
  }

  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT10);
    expect(outputs[RESOLVED_UNIT10], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
  }

  // Test inference of instance fields across units
  void test_perform_inference_cross_unit_instance() {
    List<Source> sources = newSources({
      '/a.dart': '''
          import 'b.dart';
          class A {
            final a2 = new B().b2;
          }
      ''',
      '/b.dart': '''
          class B {
            final b2 = 1;
          }
      ''',
      '/main.dart': '''
          import "a.dart";

          test1() {
            int x = 0;
            x = new A().a2;
          }
    '''
    });
    InterfaceType intType = context.typeProvider.intType;
    DartType dynamicType = context.typeProvider.dynamicType;

    computeResult(
        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
    CompilationUnit unit1 = outputs[RESOLVED_UNIT10];

    // B.b2 shoud be resolved on the rhs, but not yet inferred.
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);

    computeResult(
        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
    CompilationUnit unit0 = outputs[RESOLVED_UNIT10];

    // B.b2 should now be fully resolved and inferred.
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);

    // A.a2 should now be resolved on the rhs, but not yet inferred.
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, intType);

    computeResult(
        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);

    // A.a2 should now be fully resolved and inferred.
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
  }

  // Test inference of instance fields across units
  void test_perform_inference_cross_unit_instance_cyclic() {
    List<Source> sources = newSources({
      '/a.dart': '''
          import 'b.dart';
          class A {
            final a2 = new B().b2;
          }
      ''',
      '/b.dart': '''
          import 'a.dart';
          class B {
            final b2 = 1;
          }
      ''',
      '/main.dart': '''
          import "a.dart";

          test1() {
            int x = 0;
            x = new A().a2;
          }
    '''
    });
    DartType dynamicType = context.typeProvider.dynamicType;

    computeResult(
        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
    CompilationUnit unit0 = outputs[RESOLVED_UNIT10];

    // A.a2 should now be resolved on the rhs, but not yet inferred.
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);

    computeResult(
        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);

    // A.a2 should now be fully resolved and inferred (but not re-resolved).
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
  }

  // Test inference of instance fields across units with cycles
  void test_perform_inference_cross_unit_static_instance() {
    List<Source> sources = newSources({
      '/a.dart': '''
          import 'b.dart';
          class A {
            static final a1 = B.b1;
            final a2 = new B().b2;
          }
      ''',
      '/b.dart': '''
          class B {
            static final b1 = 1;
            final b2 = 1;
          }
      ''',
      '/main.dart': '''
          import "a.dart";

          test1() {
            int x = 0;
            // inference in A now works.
            x = A.a1;
            x = new A().a2;
          }
    '''
    });
    InterfaceType intType = context.typeProvider.intType;
    DartType dynamicType = context.typeProvider.dynamicType;

    computeResult(
        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
    CompilationUnit unit1 = outputs[RESOLVED_UNIT10];

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);

    computeResult(
        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
    CompilationUnit unit0 = outputs[RESOLVED_UNIT10];

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, intType);

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);

    computeResult(
        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
  }

  // Test inference between static and instance fields
  void test_perform_inference_instance() {
    List<Source> sources = newSources({
      '/a.dart': '''
          import 'b.dart';
          class A {
            final a2 = new B().b2;
          }

          class B {
            final b2 = 1;
          }
      ''',
      '/main.dart': '''
          import "a.dart";

          test1() {
            int x = 0;
            x = new A().a2;
          }
    '''
    });
    InterfaceType intType = context.typeProvider.intType;
    DartType dynamicType = context.typeProvider.dynamicType;

    computeResult(
        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
    CompilationUnit unit0 = outputs[RESOLVED_UNIT10];

    // A.a2 should now be resolved on the rhs, but not yet inferred.
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);

    // B.b2 shoud be resolved on the rhs, but not yet inferred.
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "B", "b2"), dynamicType, intType);

    computeResult(
        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);

    // A.a2 should now be fully resolved and inferred (but not re-resolved).
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);

    // B.b2 should now be fully resolved and inferred.
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "B", "b2"), intType, intType);
  }
}

@reflectiveTest
class ResolveLibraryReferencesTaskTest extends _AbstractDartTaskTest {
  void setUp() {
    super.setUp();
    context.analysisOptions = new AnalysisOptionsImpl()
      ..enableGenericMethods = true
      ..strongMode = true;
  }

  test_referencedNames_class_constructor() {
    ReferencedNames info = _computeReferencedNames('''
class U {
  U.named(A a, B b) {
    C c = null;
  }
}
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
  }

  test_referencedNames_class_field() {
    ReferencedNames info = _computeReferencedNames('''
class U {
  A f = new B();
}
''');
    expect(info.names, unorderedEquals(['A', 'B']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
  }

  test_referencedNames_class_getter() {
    ReferencedNames info = _computeReferencedNames('''
class U {
  A get a => new B();
}
''');
    expect(info.names, unorderedEquals(['A', 'B']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A']));
  }

  test_referencedNames_class_members() {
    ReferencedNames info = _computeReferencedNames('''
class U {
  int a;
  int get b;
  set c(_) {}
  m(D d) {
    a;
    b;
    c = 1;
    m();
  }
}
''');
    expect(info.names, unorderedEquals(['int', 'D']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['int', 'D']));
  }

  test_referencedNames_class_members_dontHideQualified() {
    ReferencedNames info = _computeReferencedNames('''
class U {
  int a;
  int get b;
  set c(_) {}
  m(D d) {
    d.a;
    d.b;
    d.c;
  }
}
''');
    expect(info.names, unorderedEquals(['int', 'D', 'a', 'b', 'c']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['int', 'D']));
  }

  test_referencedNames_class_method() {
    ReferencedNames info = _computeReferencedNames('''
class U {
  A m(B p) {
    C v = 0;
  }
}
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
  }

  test_referencedNames_class_method_localVariables() {
    ReferencedNames info = _computeReferencedNames('''
class U {
  A m() {
    B b = null;
    b;
    {
      C c = null;
      b;
      c;
    }
    d;
  }
}
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C', 'd']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A']));
  }

  test_referencedNames_class_method_parameters() {
    ReferencedNames info = _computeReferencedNames('''
class U {
  m(A a) {
    a;
    b;
  }
}
''');
    expect(info.names, unorderedEquals(['A', 'b']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A']));
  }

  test_referencedNames_class_method_typeParameters() {
    ReferencedNames info = _computeReferencedNames('''
class U {
  A m<T>(B b, T t) {
    C c = 0;
  }
}
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
  }

  test_referencedNames_class_setter() {
    ReferencedNames info = _computeReferencedNames('''
class U {
  set a(A a) {
    B b = null;
  }
}
''');
    expect(info.names, unorderedEquals(['A', 'B']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A']));
  }

  test_referencedNames_class_typeParameters() {
    ReferencedNames info = _computeReferencedNames('''
class U<T> {
  T f = new A<T>();
}
''');
    expect(info.names, unorderedEquals(['A']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A']));
  }

  test_referencedNames_localFunction() {
    ReferencedNames info = _computeReferencedNames('''
f(A a) {
  g(B b) {}
}
''');
    expect(info.names, unorderedEquals(['A', 'B']));
    expect(info.userToDependsOn.keys, unorderedEquals(['f']));
    expect(info.userToDependsOn['f'], unorderedEquals(['A']));
  }

  test_referencedNames_topLevelVariable() {
    ReferencedNames info = _computeReferencedNames('''
A v = new B(c);
''');
    expect(info.names, unorderedEquals(['A', 'B', 'c']));
    expect(info.userToDependsOn.keys, unorderedEquals(['v']));
    expect(info.userToDependsOn['v'], unorderedEquals(['A', 'B', 'c']));
  }

  test_referencedNames_topLevelVariable_multiple() {
    ReferencedNames info = _computeReferencedNames('''
A v1 = new B(c), v2 = new D<E>(f);
''');
    expect(info.names, unorderedEquals(['A', 'B', 'c', 'D', 'E', 'f']));
    expect(info.userToDependsOn.keys, unorderedEquals(['v1', 'v2']));
    expect(info.userToDependsOn['v1'], unorderedEquals(['A', 'B', 'c']));
    expect(info.userToDependsOn['v2'], unorderedEquals(['A', 'D', 'E', 'f']));
  }

  test_referencedNames_unit_classTypeAlias() {
    ReferencedNames info = _computeReferencedNames('''
class U = A with B implements C;
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B', 'C']));
  }

  test_referencedNames_unit_classTypeAlias_typeParameters() {
    ReferencedNames info = _computeReferencedNames('''
class U<T1, T2 extends D> = A<T1> with B<T2> implements C<T1, T2>;
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C', 'D']));
    expect(info.userToDependsOn.keys, unorderedEquals(['U']));
    expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B', 'C', 'D']));
  }

  test_referencedNames_unit_function() {
    ReferencedNames info = _computeReferencedNames('''
A f(B b) {
  C c = 0;
}
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C']));
    expect(info.userToDependsOn.keys, unorderedEquals(['f']));
    expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
  }

  test_referencedNames_unit_function_localFunctions() {
    ReferencedNames info = _computeReferencedNames('''
A f() {
  B b = null;
  C g() {}
  g();
}
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C']));
    expect(info.userToDependsOn.keys, unorderedEquals(['f']));
    expect(info.userToDependsOn['f'], unorderedEquals(['A']));
  }

  test_referencedNames_unit_function_localsDontHideQualified() {
    ReferencedNames info = _computeReferencedNames('''
f(A a, B b) {
  var v = 0;
  a.v;
  a.b;
}
''');
    expect(info.names, unorderedEquals(['A', 'B', 'v', 'b']));
    expect(info.userToDependsOn.keys, unorderedEquals(['f']));
    expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
  }

  test_referencedNames_unit_function_localVariables() {
    ReferencedNames info = _computeReferencedNames('''
A f() {
  B b = null;
  b;
  {
    C c = null;
    b;
    c;
  }
  d;
}
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C', 'd']));
    expect(info.userToDependsOn.keys, unorderedEquals(['f']));
    expect(info.userToDependsOn['f'], unorderedEquals(['A']));
  }

  test_referencedNames_unit_function_parameters() {
    ReferencedNames info = _computeReferencedNames('''
A f(B b) {
  C c = 0;
  b;
}
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C']));
    expect(info.userToDependsOn.keys, unorderedEquals(['f']));
    expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
  }

  test_referencedNames_unit_function_typeParameters() {
    ReferencedNames info = _computeReferencedNames('''
A f<T>(B b, T t) {
  C c = 0;
}
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C']));
    expect(info.userToDependsOn.keys, unorderedEquals(['f']));
    expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
  }

  test_referencedNames_unit_functionTypeAlias() {
    ReferencedNames info = _computeReferencedNames('''
typedef A F(B B, C c(D d));
''');
    expect(info.names, unorderedEquals(['A', 'B', 'C', 'D']));
    expect(info.userToDependsOn.keys, unorderedEquals(['F']));
    expect(info.userToDependsOn['F'], unorderedEquals(['A', 'B', 'C', 'D']));
  }

  test_referencedNames_unit_functionTypeAlias_typeParameters() {
    ReferencedNames info = _computeReferencedNames('''
typedef A F<T>(B b, T t);
''');
    expect(info.names, unorderedEquals(['A', 'B']));
    expect(info.userToDependsOn.keys, unorderedEquals(['F']));
    expect(info.userToDependsOn['F'], unorderedEquals(['A', 'B']));
  }

  test_referencedNames_unit_getter() {
    ReferencedNames info = _computeReferencedNames('''
A get aaa {
  return new B();
}
''');
    expect(info.names, unorderedEquals(['A', 'B']));
    expect(info.userToDependsOn.keys, unorderedEquals(['aaa']));
    expect(info.userToDependsOn['aaa'], unorderedEquals(['A']));
  }

  test_referencedNames_unit_setter() {
    ReferencedNames info = _computeReferencedNames('''
set aaa(A a) {
  B b = null;
}
''');
    expect(info.names, unorderedEquals(['A', 'B']));
    expect(info.userToDependsOn.keys, unorderedEquals(['aaa']));
    expect(info.userToDependsOn['aaa'], unorderedEquals(['A']));
  }

  ReferencedNames _computeReferencedNames(String code) {
    Source source = newSource('/test.dart', code);
    computeResult(source, REFERENCED_NAMES,
        matcher: isResolveLibraryReferencesTask);
    return outputs[REFERENCED_NAMES];
  }
}

@reflectiveTest
class ResolveLibraryTaskTest extends _AbstractDartTaskTest {
  test_perform() {
    Source sourceLib = newSource(
        '/my_lib.dart',
        '''
library my_lib;
const a = new A();
class A {
  const A();
}
@a
class C {}
''');
    computeResult(sourceLib, LIBRARY_ELEMENT, matcher: isResolveLibraryTask);
    // validate
    LibraryElement library = outputs[LIBRARY_ELEMENT];
    ClassElement classC = library.getType('C');
    List<ElementAnnotation> metadata = classC.metadata;
    expect(metadata, hasLength(1));
    ElementAnnotation annotation = metadata[0];
    expect(annotation, isNotNull);
    expect((annotation as ElementAnnotationImpl).evaluationResult, isNotNull);
  }
}

@reflectiveTest
class ResolveLibraryTypeNamesTaskTest extends _AbstractDartTaskTest {
  test_perform() {
    Source sourceLib = newSource(
        '/my_lib.dart',
        '''
library my_lib;
part 'my_part.dart';
class A {}
class B extends A {}
''');
    newSource(
        '/my_part.dart',
        '''
part of my_lib;
class C extends A {}
''');
    computeResult(sourceLib, LIBRARY_ELEMENT6,
        matcher: isResolveLibraryTypeNamesTask);
    // validate
    LibraryElement library = outputs[LIBRARY_ELEMENT6];
    {
      ClassElement classB = library.getType('B');
      expect(classB.supertype.displayName, 'A');
    }
    {
      ClassElement classC = library.getType('C');
      expect(classC.supertype.displayName, 'A');
    }
    expect(library.loadLibraryFunction, isNotNull);
  }

  test_perform_external() {
    Source sourceA = newSource(
        '/a.dart',
        '''
library a;
import 'b.dart';
class A extends B {}
''');
    newSource(
        '/b.dart',
        '''
library b;
class B {}
''');
    // The reference A to B should be resolved, but there's no requirement that
    // the full class hierarchy be resolved.
    computeResult(sourceA, LIBRARY_ELEMENT6,
        matcher: isResolveLibraryTypeNamesTask);
    // validate
    LibraryElement library = outputs[LIBRARY_ELEMENT6];
    {
      ClassElement clazz = library.getType('A');
      expect(clazz.displayName, 'A');
      clazz = clazz.supertype.element;
      expect(clazz.displayName, 'B');
    }
  }
}

@reflectiveTest
class ResolveTopLevelUnitTypeBoundsTaskTest extends _AbstractDartTaskTest {
  test_perform_boundIsGenericType() {
    Source source = newSource(
        '/test.dart',
        '''
class C<T extends Map<String, List<int>>> {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT4,
        matcher: isResolveTopLevelUnitTypeBoundsTask);
    // validate
    CompilationUnit unit = outputs[RESOLVED_UNIT4];
    ClassDeclaration nodeC = unit.declarations[0];
    _assertTypeParameterBound(nodeC.typeParameters.typeParameters[0],
        'Map<String, List<int>>', 'Map');
  }

  test_perform_errors() {
    Source source = newSource(
        '/test.dart',
        '''
class C<T extends NoSuchClass> {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVE_TYPE_BOUNDS_ERRORS,
        matcher: isResolveTopLevelUnitTypeBoundsTask);
    // validate
    _fillErrorListener(RESOLVE_TYPE_BOUNDS_ERRORS);
    errorListener
        .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
  }

  test_perform_ignoreBoundsOfBounds() {
    Source source = newSource(
        '/test.dart',
        '''
class A<T1 extends num> {}
class B<T2 extends A> {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT4,
        matcher: isResolveTopLevelUnitTypeBoundsTask);
    // validate
    CompilationUnit unit = outputs[RESOLVED_UNIT4];
    ClassDeclaration nodeB = unit.declarations[1];
    _assertTypeParameterBound(
        nodeB.typeParameters.typeParameters[0], 'A<dynamic>', 'A');
  }

  test_perform_outputs() {
    Source source = newSource(
        '/test.dart',
        r'''
class C<T extends int> {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT4);
    expect(outputs[RESOLVED_UNIT4], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT4], isTrue);
    expect(outputs[RESOLVE_TYPE_BOUNDS_ERRORS], isNotNull);
  }

  test_perform_unitMember_ClassDeclaration() {
    Source source = newSource(
        '/test.dart',
        '''
class C<T extends int> extends Object {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT4,
        matcher: isResolveTopLevelUnitTypeBoundsTask);
    // validate
    CompilationUnit unit = outputs[RESOLVED_UNIT4];
    ClassDeclaration nodeC = unit.declarations[0];
    // 'extends Object' is not resolved
    expect(nodeC.extendsClause.superclass.name.staticElement, isNull);
    // but 'T extends int' is resolved
    _assertTypeParameterBound(
        nodeC.typeParameters.typeParameters[0], 'int', 'int');
  }

  test_perform_unitMember_ClassTypeAlias() {
    Source source = newSource(
        '/test.dart',
        '''
class C<T extends double> = Object;
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT4,
        matcher: isResolveTopLevelUnitTypeBoundsTask);
    // validate
    CompilationUnit unit = outputs[RESOLVED_UNIT4];
    ClassTypeAlias nodeC = unit.declarations[0];
    // '= Object' is not resolved
    expect(nodeC.superclass.name.staticElement, isNull);
    // but 'T extends int' is resolved
    _assertTypeParameterBound(
        nodeC.typeParameters.typeParameters[0], 'double', 'double');
  }

  test_perform_unitMember_FunctionTypeAlias() {
    Source source = newSource(
        '/test.dart',
        '''
typedef F<T extends String>();
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT4,
        matcher: isResolveTopLevelUnitTypeBoundsTask);
    // validate
    CompilationUnit unit = outputs[RESOLVED_UNIT4];
    FunctionTypeAlias nodeF = unit.declarations[0];
    // but 'T extends String' is resolved
    _assertTypeParameterBound(
        nodeF.typeParameters.typeParameters[0], 'String', 'String');
  }

  void _assertTypeParameterBound(TypeParameter typeParameter,
      String expectedBoundTypeString, String expectedBoundElementName) {
    TypeName boundNode = typeParameter.bound;
    Identifier boundName = boundNode.name;
    expect(boundNode.type.toString(), expectedBoundTypeString);
    expect(boundName.staticType.toString(), expectedBoundTypeString);
    expect(boundName.staticElement.displayName, expectedBoundElementName);
  }
}

@reflectiveTest
class ResolveUnitTaskTest extends _AbstractDartTaskTest {
  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT12);
    expect(outputs[RESOLVED_UNIT12], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT12], isTrue);
  }

  void test_perform() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
void f() {
  var c = new C();
  c.m();
}
class C {
  void m() {
    f();
  }
}
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12,
        matcher: isResolveUnitTask);
    CompilationUnit unit = outputs[RESOLVED_UNIT12];

    FunctionDeclaration f = unit.declarations[0];
    _assertResolved(f.functionExpression.body);

    MethodDeclaration m = (unit.declarations[1] as ClassDeclaration).members[0];
    _assertResolved(m.body);

    expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
  }

  void test_perform_ensurePropagatedVariableTypes() {
    newSource(
        '/lib.dart',
        '''
class A {
  final v = 1;
}
''');
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
import 'lib.dart';
main(A a) {
  a.v.isEven;
}
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12,
        matcher: isResolveUnitTask);
    expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
    CompilationUnit unit = outputs[RESOLVED_UNIT12];
    FunctionDeclaration main = unit.declarations[0];
    BlockFunctionBody body = main.functionExpression.body;
    ExpressionStatement statement = body.block.statements.single;
    Expression expression = statement.expression;
    expect(expression.bestType, context.typeProvider.boolType);
  }

  void _assertResolved(FunctionBody body) {
    ResolutionVerifier verifier = new ResolutionVerifier();
    body.accept(verifier);
    verifier.assertResolved();
  }
}

@reflectiveTest
class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest {
  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT5);
    expect(outputs[RESOLVED_UNIT5], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT5], isTrue);
  }

  test_perform() {
    Source source = newSource(
        '/test.dart',
        '''
class A {}
class B extends A {}
int f(String p) => p.length;
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT5, matcher: isResolveUnitTypeNamesTask);
    // validate
    CompilationUnit unit = outputs[RESOLVED_UNIT5];
    {
      ClassDeclaration nodeA = unit.declarations[0];
      ClassDeclaration nodeB = unit.declarations[1];
      DartType extendsType = nodeB.extendsClause.superclass.type;
      expect(extendsType, nodeA.element.type);
    }
    {
      FunctionDeclaration functionNode = unit.declarations[2];
      DartType returnType = functionNode.returnType.type;
      List<FormalParameter> parameters =
          functionNode.functionExpression.parameters.parameters;
      expect(returnType.displayName, 'int');
      expect(parameters[0].element.type.displayName, 'String');
    }
  }

  test_perform_errors() {
    Source source = newSource(
        '/test.dart',
        '''
NoSuchClass f() => null;
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVE_TYPE_NAMES_ERRORS,
        matcher: isResolveUnitTypeNamesTask);
    // validate
    _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
    errorListener
        .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
  }

  test_perform_typedef() {
    Source source = newSource(
        '/test.dart',
        '''
typedef int F(G g);
typedef String G(int p);
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT5, matcher: isResolveUnitTypeNamesTask);
    // validate
    CompilationUnit unit = outputs[RESOLVED_UNIT5];
    FunctionTypeAlias nodeF = unit.declarations[0];
    FunctionTypeAlias nodeG = unit.declarations[1];
    {
      FormalParameter parameter = nodeF.parameters.parameters[0];
      DartType parameterType = parameter.element.type;
      Element returnTypeElement = nodeF.returnType.type.element;
      expect(returnTypeElement.displayName, 'int');
      expect(parameterType.element, nodeG.element);
    }
    {
      FormalParameter parameter = nodeG.parameters.parameters[0];
      DartType parameterType = parameter.element.type;
      expect(nodeG.returnType.type.element.displayName, 'String');
      expect(parameterType.element.displayName, 'int');
    }
  }

  test_perform_typedef_errors() {
    Source source = newSource(
        '/test.dart',
        '''
typedef int F(NoSuchType p);
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVE_TYPE_NAMES_ERRORS,
        matcher: isResolveUnitTypeNamesTask);
    // validate
    _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
    errorListener
        .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
  }
}

@reflectiveTest
class ResolveVariableReferencesTaskTest extends _AbstractDartTaskTest {
  /**
   * Verify that the mutated states of the given [variable] correspond to the
   * [mutatedInClosure] and [mutatedInScope] matchers.
   */
  void expectMutated(FunctionBody body, VariableElement variable,
      bool mutatedInClosure, bool mutatedInScope) {
    expect(body.isPotentiallyMutatedInClosure(variable), mutatedInClosure);
    expect(body.isPotentiallyMutatedInScope(variable), mutatedInScope);
  }

  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT6);
    expect(outputs[RESOLVED_UNIT6], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT6], isTrue);
  }

  test_perform_buildClosureLibraryElements() {
    Source source = newSource(
        '/test.dart',
        '''
main() {
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT6,
        matcher: isResolveVariableReferencesTask);
  }

  test_perform_local() {
    Source source = newSource(
        '/test.dart',
        '''
main() {
  var v1 = 1;
  var v2 = 1;
  var v3 = 1;
  var v4 = 1;
  v2 = 2;
  v4 = 2;
  localFunction() {
    v3 = 3;
    v4 = 3;
  }
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT6,
        matcher: isResolveVariableReferencesTask);
    // validate
    CompilationUnit unit = outputs[RESOLVED_UNIT6];
    FunctionDeclaration mainDeclaration = unit.declarations[0];
    FunctionBody body = mainDeclaration.functionExpression.body;
    FunctionElement main = mainDeclaration.element;
    expectMutated(body, main.localVariables[0], false, false);
    expectMutated(body, main.localVariables[1], false, true);
    expectMutated(body, main.localVariables[2], true, true);
    expectMutated(body, main.localVariables[3], true, true);
  }

  test_perform_parameter() {
    Source source = newSource(
        '/test.dart',
        '''
main(p1, p2, p3, p4) {
  p2 = 2;
  p4 = 2;
  localFunction() {
    p3 = 3;
    p4 = 3;
  }
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT6,
        matcher: isResolveVariableReferencesTask);
    // validate
    CompilationUnit unit = outputs[RESOLVED_UNIT6];
    FunctionDeclaration mainDeclaration = unit.declarations[0];
    FunctionBody body = mainDeclaration.functionExpression.body;
    FunctionElement main = mainDeclaration.element;
    expectMutated(body, main.parameters[0], false, false);
    expectMutated(body, main.parameters[1], false, true);
    expectMutated(body, main.parameters[2], true, true);
    expectMutated(body, main.parameters[3], true, true);
  }
}

@reflectiveTest
class ScanDartTaskTest extends _AbstractDartTaskTest {
  test_ignore_info() {
    _performScanTask('''
//ignore: error_code
var x = '';
foo(); // ignore:   error_code_2
bar(); //ignore: error_code, error_code_2
''');

    IgnoreInfo info = outputs[IGNORE_INFO];
    expect(info.ignores.keys, hasLength(3));
    expect(info.ignores[1].first, 'error_code');
    expect(info.ignores[3].first, 'error_code_2');
    expect(info.ignores[4], unorderedEquals(['error_code', 'error_code_2']));
  }

  test_perform_errors() {
    _performScanTask('import "');
    expect(outputs, hasLength(4));
    expect(outputs[LINE_INFO], isNotNull);
    expect(outputs[SCAN_ERRORS], hasLength(1));
    expect(outputs[TOKEN_STREAM], isNotNull);
    IgnoreInfo ignoreInfo = outputs[IGNORE_INFO];
    expect(ignoreInfo, isNotNull);
    expect(ignoreInfo.hasIgnores, isFalse);
  }

  test_perform_noErrors() {
    _performScanTask('class A {}');
    expect(outputs, hasLength(4));
    expect(outputs[LINE_INFO], isNotNull);
    expect(outputs[SCAN_ERRORS], hasLength(0));
    expect(outputs[TOKEN_STREAM], isNotNull);
    IgnoreInfo ignoreInfo = outputs[IGNORE_INFO];
    expect(ignoreInfo, isNotNull);
    expect(ignoreInfo.hasIgnores, isFalse);
  }

  test_perform_script() {
    String scriptContent = '''
      void buttonPressed() {
    ''';
    String htmlContent = '''
<!DOCTYPE html>
<html>
  <head>
    <title>test page</title>
    <script type='application/dart'>$scriptContent</script>
  </head>
  <body>Test</body>
</html>
''';
    Source source = newSource('/test.html', htmlContent);
    DartScript script =
        new DartScript(source, [new ScriptFragment(97, 5, 36, scriptContent)]);

    computeResult(script, TOKEN_STREAM, matcher: isScanDartTask);
    expect(outputs[LINE_INFO], isNotNull);
    expect(outputs[SCAN_ERRORS], isEmpty);
    Token tokenStream = outputs[TOKEN_STREAM];
    expect(tokenStream, isNotNull);
    expect(tokenStream.lexeme, 'void');
  }

  void _performScanTask(String content) {
    AnalysisTarget target = newSource('/test.dart', content);
    computeResult(target, TOKEN_STREAM, matcher: isScanDartTask);
  }
}

@reflectiveTest
class StrongModeInferenceTest extends _AbstractDartTaskTest {
  @override
  void setUp() {
    super.setUp();
    enableStrongMode();
  }

  // Check that even within a static variable cycle, inferred
  // types get propagated to the members of the cycle.
  void test_perform_cycle() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
var piFirst = true;
var pi = piFirst ? 3.14 : tau / 2;
var tau = piFirst ? pi * 2 : 6.28;
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
    CompilationUnit unit = outputs[RESOLVED_UNIT12];
    VariableElement piFirst =
        AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
    VariableElement pi =
        AstFinder.getTopLevelVariable(unit, 'pi').name.staticElement;
    VariableElement tau =
        AstFinder.getTopLevelVariable(unit, 'tau').name.staticElement;
    Expression piFirstUse = (AstFinder
            .getTopLevelVariable(unit, 'tau')
            .initializer as ConditionalExpression)
        .condition;

    expect(piFirstUse.staticType, context.typeProvider.boolType);
    expect(piFirst.type, context.typeProvider.boolType);
    expect(pi.type.isDynamic, isTrue);
    expect(tau.type.isDynamic, isTrue);
  }

  void test_perform_inference_cross_unit_cyclic() {
    AnalysisTarget firstSource = newSource(
        '/a.dart',
        '''
          import 'test.dart';
          var x = 2;
          class A { static var x = 2; }
''');
    AnalysisTarget secondSource = newSource(
        '/test.dart',
        '''
          import 'a.dart';
          var y = x;
          class B { static var y = A.x; }

          test1() {
            int t = 3;
            t = x;
            t = y;
            t = A.x;
            t = B.y;
          }
''');
    computeResult(
        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT12);
    CompilationUnit unit1 = outputs[RESOLVED_UNIT12];
    computeResult(
        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT12);
    CompilationUnit unit2 = outputs[RESOLVED_UNIT12];

    InterfaceType intType = context.typeProvider.intType;

    assertVariableDeclarationTypes(
        AstFinder.getTopLevelVariable(unit1, "x"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "A", "x"), intType, intType);

    assertVariableDeclarationTypes(
        AstFinder.getTopLevelVariable(unit2, "y"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit2, "B", "y"), intType, intType);

    List<Statement> statements =
        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");

    assertAssignmentStatementTypes(statements[1], intType, intType);
    assertAssignmentStatementTypes(statements[2], intType, intType);
    assertAssignmentStatementTypes(statements[3], intType, intType);
    assertAssignmentStatementTypes(statements[4], intType, intType);
  }

  // Test that local variables in method bodies are inferred appropriately
  void test_perform_inference_cross_unit_instance() {
    List<Source> sources = newSources({
      '/a.dart': '''
          import 'b.dart';
          class A {
            final a2 = new B().b2;
          }
      ''',
      '/b.dart': '''
          class B {
            final b2 = 1;
          }
      ''',
      '/main.dart': '''
          import "a.dart";

          test1() {
            int x = 0;
            x = new A().a2;
          }
    '''
    });
    List<dynamic> units =
        computeLibraryResults(sources, RESOLVED_UNIT12).toList();
    CompilationUnit unit0 = units[0];
    CompilationUnit unit1 = units[1];
    CompilationUnit unit2 = units[2];

    InterfaceType intType = context.typeProvider.intType;

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);

    List<Statement> statements =
        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");

    assertAssignmentStatementTypes(statements[1], intType, intType);
  }

  // Test inference interactions between local variables and fields
  void test_perform_inference_cross_unit_instance_member() {
    List<Source> sources = newSources({
      '/a.dart': '''
          import 'b.dart';
            var bar = new B();
            void foo() {
              String x = bar.f.z;
            }
      ''',
      '/b.dart': '''
        class C {
          var z = 3;
        }

        class B {
          var f = new C();
        }
      ''',
      '/c.dart': '''
          import 'b.dart';
            var bar = new B();
            void foo() {
              String x = bar.f.z;
            }
    '''
    });
    List<dynamic> units =
        computeLibraryResults(sources, RESOLVED_UNIT12).toList();
    CompilationUnit unit0 = units[0];
    CompilationUnit unit2 = units[2];

    InterfaceType intType = context.typeProvider.intType;
    InterfaceType stringType = context.typeProvider.stringType;

    assertVariableDeclarationStatementTypes(
        AstFinder.getStatementsInTopLevelFunction(unit0, "foo")[0],
        stringType,
        intType);
    assertVariableDeclarationStatementTypes(
        AstFinder.getStatementsInTopLevelFunction(unit2, "foo")[0],
        stringType,
        intType);
  }

  // Test inference interactions between local variables and top level
  // variables
  void test_perform_inference_cross_unit_non_cyclic() {
    AnalysisTarget firstSource = newSource(
        '/a.dart',
        '''
          var x = 2;
          class A { static var x = 2; }
''');
    AnalysisTarget secondSource = newSource(
        '/test.dart',
        '''
          import 'a.dart';
          var y = x;
          class B { static var y = A.x; }

          test1() {
            x = /*severe:StaticTypeError*/"hi";
            y = /*severe:StaticTypeError*/"hi";
            A.x = /*severe:StaticTypeError*/"hi";
            B.y = /*severe:StaticTypeError*/"hi";
          }
''');
    computeResult(
        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT12);
    CompilationUnit unit1 = outputs[RESOLVED_UNIT12];
    computeResult(
        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT12);
    CompilationUnit unit2 = outputs[RESOLVED_UNIT12];

    InterfaceType intType = context.typeProvider.intType;
    InterfaceType stringType = context.typeProvider.stringType;

    assertVariableDeclarationTypes(
        AstFinder.getTopLevelVariable(unit1, "x"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "A", "x"), intType, intType);

    assertVariableDeclarationTypes(
        AstFinder.getTopLevelVariable(unit2, "y"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit2, "B", "y"), intType, intType);

    List<Statement> statements =
        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");

    assertAssignmentStatementTypes(statements[0], intType, stringType);
    assertAssignmentStatementTypes(statements[1], intType, stringType);
  }

  // Test that inference does not propagate from null
  void test_perform_inference_cross_unit_static_instance() {
    List<Source> sources = newSources({
      '/a.dart': '''
          import 'b.dart';
          class A {
            static final a1 = B.b1;
            final a2 = new B().b2;
          }
      ''',
      '/b.dart': '''
          class B {
            static final b1 = 1;
            final b2 = 1;
          }
      ''',
      '/main.dart': '''
          import "a.dart";

          test1() {
            int x = 0;
            // inference in A now works.
            x = A.a1;
            x = new A().a2;
          }
    '''
    });
    List<dynamic> units =
        computeLibraryResults(sources, RESOLVED_UNIT12).toList();
    CompilationUnit unit0 = units[0];
    CompilationUnit unit1 = units[1];
    CompilationUnit unit2 = units[2];

    InterfaceType intType = context.typeProvider.intType;

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);

    List<Statement> statements =
        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");

    assertAssignmentStatementTypes(statements[1], intType, intType);
    assertAssignmentStatementTypes(statements[2], intType, intType);
  }

  // Test inference across units (non-cyclic)
  void test_perform_inference_local_variables() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
      test() {
        int x = 3;
        x = "hi";
        var y = 3;
        y = "hi";
      }
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
    CompilationUnit unit = outputs[RESOLVED_UNIT12];

    InterfaceType intType = context.typeProvider.intType;
    InterfaceType stringType = context.typeProvider.stringType;

    List<Statement> statements =
        AstFinder.getStatementsInTopLevelFunction(unit, "test");

    assertVariableDeclarationStatementTypes(statements[0], intType, intType);
    assertAssignmentStatementTypes(statements[1], intType, stringType);
    assertVariableDeclarationStatementTypes(statements[2], intType, intType);
    assertAssignmentStatementTypes(statements[3], intType, stringType);
  }

  // Test inference across units (cyclic)
  void test_perform_inference_local_variables_fields() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
      class A {
        int x = 0;

        test1() {
          var a = x;
          a = "hi";
          a = 3;
          var b = y;
          b = "hi";
          b = 4;
          var c = z;
          c = "hi";
          c = 4;
        }

        int y; // field def after use
        final z = 42; // should infer `int`
      }
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
    CompilationUnit unit = outputs[RESOLVED_UNIT12];

    InterfaceType intType = context.typeProvider.intType;
    InterfaceType stringType = context.typeProvider.stringType;

    List<Statement> statements =
        AstFinder.getStatementsInMethod(unit, "A", "test1");

    assertVariableDeclarationStatementTypes(statements[0], intType, intType);
    assertAssignmentStatementTypes(statements[1], intType, stringType);
    assertAssignmentStatementTypes(statements[2], intType, intType);

    assertVariableDeclarationStatementTypes(statements[3], intType, intType);
    assertAssignmentStatementTypes(statements[4], intType, stringType);
    assertAssignmentStatementTypes(statements[5], intType, intType);

    assertVariableDeclarationStatementTypes(statements[6], intType, intType);
    assertAssignmentStatementTypes(statements[7], intType, stringType);
    assertAssignmentStatementTypes(statements[8], intType, intType);

    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit, "A", "x"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit, "A", "z"), intType, intType);
  }

  // Test inference of instance fields across units
  void test_perform_inference_local_variables_topLevel() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
      int x = 0;

      test1() {
        var a = x;
        a = /*severe:StaticTypeError*/"hi";
        a = 3;
        var b = y;
        b = /*severe:StaticTypeError*/"hi";
        b = 4;
        var c = z;
        c = /*severe:StaticTypeError*/"hi";
        c = 4;
      }

      int y = 0; // field def after use
      final z = 42; // should infer `int`
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
    CompilationUnit unit = outputs[RESOLVED_UNIT12];

    InterfaceType intType = context.typeProvider.intType;
    InterfaceType stringType = context.typeProvider.stringType;

    List<Statement> statements =
        AstFinder.getStatementsInTopLevelFunction(unit, "test1");

    assertVariableDeclarationStatementTypes(statements[0], intType, intType);
    assertAssignmentStatementTypes(statements[1], intType, stringType);
    assertAssignmentStatementTypes(statements[2], intType, intType);

    assertVariableDeclarationStatementTypes(statements[3], intType, intType);
    assertAssignmentStatementTypes(statements[4], intType, stringType);
    assertAssignmentStatementTypes(statements[5], intType, intType);

    assertVariableDeclarationStatementTypes(statements[6], intType, intType);
    assertAssignmentStatementTypes(statements[7], intType, stringType);
    assertAssignmentStatementTypes(statements[8], intType, intType);

    assertVariableDeclarationTypes(
        AstFinder.getTopLevelVariable(unit, "x"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getTopLevelVariable(unit, "y"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getTopLevelVariable(unit, "z"), intType, intType);
  }

  // Test inference between static and instance fields
  void test_perform_inference_null() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
      var x = null;
      var y = 3;
      class A {
        static var x = null;
        static var y = 3;

        var x2 = null;
        var y2 = 3;
      }

      test() {
        x = "hi";
        y = /*severe:StaticTypeError*/"hi";
        A.x = "hi";
        A.y = /*severe:StaticTypeError*/"hi";
        new A().x2 = "hi";
        new A().y2 = /*severe:StaticTypeError*/"hi";
      }
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
    CompilationUnit unit = outputs[RESOLVED_UNIT12];

    InterfaceType intType = context.typeProvider.intType;
    InterfaceType stringType = context.typeProvider.stringType;
    DartType bottomType = context.typeProvider.bottomType;
    DartType dynamicType = context.typeProvider.dynamicType;

    assertVariableDeclarationTypes(
        AstFinder.getTopLevelVariable(unit, "x"), dynamicType, bottomType);
    assertVariableDeclarationTypes(
        AstFinder.getTopLevelVariable(unit, "y"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit, "A", "x"), dynamicType, bottomType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit, "A", "y"), intType, intType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit, "A", "x2"), dynamicType, bottomType);
    assertVariableDeclarationTypes(
        AstFinder.getFieldInClass(unit, "A", "y2"), intType, intType);

    List<Statement> statements =
        AstFinder.getStatementsInTopLevelFunction(unit, "test");

    assertAssignmentStatementTypes(statements[0], dynamicType, stringType);
    assertAssignmentStatementTypes(statements[1], intType, stringType);
    assertAssignmentStatementTypes(statements[2], dynamicType, stringType);
    assertAssignmentStatementTypes(statements[3], intType, stringType);
    assertAssignmentStatementTypes(statements[4], dynamicType, stringType);
    assertAssignmentStatementTypes(statements[5], intType, stringType);
  }

  // Test inference between fields and method bodies
  void test_perform_local_explicit_disabled() {
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
      test() {
        int x = 3;
        x = "hi";
      }
''');
    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
    CompilationUnit unit = outputs[RESOLVED_UNIT12];

    InterfaceType intType = context.typeProvider.intType;
    InterfaceType stringType = context.typeProvider.stringType;

    List<Statement> statements =
        AstFinder.getStatementsInTopLevelFunction(unit, "test");
    VariableDeclaration decl =
        (statements[0] as VariableDeclarationStatement).variables.variables[0];
    expect(decl.element.type, intType);
    expect(decl.initializer.staticType, intType);

    ExpressionStatement statement = statements[1];
    AssignmentExpression assgn = statement.expression;
    expect(assgn.leftHandSide.staticType, intType);
    expect(assgn.rightHandSide.staticType, stringType);
  }
}

@reflectiveTest
class StrongModeVerifyUnitTaskTest extends _AbstractDartTaskTest {
  @override
  void setUp() {
    super.setUp();
    enableStrongMode();
  }

  test_created_resolved_unit() {
    Source source = newSource(
        '/test.dart',
        r'''
library lib;
class A {}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, RESOLVED_UNIT);
    expect(outputs[RESOLVED_UNIT], isNotNull);
    expect(outputs[CREATED_RESOLVED_UNIT], isTrue);
  }

  void test_perform_recordDynamicInvoke() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
void main() {
  dynamic a = [];
  a[0];
}
''');
    computeResult(new LibrarySpecificUnit(source, source), STRONG_MODE_ERRORS);
    CompilationUnit unit = outputs[RESOLVED_UNIT];

    // validate
    _fillErrorListener(STRONG_MODE_ERRORS);
    expect(errorListener.errors, isEmpty);

    List<Statement> statements =
        AstFinder.getStatementsInTopLevelFunction(unit, "main");
    ExpressionStatement statement = statements[1];
    IndexExpression idx = statement.expression;
    expect(strong_ast.isDynamicInvoke(idx.target), isTrue);
  }

  void test_perform_verifyError() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
class A {}
class B extends A {}
B b = new A();
''');
    computeResult(new LibrarySpecificUnit(source, source), STRONG_MODE_ERRORS);
    // validate
    _fillErrorListener(STRONG_MODE_ERRORS);

    var errors = errorListener.errors;
    expect(errors.length, 1);
    expect(errors[0].errorCode.name, "STRONG_MODE_STATIC_TYPE_ERROR");
  }
}

@reflectiveTest
class VerifyUnitTaskTest extends _AbstractDartTaskTest {
  test_perform_constantError() {
    Source source = newSource(
        '/test.dart',
        '''
main(int p) {
  const v = p;
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
    // validate
    _fillErrorListener(VERIFY_ERRORS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[
      CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
    ]);
  }

  test_perform_ConstantValidator_declaredIdentifier() {
    Source source = newSource(
        '/test.dart',
        '''
void main() {
  for (const foo in []) {
    print(foo);
  }
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
    // validate
    _fillErrorListener(VERIFY_ERRORS);
    errorListener.assertNoErrors();
  }

  test_perform_ConstantValidator_dependencyCycle() {
    Source source = newSource(
        '/test.dart',
        '''
const int a = b;
const int b = c;
const int c = a;
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
    // validate
    _fillErrorListener(VERIFY_ERRORS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[
      CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
      CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
      CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT
    ]);
  }

  test_perform_ConstantValidator_duplicateFields() {
    Source source = newSource(
        '/test.dart',
        '''
class Test {
  final int x = 1;
  final int x = 2;
  const Test();
}

main() {
  const Test();
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
    // validate
    _fillErrorListener(VERIFY_ERRORS);
    errorListener.assertNoErrors();
  }

  test_perform_ConstantValidator_noInitializer() {
    Source source = newSource(
        '/test.dart',
        '''
const x;
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
    // validate
    _fillErrorListener(VERIFY_ERRORS);
    errorListener.assertErrorsWithCodes(
        <ErrorCode>[CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
  }

  test_perform_ConstantValidator_unknownValue() {
    Source source = newSource(
        '/test.dart',
        '''
import 'no-such-file.dart' as p;

const int x = p.y;
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
    // validate
    _fillErrorListener(VERIFY_ERRORS);
    errorListener.assertErrorsWithCodes(<ErrorCode>[
      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
      CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
    ]);
  }

  test_perform_directiveError() {
    Source source = newSource(
        '/test.dart',
        '''
import 'no-such-file.dart';
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
    // validate
    _fillErrorListener(VERIFY_ERRORS);
    errorListener.assertErrorsWithCodes(
        <ErrorCode>[CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
  }

  void test_perform_reresolution() {
    enableStrongMode();
    AnalysisTarget source = newSource(
        '/test.dart',
        '''
const topLevel = 3;
class C {
  String field = topLevel;
}
''');
    computeResult(new LibrarySpecificUnit(source, source), VERIFY_ERRORS);
    // validate
    _fillErrorListener(VERIFY_ERRORS);

    var errors = errorListener.errors;
    expect(errors.length, 1);
    expect(errors[0].errorCode, StaticTypeWarningCode.INVALID_ASSIGNMENT);
  }

  test_perform_verifyError() {
    Source source = newSource(
        '/test.dart',
        '''
main() {
  if (42) {
    print('Not bool!');
  }
}
''');
    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
    // validate
    _fillErrorListener(VERIFY_ERRORS);
    errorListener.assertErrorsWithCodes(
        <ErrorCode>[StaticTypeWarningCode.NON_BOOL_CONDITION]);
  }
}

class _AbstractDartTaskTest extends AbstractContextTest {
  Source emptySource;

  GatheringErrorListener errorListener = new GatheringErrorListener();

  void assertAssignmentStatementTypes(
      Statement stmt, DartType leftType, DartType rightType) {
    AssignmentExpression assgn = (stmt as ExpressionStatement).expression;
    expect(assgn.leftHandSide.staticType, leftType);
    expect(assgn.rightHandSide.staticType, rightType);
  }

  void assertIsInvalid(AnalysisTarget target, ResultDescriptor descriptor) {
    CacheEntry entry = context.getCacheEntry(target);
    expect(entry.isInvalid(descriptor), isTrue);
  }

  void assertIsValid(AnalysisTarget target, ResultDescriptor descriptor) {
    CacheEntry entry = context.getCacheEntry(target);
    expect(entry.isValid(descriptor), isTrue);
  }

  void assertSameResults(List<ResultDescriptor> descriptors) {
    descriptors.forEach((descriptor) {
      var oldResult = oldOutputs[descriptor];
      var newResult = outputs[descriptor];
      expect(newResult, same(oldResult), reason: descriptor.name);
    });
  }

  void assertVariableDeclarationStatementTypes(
      Statement stmt, DartType varType, DartType initializerType) {
    VariableDeclaration decl =
        (stmt as VariableDeclarationStatement).variables.variables[0];
    assertVariableDeclarationTypes(decl, varType, initializerType);
  }

  void assertVariableDeclarationTypes(
      VariableDeclaration decl, DartType varType, DartType initializerType) {
    expect(decl.element.type, varType);
    expect(decl.initializer.staticType, initializerType);
  }

  List<dynamic> computeLibraryResults(
      List<Source> sources, ResultDescriptor result,
      {isInstanceOf matcher: null}) {
    dynamic compute(Source source) {
      computeResult(new LibrarySpecificUnit(source, source), result,
          matcher: matcher);
      return outputs[result];
    }
    return sources.map(compute).toList();
  }

  List<Map<ResultDescriptor, dynamic>> computeLibraryResultsMap(
      List<Source> sources, ResultDescriptor result,
      {isInstanceOf matcher: null}) {
    Map<ResultDescriptor, dynamic> compute(Source source) {
      computeResult(new LibrarySpecificUnit(source, source), result,
          matcher: matcher);
      return outputs;
    }
    return sources.map(compute).toList();
  }

  /**
   * Create a script object with a single fragment containing the given
   * [scriptContent].
   */
  DartScript createScript(String scriptContent) {
    String htmlContent = '''
<!DOCTYPE html>
<html>
  <head>
    <title>test page</title>
    <script type='application/dart'>$scriptContent</script>
  </head>
  <body>Test</body>
</html>
''';
    Source source = newSource('/test.html', htmlContent);
    return new DartScript(
        source, [new ScriptFragment(97, 5, 36, scriptContent)]);
  }

  /**
   * Enable strong mode in the current analysis context.
   */
  void enableStrongMode() {
    AnalysisOptionsImpl options = context.analysisOptions;
    options.strongMode = true;
    context.analysisOptions = options;
  }

  void setUp() {
    super.setUp();
    emptySource = newSource('/test.dart');
  }

  /**
   * Fill [errorListener] with [result] errors in the current [task].
   */
  void _fillErrorListener(ResultDescriptor<List<AnalysisError>> result) {
    List<AnalysisError> errors = task.outputs[result] as List<AnalysisError>;
    expect(errors, isNotNull, reason: result.name);
    errorListener = new GatheringErrorListener();
    errorListener.addAll(errors);
  }
}
