| Index: packages/analyzer/test/src/task/dart_test.dart | 
| diff --git a/packages/analyzer/test/src/task/dart_test.dart b/packages/analyzer/test/src/task/dart_test.dart | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..0f39004e1c77208f0eb03914aef6097e2dd86f1d | 
| --- /dev/null | 
| +++ b/packages/analyzer/test/src/task/dart_test.dart | 
| @@ -0,0 +1,4259 @@ | 
| +// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file | 
| +// for details. All rights reserved. Use of this source code is governed by a | 
| +// BSD-style license that can be found in the LICENSE file. | 
| + | 
| +library test.src.task.dart_test; | 
| + | 
| +import 'package:analyzer/src/context/cache.dart'; | 
| +import 'package:analyzer/src/generated/ast.dart'; | 
| +import 'package:analyzer/src/generated/constant.dart'; | 
| +import 'package:analyzer/src/generated/element.dart'; | 
| +import 'package:analyzer/src/generated/engine.dart' | 
| +    show AnalysisOptionsImpl, CacheState; | 
| +import 'package:analyzer/src/generated/error.dart'; | 
| +import 'package:analyzer/src/generated/resolver.dart'; | 
| +import 'package:analyzer/src/generated/scanner.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/task/dart.dart'; | 
| +import 'package:analyzer/task/general.dart'; | 
| +import 'package:analyzer/task/model.dart'; | 
| +import 'package:unittest/unittest.dart'; | 
| + | 
| +import '../../generated/resolver_test.dart'; | 
| +import '../../generated/test_support.dart'; | 
| +import '../../reflective_tests.dart'; | 
| +import '../../utils.dart'; | 
| +import '../context/abstract_context.dart'; | 
| + | 
| +main() { | 
| +  initializeTestEnvironment(); | 
| +  runReflectiveTests(BuildCompilationUnitElementTaskTest); | 
| +  runReflectiveTests(BuildDirectiveElementsTaskTest); | 
| +  runReflectiveTests(BuildEnumMemberElementsTaskTest); | 
| +  runReflectiveTests(BuildExportNamespaceTaskTest); | 
| +  runReflectiveTests(BuildLibraryElementTaskTest); | 
| +  runReflectiveTests(BuildPublicNamespaceTaskTest); | 
| +  runReflectiveTests(BuildSourceExportClosureTaskTest); | 
| +  runReflectiveTests(BuildSourceImportExportClosureTaskTest); | 
| +  runReflectiveTests(BuildTypeProviderTaskTest); | 
| +  runReflectiveTests(ComputeConstantDependenciesTaskTest); | 
| +  runReflectiveTests(ComputeConstantValueTaskTest); | 
| +  runReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest); | 
| +  runReflectiveTests(ComputeLibraryCycleTaskTest); | 
| +  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(ResolveInstanceFieldsInUnitTaskTest); | 
| +  runReflectiveTests(ResolveLibraryTypeNamesTaskTest); | 
| +  runReflectiveTests(ResolveUnitTaskTest); | 
| +  runReflectiveTests(ResolveUnitTypeNamesTaskTest); | 
| +  runReflectiveTests(ResolveVariableReferencesTaskTest); | 
| +  runReflectiveTests(ScanDartTaskTest); | 
| +  runReflectiveTests(StrongModeInferenceTest); | 
| +  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 isBuildSourceImportExportClosureTask = | 
| +    new isInstanceOf<BuildSourceImportExportClosureTask>(); | 
| +isInstanceOf isBuildTypeProviderTask = | 
| +    new isInstanceOf<BuildTypeProviderTask>(); | 
| +isInstanceOf isComputeConstantDependenciesTask = | 
| +    new isInstanceOf<ComputeConstantDependenciesTask>(); | 
| +isInstanceOf isComputeConstantValueTask = | 
| +    new isInstanceOf<ComputeConstantValueTask>(); | 
| +isInstanceOf isComputeInferableStaticVariableDependenciesTask = | 
| +    new isInstanceOf<ComputeInferableStaticVariableDependenciesTask>(); | 
| +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 isResolveLibraryTypeNamesTask = | 
| +    new isInstanceOf<ResolveLibraryTypeNamesTask>(); | 
| +isInstanceOf isResolveUnitTask = new isInstanceOf<ResolveUnitTask>(); | 
| +isInstanceOf isResolveUnitTypeNamesTask = | 
| +    new isInstanceOf<ResolveUnitTypeNamesTask>(); | 
| +isInstanceOf isResolveVariableReferencesTask = | 
| +    new isInstanceOf<ResolveVariableReferencesTask>(); | 
| +isInstanceOf isScanDartTask = new isInstanceOf<ScanDartTask>(); | 
| +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_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], | 
| +      new ConstantEvaluationTarget_Annotation( | 
| +          context, source, source, annotation), | 
| +      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(3)); | 
| +    expect(outputs[COMPILATION_UNIT_CONSTANTS], isNotNull); | 
| +    expect(outputs[COMPILATION_UNIT_ELEMENT], isNotNull); | 
| +    expect(outputs[RESOLVED_UNIT1], isNotNull); | 
| +  } | 
| + | 
| +  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 { | 
| +  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); | 
| +  } | 
| + | 
| +  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_perform() { | 
| +    Source source = newSource( | 
| +        '/test.dart', | 
| +        ''' | 
| +enum MyEnum { | 
| +  A, B | 
| +} | 
| +'''); | 
| +    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT2, | 
| +        matcher: isBuildEnumMemberElementsTask); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT2]; | 
| +    // 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[0].element; | 
| +    CompilationUnitElement unitElement2 = partUnits[1].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]; | 
| +  } | 
| +} | 
| + | 
| +@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 { | 
| +  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 = outputs[EXPORT_SOURCE_CLOSURE]; | 
| +      expect(closure, unorderedEquals([sourceA, sourceB, sourceC])); | 
| +    } | 
| +    // c.dart | 
| +    { | 
| +      computeResult(sourceC, EXPORT_SOURCE_CLOSURE, | 
| +          matcher: isBuildSourceExportClosureTask); | 
| +      List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE]; | 
| +      expect(closure, unorderedEquals([sourceA, sourceB, sourceC])); | 
| +    } | 
| +    // d.dart | 
| +    { | 
| +      computeResult(sourceD, EXPORT_SOURCE_CLOSURE, | 
| +          matcher: isBuildSourceExportClosureTask); | 
| +      List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE]; | 
| +      expect(closure, unorderedEquals([sourceD])); | 
| +    } | 
| +  } | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class BuildSourceImportExportClosureTaskTest extends _AbstractDartTaskTest { | 
| +  test_perform_importExportClosure() { | 
| +    Source sourceA = newSource( | 
| +        '/a.dart', | 
| +        ''' | 
| +library lib_a; | 
| +'''); | 
| +    Source sourceB = newSource( | 
| +        '/b.dart', | 
| +        ''' | 
| +library lib_b; | 
| +export 'a.dart'; | 
| +'''); | 
| +    Source sourceC = newSource( | 
| +        '/c.dart', | 
| +        ''' | 
| +library lib_c; | 
| +import 'b.dart'; | 
| +'''); | 
| +    Source coreSource = context.sourceFactory.resolveUri(null, 'dart:core'); | 
| +    // c.dart | 
| +    { | 
| +      computeResult(sourceC, IMPORT_EXPORT_SOURCE_CLOSURE, | 
| +          matcher: isBuildSourceImportExportClosureTask); | 
| +      List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE]; | 
| +      expect(closure, contains(sourceA)); | 
| +      expect(closure, contains(sourceB)); | 
| +      expect(closure, contains(sourceC)); | 
| +      expect(closure, contains(coreSource)); | 
| +    } | 
| +    // b.dart | 
| +    { | 
| +      computeResult(sourceB, IMPORT_EXPORT_SOURCE_CLOSURE, | 
| +          matcher: isBuildSourceImportExportClosureTask); | 
| +      List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE]; | 
| +      expect(closure, contains(sourceA)); | 
| +      expect(closure, contains(sourceB)); | 
| +      expect(closure, contains(coreSource)); | 
| +    } | 
| +  } | 
| + | 
| +  test_perform_isClient_false() { | 
| +    Source sourceA = newSource( | 
| +        '/a.dart', | 
| +        ''' | 
| +library lib_a; | 
| +import 'b.dart'; | 
| +'''); | 
| +    newSource( | 
| +        '/b.dart', | 
| +        ''' | 
| +library lib_b; | 
| +'''); | 
| +    computeResult(sourceA, IS_CLIENT, | 
| +        matcher: isBuildSourceImportExportClosureTask); | 
| +    expect(outputs[IS_CLIENT], isFalse); | 
| +  } | 
| + | 
| +  test_perform_isClient_true_export_indirect() { | 
| +    newSource( | 
| +        '/exports_html.dart', | 
| +        ''' | 
| +library lib_exports_html; | 
| +export 'dart:html'; | 
| +'''); | 
| +    Source source = newSource( | 
| +        '/test.dart', | 
| +        ''' | 
| +import 'exports_html.dart'; | 
| +'''); | 
| +    computeResult(source, IS_CLIENT, | 
| +        matcher: isBuildSourceImportExportClosureTask); | 
| +    expect(outputs[IS_CLIENT], isTrue); | 
| +  } | 
| + | 
| +  test_perform_isClient_true_import_direct() { | 
| +    Source sourceA = newSource( | 
| +        '/a.dart', | 
| +        ''' | 
| +library lib_a; | 
| +import 'dart:html'; | 
| +'''); | 
| +    computeResult(sourceA, IS_CLIENT, | 
| +        matcher: isBuildSourceImportExportClosureTask); | 
| +    expect(outputs[IS_CLIENT], isTrue); | 
| +  } | 
| + | 
| +  test_perform_isClient_true_import_indirect() { | 
| +    Source sourceA = newSource( | 
| +        '/a.dart', | 
| +        ''' | 
| +library lib_a; | 
| +import 'b.dart'; | 
| +'''); | 
| +    newSource( | 
| +        '/b.dart', | 
| +        ''' | 
| +library lib_b; | 
| +import 'dart:html'; | 
| +'''); | 
| +    computeResult(sourceA, IS_CLIENT, | 
| +        matcher: isBuildSourceImportExportClosureTask); | 
| +    expect(outputs[IS_CLIENT], isTrue); | 
| +  } | 
| +} | 
| + | 
| +@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 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( | 
| +        new ConstantEvaluationTarget_Annotation( | 
| +            context, source, source, annotation), | 
| +        CONSTANT_DEPENDENCIES, | 
| +        matcher: isComputeConstantDependenciesTask); | 
| +    expect( | 
| +        outputs[CONSTANT_DEPENDENCIES].toSet(), [x, constructorForD].toSet()); | 
| +  } | 
| + | 
| +  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( | 
| +        new ConstantEvaluationTarget_Annotation( | 
| +            context, source, source, annotation), | 
| +        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_UNIT2); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT2]; | 
| +    // 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]; | 
| +        ConstantEvaluationTarget_Annotation target = | 
| +            new ConstantEvaluationTarget_Annotation( | 
| +                context, source, source, annotation); | 
| +        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'].intValue, 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.intValue, 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.intValue, 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.intValue, 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 = | 
| +          _findVariable(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 = _findVariable(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); | 
| +  } | 
| + | 
| +  PropertyInducingElement _findVariable( | 
| +      CompilationUnit unit, String variableName) { | 
| +    // Find the element for the given constant. | 
| +    return unit.element.topLevelVariables.firstWhere( | 
| +        (TopLevelVariableElement variable) => variable.name == variableName); | 
| +  } | 
| + | 
| +  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_perform() { | 
| +    AnalysisTarget source = newSource( | 
| +        '/test.dart', | 
| +        ''' | 
| +const a = b; | 
| +const b = 0; | 
| +'''); | 
| +    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); | 
| +    computeResult(target, RESOLVED_UNIT5); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    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]; | 
| +    expect(dependencies, unorderedEquals([elementB])); | 
| +  } | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class ComputeLibraryCycleTaskTest extends _AbstractDartTaskTest { | 
| +  @override | 
| +  void setUp() { | 
| +    super.setUp(); | 
| +    enableStrongMode(); | 
| +  } | 
| + | 
| +  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 = results[0][LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; | 
| +    expect(component0, hasLength(1)); | 
| +    expect(component1, hasLength(1)); | 
| + | 
| +    List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; | 
| +    expect(units0, hasLength(1)); | 
| +    expect(units1, hasLength(1)); | 
| + | 
| +    List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    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 = results[0][LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component2 = results[2][LIBRARY_CYCLE]; | 
| + | 
| +    expect(component0, hasLength(3)); | 
| +    expect(component1, hasLength(3)); | 
| +    expect(component2, hasLength(3)); | 
| + | 
| +    List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS]; | 
| +    expect(units0, hasLength(3)); | 
| +    expect(units1, hasLength(3)); | 
| +    expect(units2, hasLength(3)); | 
| + | 
| +    List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    expect(dep0, hasLength(1)); // dart:core | 
| +    expect(dep1, hasLength(1)); // dart:core | 
| +    expect(dep2, hasLength(1)); // dart:core | 
| +  } | 
| + | 
| +  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 = results[0][LIBRARY_CYCLE]; | 
| +    expect(component0, hasLength(1)); | 
| + | 
| +    List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; | 
| +    expect(units0, hasLength(1)); | 
| + | 
| +    List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    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 = outputs[LIBRARY_CYCLE]; | 
| +    List<CompilationUnitElement> units = outputs[LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> deps = outputs[LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    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 = results[0][LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component2 = results[2][LIBRARY_CYCLE]; | 
| +    expect(component0, hasLength(1)); | 
| +    expect(component1, hasLength(1)); | 
| +    expect(component2, hasLength(1)); | 
| + | 
| +    List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS]; | 
| +    expect(units0, hasLength(1)); | 
| +    expect(units1, hasLength(1)); | 
| +    expect(units2, hasLength(1)); | 
| + | 
| +    List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    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 = results[0][LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component2 = results[2][LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component3 = results[3][LIBRARY_CYCLE]; | 
| + | 
| +    expect(component0, hasLength(2)); | 
| +    expect(component1, hasLength(2)); | 
| +    expect(component2, hasLength(2)); | 
| +    expect(component3, hasLength(2)); | 
| + | 
| +    List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units3 = results[3][LIBRARY_CYCLE_UNITS]; | 
| +    expect(units0, hasLength(2)); | 
| +    expect(units1, hasLength(2)); | 
| +    expect(units2, hasLength(2)); | 
| +    expect(units3, hasLength(2)); | 
| + | 
| +    List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep3 = results[3][LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    expect(dep0, hasLength(1)); // dart:core | 
| +    expect(dep1, hasLength(1)); // dart:core | 
| +    expect(dep3, 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 = results0[LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component1 = results1[LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component2 = results2[LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component3 = results3[LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component4 = results4[LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component5 = results5[LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component6 = results6[LIBRARY_CYCLE]; | 
| +    List<LibraryElement> component7 = results7[LIBRARY_CYCLE]; | 
| + | 
| +    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 = results0[LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units1 = results1[LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units2 = results2[LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units3 = results3[LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units4 = results4[LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units5 = results5[LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units6 = results6[LIBRARY_CYCLE_UNITS]; | 
| +    List<CompilationUnitElement> units7 = results7[LIBRARY_CYCLE_UNITS]; | 
| +    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 = results0[LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep1 = results1[LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep2 = results2[LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep3 = results3[LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep4 = results4[LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep5 = results5[LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep6 = results6[LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    List<CompilationUnitElement> dep7 = results7[LIBRARY_CYCLE_DEPENDENCIES]; | 
| +    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 | 
| +  } | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class ContainingLibrariesTaskTest extends _AbstractDartTaskTest { | 
| +  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 = outputs[CONTAINING_LIBRARIES]; | 
| +    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 = outputs[CONTAINING_LIBRARIES]; | 
| +    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 = outputs[CONTAINING_LIBRARIES]; | 
| +    expect(containingLibraries, unorderedEquals([library])); | 
| +  } | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class DartErrorsTaskTest extends _AbstractDartTaskTest { | 
| +  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 = outputs[DART_ERRORS]; | 
| +    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 = outputs[DART_ERRORS]; | 
| +    // 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_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_UNIT, matcher: isEvaluateUnitConstantsTask); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT]; | 
| +    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() { | 
| +    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'])); | 
| +  } | 
| + | 
| +  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; | 
| + | 
| +  fail_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(); | 
| +  } | 
| + | 
| +  @override | 
| +  void tearDown() { | 
| +    LintGenerator.LINTERS.clear(); | 
| +    super.tearDown(); | 
| +  } | 
| + | 
| +  test_camel_case_types() { | 
| +    Source source = newSource( | 
| +        '/test.dart', | 
| +        ''' | 
| +class a { } | 
| +'''); | 
| + | 
| +    LintGenerator.LINTERS.clear(); | 
| +    LintGenerator.LINTERS.add(new GenerateLintsTaskTest_TestLinter()); | 
| + | 
| +    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 | 
| +  AstVisitor getVisitor() => new GenerateLintsTaskTest_AstVisitor(this); | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class InferInstanceMembersInUnitTaskTest extends _AbstractDartTaskTest { | 
| +  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_UNIT8, | 
| +        matcher: isInferInstanceMembersInUnitTask); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT8]; | 
| +    VariableDeclaration field = getFieldInClass(unit, 'B', 'f'); | 
| +    MethodDeclaration method = getMethodInClass(unit, 'B', 'm'); | 
| +    DartType typeX = getClass(unit, 'X').element.type; | 
| +    DartType typeY = getClass(unit, 'Y').element.type; | 
| +    DartType typeZ = 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_UNIT8, | 
| +        matcher: isInferInstanceMembersInUnitTask); | 
| +    CompilationUnit firstUnit = outputs[RESOLVED_UNIT8]; | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8); | 
| +    CompilationUnit secondUnit = outputs[RESOLVED_UNIT8]; | 
| + | 
| +    VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a'); | 
| +    VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b'); | 
| +    VariableDeclaration variableC = 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_UNIT8); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT8]; | 
| +    VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel'); | 
| +    VariableDeclaration fieldDecl = 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 { | 
| +  void test_perform_const_field() { | 
| +    enableStrongMode(); | 
| +    AnalysisTarget source = newSource( | 
| +        '/test.dart', | 
| +        ''' | 
| +class M { | 
| +  static const X = ""; | 
| +} | 
| +'''); | 
| +    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6, | 
| +        matcher: isInferStaticVariableTypesInUnitTask); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT6]; | 
| +    VariableDeclaration declaration = getFieldInClass(unit, 'M', 'X'); | 
| +    InterfaceType stringType = context.typeProvider.stringType; | 
| +    expect(declaration.element.type, stringType); | 
| +  } | 
| + | 
| +  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_UNIT6, | 
| +        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_UNIT6, | 
| +        matcher: isInferStaticVariableTypesInUnitTask); | 
| +    CompilationUnit firstUnit = outputs[RESOLVED_UNIT6]; | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT6); | 
| +    CompilationUnit secondUnit = outputs[RESOLVED_UNIT6]; | 
| + | 
| +    VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a'); | 
| +    VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b'); | 
| +    VariableDeclaration variableC = getTopLevelVariable(firstUnit, 'c'); | 
| +    ClassDeclaration classM = 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_UNIT6, | 
| +        matcher: isInferStaticVariableTypesInUnitTask); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT6]; | 
| +    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_UNIT5); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    VariableDeclaration declaration = 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_UNIT5); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    VariableDeclaration declaration = 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_UNIT5); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel3'); | 
| +    VariableDeclaration fieldDecl = 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_UNIT5); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    VariableElement topLevel = | 
| +        getTopLevelVariable(unit, 'topLevel').name.staticElement; | 
| +    VariableElement field = | 
| +        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_UNIT5); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    VariableElement piFirst = | 
| +        getTopLevelVariable(unit, 'piFirst').name.staticElement; | 
| +    VariableElement pi = getTopLevelVariable(unit, 'pi').name.staticElement; | 
| +    VariableElement tau = 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_UNIT5); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    VariableElement a = 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_UNIT5); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    VariableElement a = 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 { | 
| +  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 = outputs[LIBRARY_UNIT_ERRORS]; | 
| +    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 = outputs[LIBRARY_UNIT_ERRORS]; | 
| +    expect(errors, hasLength(0)); | 
| +  } | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class ParseDartTaskTest extends _AbstractDartTaskTest { | 
| +  Source source; | 
| + | 
| +  test_perform() { | 
| +    _performParseTask(r''' | 
| +part of lib; | 
| +class B {}'''); | 
| +    expect(outputs, hasLength(8)); | 
| +    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[PARSE_ERRORS], hasLength(0)); | 
| +    expect(outputs[PARSED_UNIT], isNotNull); | 
| +    expect(outputs[SOURCE_KIND], SourceKind.PART); | 
| +    expect(outputs[UNITS], hasLength(1)); | 
| +  } | 
| + | 
| +  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(8)); | 
| +    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[PARSE_ERRORS], hasLength(0)); | 
| +    expect(outputs[PARSED_UNIT], isNotNull); | 
| +    expect(outputs[SOURCE_KIND], SourceKind.UNKNOWN); | 
| +    expect(outputs[UNITS], hasLength(1)); | 
| +  } | 
| + | 
| +  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(8)); | 
| +    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[PARSE_ERRORS], hasLength(2)); | 
| +    expect(outputs[PARSED_UNIT], isNotNull); | 
| +    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY); | 
| +    expect(outputs[UNITS], hasLength(2)); | 
| +  } | 
| + | 
| +  test_perform_library() { | 
| +    _performParseTask(r''' | 
| +library lib; | 
| +import 'lib2.dart'; | 
| +export 'lib3.dart'; | 
| +part 'part.dart'; | 
| +class A {'''); | 
| +    expect(outputs, hasLength(8)); | 
| +    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[PARSE_ERRORS], hasLength(1)); | 
| +    expect(outputs[PARSED_UNIT], isNotNull); | 
| +    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY); | 
| +    expect(outputs[UNITS], hasLength(2)); | 
| +  } | 
| + | 
| +  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(8)); | 
| +    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[PARSE_ERRORS], hasLength(0)); | 
| +    expect(outputs[PARSED_UNIT], isNotNull); | 
| +    expect(outputs[SOURCE_KIND], SourceKind.PART); | 
| +    expect(outputs[UNITS], hasLength(1)); | 
| +  } | 
| + | 
| +  void _performParseTask(String content) { | 
| +    source = newSource('/test.dart', content); | 
| +    computeResult(source, PARSED_UNIT, matcher: isParseDartTask); | 
| +  } | 
| + | 
| +  static void _assertHasCore(List<Source> sources, int lenght) { | 
| +    expect(sources, hasLength(lenght)); | 
| +    expect(sources, contains(predicate((Source s) { | 
| +      return s.fullName.endsWith('core.dart'); | 
| +    }))); | 
| +  } | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class PartiallyResolveUnitReferencesTaskTest extends _AbstractDartTaskTest { | 
| +  test_perform() { | 
| +    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_UNIT5, | 
| +        matcher: isPartiallyResolveUnitReferencesTask); | 
| +    // Test the outputs | 
| +    expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(4)); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    expect(unit, same(outputs[RESOLVED_UNIT5])); | 
| +    // 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_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_UNIT5, | 
| +        matcher: isPartiallyResolveUnitReferencesTask); | 
| +    // validate | 
| +    expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(0)); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    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_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_UNIT5, | 
| +        matcher: isPartiallyResolveUnitReferencesTask); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT5]; | 
| +    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 ResolveInstanceFieldsInUnitTaskTest extends _AbstractDartTaskTest { | 
| +  @override | 
| +  void setUp() { | 
| +    super.setUp(); | 
| +    enableStrongMode(); | 
| +  } | 
| + | 
| +  // 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_UNIT7); | 
| +    CompilationUnit unit1 = outputs[RESOLVED_UNIT7]; | 
| + | 
| +    // B.b2 shoud be resolved on the rhs, but not yet inferred. | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "B", "b2"), dynamicType, intType); | 
| + | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); | 
| +    CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; | 
| + | 
| +    // B.b2 should now be fully resolved and inferred. | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "B", "b2"), intType, intType); | 
| + | 
| +    // A.a2 should now be resolved on the rhs, but not yet inferred. | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a2"), dynamicType, intType); | 
| + | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7); | 
| +    CompilationUnit unit2 = outputs[RESOLVED_UNIT7]; | 
| + | 
| +    // A.a2 should now be fully resolved and inferred. | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a2"), intType, intType); | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        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; | 
| +          } | 
| +    ''' | 
| +    }); | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| +    DartType dynamicType = context.typeProvider.dynamicType; | 
| + | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); | 
| +    CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; | 
| + | 
| +    // A.a2 should now be resolved on the rhs, but not yet inferred. | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); | 
| + | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7); | 
| +    CompilationUnit unit2 = outputs[RESOLVED_UNIT7]; | 
| + | 
| +    // A.a2 should now be fully resolved and inferred. | 
| +    assertVariableDeclarationTypes( | 
| +        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_UNIT7); | 
| +    CompilationUnit unit1 = outputs[RESOLVED_UNIT7]; | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "B", "b1"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "B", "b2"), dynamicType, intType); | 
| + | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); | 
| +    CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a1"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a2"), dynamicType, intType); | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "B", "b1"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "B", "b2"), intType, intType); | 
| + | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7); | 
| +    CompilationUnit unit2 = outputs[RESOLVED_UNIT7]; | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a1"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a2"), intType, intType); | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "B", "b1"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        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_UNIT7); | 
| +    CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; | 
| + | 
| +    // A.a2 should now be resolved on the rhs, but not yet inferred. | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); | 
| + | 
| +    // B.b2 shoud be resolved on the rhs, but not yet inferred. | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "B", "b2"), dynamicType, intType); | 
| + | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7); | 
| +    CompilationUnit unit1 = outputs[RESOLVED_UNIT7]; | 
| + | 
| +    // A.a2 should now be fully resolved and inferred. | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); | 
| + | 
| +    // B.b2 should now be fully resolved and inferred. | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "B", "b2"), intType, intType); | 
| +  } | 
| +} | 
| + | 
| +@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_ELEMENT5, | 
| +        matcher: isResolveLibraryTypeNamesTask); | 
| +    // validate | 
| +    LibraryElement library = outputs[LIBRARY_ELEMENT5]; | 
| +    { | 
| +      ClassElement classB = library.getType('B'); | 
| +      expect(classB.supertype.displayName, 'A'); | 
| +    } | 
| +    { | 
| +      ClassElement classC = library.getType('C'); | 
| +      expect(classC.supertype.displayName, 'A'); | 
| +    } | 
| +  } | 
| + | 
| +  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_ELEMENT5, | 
| +        matcher: isResolveLibraryTypeNamesTask); | 
| +    // validate | 
| +    LibraryElement library = outputs[LIBRARY_ELEMENT5]; | 
| +    { | 
| +      ClassElement clazz = library.getType('A'); | 
| +      expect(clazz.displayName, 'A'); | 
| +      clazz = clazz.supertype.element; | 
| +      expect(clazz.displayName, 'B'); | 
| +    } | 
| +  } | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class ResolveUnitTaskTest extends _AbstractDartTaskTest { | 
| +  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_UNIT9, | 
| +        matcher: isResolveUnitTask); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT9]; | 
| + | 
| +    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 _assertResolved(FunctionBody body) { | 
| +    ResolutionVerifier verifier = new ResolutionVerifier(); | 
| +    body.accept(verifier); | 
| +    verifier.assertResolved(); | 
| +  } | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest { | 
| +  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_UNIT3, matcher: isResolveUnitTypeNamesTask); | 
| +    // validate | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT3]; | 
| +    { | 
| +      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_UNIT3, matcher: isResolveUnitTypeNamesTask); | 
| +    // validate | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT3]; | 
| +    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(VariableElement variable, Matcher mutatedInClosure, | 
| +      Matcher mutatedInScope) { | 
| +    expect(variable.isPotentiallyMutatedInClosure, mutatedInClosure); | 
| +    expect(variable.isPotentiallyMutatedInScope, mutatedInScope); | 
| +  } | 
| + | 
| +  test_perform_buildClosureLibraryElements() { | 
| +    Source source = newSource( | 
| +        '/test.dart', | 
| +        ''' | 
| +main() { | 
| +} | 
| +'''); | 
| +    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); | 
| +    computeResult(target, RESOLVED_UNIT4, | 
| +        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_UNIT4, | 
| +        matcher: isResolveVariableReferencesTask); | 
| +    // validate | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT4]; | 
| +    FunctionElement main = unit.element.functions[0]; | 
| +    expectMutated(main.localVariables[0], isFalse, isFalse); | 
| +    expectMutated(main.localVariables[1], isFalse, isTrue); | 
| +    expectMutated(main.localVariables[2], isTrue, isTrue); | 
| +    expectMutated(main.localVariables[3], isTrue, isTrue); | 
| +  } | 
| + | 
| +  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_UNIT4, | 
| +        matcher: isResolveVariableReferencesTask); | 
| +    // validate | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT4]; | 
| +    FunctionElement main = unit.element.functions[0]; | 
| +    expectMutated(main.parameters[0], isFalse, isFalse); | 
| +    expectMutated(main.parameters[1], isFalse, isTrue); | 
| +    expectMutated(main.parameters[2], isTrue, isTrue); | 
| +    expectMutated(main.parameters[3], isTrue, isTrue); | 
| +  } | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class ScanDartTaskTest extends _AbstractDartTaskTest { | 
| +  test_perform_errors() { | 
| +    _performScanTask('import "'); | 
| +    expect(outputs, hasLength(3)); | 
| +    expect(outputs[LINE_INFO], isNotNull); | 
| +    expect(outputs[SCAN_ERRORS], hasLength(1)); | 
| +    expect(outputs[TOKEN_STREAM], isNotNull); | 
| +  } | 
| + | 
| +  test_perform_noErrors() { | 
| +    _performScanTask('class A {}'); | 
| +    expect(outputs, hasLength(3)); | 
| +    expect(outputs[LINE_INFO], isNotNull); | 
| +    expect(outputs[SCAN_ERRORS], hasLength(0)); | 
| +    expect(outputs[TOKEN_STREAM], isNotNull); | 
| +  } | 
| + | 
| +  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_UNIT9); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT9]; | 
| +    VariableElement piFirst = | 
| +        getTopLevelVariable(unit, 'piFirst').name.staticElement; | 
| +    VariableElement pi = getTopLevelVariable(unit, 'pi').name.staticElement; | 
| +    VariableElement tau = getTopLevelVariable(unit, 'tau').name.staticElement; | 
| +    Expression piFirstUse = (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_UNIT9); | 
| +    CompilationUnit unit1 = outputs[RESOLVED_UNIT9]; | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9); | 
| +    CompilationUnit unit2 = outputs[RESOLVED_UNIT9]; | 
| + | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getTopLevelVariable(unit1, "x"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "A", "x"), intType, intType); | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getTopLevelVariable(unit2, "y"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit2, "B", "y"), intType, intType); | 
| + | 
| +    List<Statement> statements = | 
| +        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_UNIT9).toList(); | 
| +    CompilationUnit unit0 = units[0]; | 
| +    CompilationUnit unit1 = units[1]; | 
| +    CompilationUnit unit2 = units[2]; | 
| + | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a2"), intType, intType); | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "B", "b2"), intType, intType); | 
| + | 
| +    List<Statement> statements = | 
| +        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_UNIT9).toList(); | 
| +    CompilationUnit unit0 = units[0]; | 
| +    CompilationUnit unit1 = units[1]; | 
| +    CompilationUnit unit2 = units[2]; | 
| + | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| +    InterfaceType stringType = context.typeProvider.stringType; | 
| + | 
| +    assertVariableDeclarationStatementTypes( | 
| +        getStatementsInTopLevelFunction(unit0, "foo")[0], stringType, intType); | 
| +    assertVariableDeclarationStatementTypes( | 
| +        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_UNIT9); | 
| +    CompilationUnit unit1 = outputs[RESOLVED_UNIT9]; | 
| +    computeResult( | 
| +        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9); | 
| +    CompilationUnit unit2 = outputs[RESOLVED_UNIT9]; | 
| + | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| +    InterfaceType stringType = context.typeProvider.stringType; | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getTopLevelVariable(unit1, "x"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "A", "x"), intType, intType); | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getTopLevelVariable(unit2, "y"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit2, "B", "y"), intType, intType); | 
| + | 
| +    List<Statement> statements = | 
| +        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_UNIT9).toList(); | 
| +    CompilationUnit unit0 = units[0]; | 
| +    CompilationUnit unit1 = units[1]; | 
| +    CompilationUnit unit2 = units[2]; | 
| + | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a1"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit0, "A", "a2"), intType, intType); | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "B", "b1"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit1, "B", "b2"), intType, intType); | 
| + | 
| +    List<Statement> statements = | 
| +        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_UNIT9); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT9]; | 
| + | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| +    InterfaceType stringType = context.typeProvider.stringType; | 
| + | 
| +    List<Statement> statements = 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_UNIT9); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT9]; | 
| + | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| +    InterfaceType stringType = context.typeProvider.stringType; | 
| + | 
| +    List<Statement> statements = 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( | 
| +        getFieldInClass(unit, "A", "x"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        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_UNIT9); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT9]; | 
| + | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| +    InterfaceType stringType = context.typeProvider.stringType; | 
| + | 
| +    List<Statement> statements = 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( | 
| +        getTopLevelVariable(unit, "x"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getTopLevelVariable(unit, "y"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        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_UNIT9); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT9]; | 
| + | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| +    InterfaceType stringType = context.typeProvider.stringType; | 
| +    DartType bottomType = context.typeProvider.bottomType; | 
| +    DartType dynamicType = context.typeProvider.dynamicType; | 
| + | 
| +    assertVariableDeclarationTypes( | 
| +        getTopLevelVariable(unit, "x"), dynamicType, bottomType); | 
| +    assertVariableDeclarationTypes( | 
| +        getTopLevelVariable(unit, "y"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit, "A", "x"), dynamicType, bottomType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit, "A", "y"), intType, intType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit, "A", "x2"), dynamicType, bottomType); | 
| +    assertVariableDeclarationTypes( | 
| +        getFieldInClass(unit, "A", "y2"), intType, intType); | 
| + | 
| +    List<Statement> statements = 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_UNIT9); | 
| +    CompilationUnit unit = outputs[RESOLVED_UNIT9]; | 
| + | 
| +    InterfaceType intType = context.typeProvider.intType; | 
| +    InterfaceType stringType = context.typeProvider.stringType; | 
| + | 
| +    List<Statement> statements = 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 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_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); | 
| +    errorListener.assertErrorsWithCodes( | 
| +        <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; | 
| +  } | 
| + | 
| +  /** | 
| +   * Return the declaration of the class with the given [className] in the given | 
| +   * compilation [unit]. | 
| +   */ | 
| +  ClassDeclaration getClass(CompilationUnit unit, String className) { | 
| +    NodeList<CompilationUnitMember> unitMembers = unit.declarations; | 
| +    for (CompilationUnitMember unitMember in unitMembers) { | 
| +      if (unitMember is ClassDeclaration && unitMember.name.name == className) { | 
| +        return unitMember; | 
| +      } | 
| +    } | 
| +    fail('No class named $className in ${unit.element.source}'); | 
| +    return null; | 
| +  } | 
| + | 
| +  /** | 
| +   * Return the declaration of the field with the given [fieldName] in the class | 
| +   * with the given [className] in the given compilation [unit]. | 
| +   */ | 
| +  VariableDeclaration getFieldInClass( | 
| +      CompilationUnit unit, String className, String fieldName) { | 
| +    ClassDeclaration unitMember = getClass(unit, className); | 
| +    NodeList<ClassMember> classMembers = unitMember.members; | 
| +    for (ClassMember classMember in classMembers) { | 
| +      if (classMember is FieldDeclaration) { | 
| +        NodeList<VariableDeclaration> fields = classMember.fields.variables; | 
| +        for (VariableDeclaration field in fields) { | 
| +          if (field.name.name == fieldName) { | 
| +            return field; | 
| +          } | 
| +        } | 
| +      } | 
| +    } | 
| +    fail('No field named $fieldName in $className'); | 
| +    return null; | 
| +  } | 
| + | 
| +  /** | 
| +   * Return the declaration of the method with the given [methodName] in the | 
| +   * class with the given [className] in the given compilation [unit]. | 
| +   */ | 
| +  MethodDeclaration getMethodInClass( | 
| +      CompilationUnit unit, String className, String methodName) { | 
| +    ClassDeclaration unitMember = getClass(unit, className); | 
| +    NodeList<ClassMember> classMembers = unitMember.members; | 
| +    for (ClassMember classMember in classMembers) { | 
| +      if (classMember is MethodDeclaration) { | 
| +        if (classMember.name.name == methodName) { | 
| +          return classMember; | 
| +        } | 
| +      } | 
| +    } | 
| +    fail('No method named $methodName in $className'); | 
| +    return null; | 
| +  } | 
| + | 
| +  List<Statement> getStatementsInMethod( | 
| +      CompilationUnit unit, String className, String methodName) { | 
| +    MethodDeclaration method = getMethodInClass(unit, className, methodName); | 
| +    BlockFunctionBody body = method.body; | 
| +    return body.block.statements; | 
| +  } | 
| + | 
| +  List<Statement> getStatementsInTopLevelFunction( | 
| +      CompilationUnit unit, String functionName) { | 
| +    FunctionDeclaration function = getTopLevelFunction(unit, functionName); | 
| +    BlockFunctionBody body = function.functionExpression.body; | 
| +    return body.block.statements; | 
| +  } | 
| + | 
| +  /** | 
| +   * Return the declaration of the top-level function with the given | 
| +   * [functionName] in the given compilation [unit]. | 
| +   */ | 
| +  FunctionDeclaration getTopLevelFunction( | 
| +      CompilationUnit unit, String functionName) { | 
| +    NodeList<CompilationUnitMember> unitMembers = unit.declarations; | 
| +    for (CompilationUnitMember unitMember in unitMembers) { | 
| +      if (unitMember is FunctionDeclaration) { | 
| +        if (unitMember.name.name == functionName) { | 
| +          return unitMember; | 
| +        } | 
| +      } | 
| +    } | 
| +    return null; | 
| +  } | 
| + | 
| +  /** | 
| +   * Return the declaration of the top-level variable with the given | 
| +   * [variableName] in the given compilation [unit]. | 
| +   */ | 
| +  VariableDeclaration getTopLevelVariable( | 
| +      CompilationUnit unit, String variableName) { | 
| +    NodeList<CompilationUnitMember> unitMembers = unit.declarations; | 
| +    for (CompilationUnitMember unitMember in unitMembers) { | 
| +      if (unitMember is TopLevelVariableDeclaration) { | 
| +        NodeList<VariableDeclaration> variables = | 
| +            unitMember.variables.variables; | 
| +        for (VariableDeclaration variable in variables) { | 
| +          if (variable.name.name == variableName) { | 
| +            return variable; | 
| +          } | 
| +        } | 
| +      } | 
| +    } | 
| +    return null; | 
| +  } | 
| + | 
| +  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]; | 
| +    expect(errors, isNotNull, reason: result.name); | 
| +    errorListener = new GatheringErrorListener(); | 
| +    errorListener.addAll(errors); | 
| +  } | 
| +} | 
|  |