| Index: packages/analyzer/test/src/context/context_test.dart | 
| diff --git a/packages/analyzer/test/src/context/context_test.dart b/packages/analyzer/test/src/context/context_test.dart | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..0544bf56789d0e1808811cd27d21d7b1d1996e64 | 
| --- /dev/null | 
| +++ b/packages/analyzer/test/src/context/context_test.dart | 
| @@ -0,0 +1,2524 @@ | 
| +// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file | 
| +// for details. All rights reserved. Use of this source code is governed by a | 
| +// BSD-style license that can be found in the LICENSE file. | 
| + | 
| +library test.src.context.context_test; | 
| + | 
| +import 'dart:async'; | 
| + | 
| +import 'package:analyzer/file_system/memory_file_system.dart'; | 
| +import 'package:analyzer/src/cancelable_future.dart'; | 
| +import 'package:analyzer/src/context/cache.dart'; | 
| +import 'package:analyzer/src/context/context.dart'; | 
| +import 'package:analyzer/src/generated/ast.dart'; | 
| +import 'package:analyzer/src/generated/element.dart'; | 
| +import 'package:analyzer/src/generated/engine.dart' | 
| +    show | 
| +        AnalysisContext, | 
| +        AnalysisContextStatistics, | 
| +        AnalysisDelta, | 
| +        AnalysisEngine, | 
| +        AnalysisErrorInfo, | 
| +        AnalysisLevel, | 
| +        AnalysisNotScheduledError, | 
| +        AnalysisOptions, | 
| +        AnalysisOptionsImpl, | 
| +        AnalysisResult, | 
| +        CacheState, | 
| +        ChangeNotice, | 
| +        ChangeSet, | 
| +        IncrementalAnalysisCache, | 
| +        TimestampedData; | 
| +import 'package:analyzer/src/generated/error.dart'; | 
| +import 'package:analyzer/src/generated/java_engine.dart'; | 
| +import 'package:analyzer/src/generated/resolver.dart'; | 
| +import 'package:analyzer/src/generated/scanner.dart'; | 
| +import 'package:analyzer/src/generated/source.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/model.dart'; | 
| +import 'package:html/dom.dart' show Document; | 
| +import 'package:unittest/unittest.dart'; | 
| +import 'package:watcher/src/utils.dart'; | 
| + | 
| +import '../../generated/engine_test.dart'; | 
| +import '../../generated/test_support.dart'; | 
| +import '../../reflective_tests.dart'; | 
| +import '../../utils.dart'; | 
| +import 'abstract_context.dart'; | 
| + | 
| +main() { | 
| +  initializeTestEnvironment(); | 
| +  runReflectiveTests(AnalysisContextImplTest); | 
| +  runReflectiveTests(LimitedInvalidateTest); | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class AnalysisContextImplTest extends AbstractContextTest { | 
| +  Future fail_implicitAnalysisEvents_removed() async { | 
| +    AnalyzedSourcesListener listener = new AnalyzedSourcesListener(); | 
| +    context.implicitAnalysisEvents.listen(listener.onData); | 
| +    // | 
| +    // Create a file that references an file that is not explicitly being | 
| +    // analyzed and fully analyze it. Ensure that the listener is told about | 
| +    // the implicitly analyzed file. | 
| +    // | 
| +    Source sourceA = newSource('/a.dart', "library a; import 'b.dart';"); | 
| +    Source sourceB = newSource('/b.dart', "library b;"); | 
| +    ChangeSet changeSet = new ChangeSet(); | 
| +    changeSet.addedSource(sourceA); | 
| +    context.applyChanges(changeSet); | 
| +    context.computeErrors(sourceA); | 
| +    await pumpEventQueue(); | 
| +    listener.expectAnalyzed(sourceB); | 
| +    // | 
| +    // Remove the reference and ensure that the listener is told that we're no | 
| +    // longer implicitly analyzing the file. | 
| +    // | 
| +    context.setContents(sourceA, "library a;"); | 
| +    context.computeErrors(sourceA); | 
| +    await pumpEventQueue(); | 
| +    listener.expectNotAnalyzed(sourceB); | 
| +  } | 
| + | 
| +  void fail_performAnalysisTask_importedLibraryDelete_html() { | 
| +    // NOTE: This was failing before converting to the new task model. | 
| +    Source htmlSource = addSource( | 
| +        "/page.html", | 
| +        r''' | 
| +<html><body><script type="application/dart"> | 
| +  import 'libB.dart'; | 
| +  main() {print('hello dart');} | 
| +</script></body></html>'''); | 
| +    Source libBSource = addSource("/libB.dart", "library libB;"); | 
| +    _analyzeAll_assertFinished(); | 
| +    context.computeErrors(htmlSource); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, | 
| +        reason: "libB resolved 1"); | 
| +    expect(!_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)), | 
| +        isTrue, | 
| +        reason: "htmlSource doesn't have errors"); | 
| +    // remove libB.dart content and analyze | 
| +    context.setContents(libBSource, null); | 
| +    _analyzeAll_assertFinished(); | 
| +    context.computeErrors(htmlSource); | 
| +    AnalysisErrorInfo errors = context.getErrors(htmlSource); | 
| +    expect(_hasAnalysisErrorWithErrorSeverity(errors), isTrue, | 
| +        reason: "htmlSource has an error"); | 
| +  } | 
| + | 
| +  void fail_recordLibraryElements() { | 
| +    fail("Implement this"); | 
| +  } | 
| + | 
| +  @override | 
| +  void tearDown() { | 
| +    context = null; | 
| +    sourceFactory = null; | 
| +    super.tearDown(); | 
| +  } | 
| + | 
| +  Future test_applyChanges_add() { | 
| +    SourcesChangedListener listener = new SourcesChangedListener(); | 
| +    context.onSourcesChanged.listen(listener.onData); | 
| +    expect(context.sourcesNeedingProcessing, isEmpty); | 
| +    Source source = newSource('/test.dart'); | 
| +    ChangeSet changeSet = new ChangeSet(); | 
| +    changeSet.addedSource(source); | 
| +    context.applyChanges(changeSet); | 
| +    expect(context.sourcesNeedingProcessing, contains(source)); | 
| +    return pumpEventQueue().then((_) { | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertNoMoreEvents(); | 
| +    }); | 
| +  } | 
| + | 
| +  Future test_applyChanges_change() { | 
| +    SourcesChangedListener listener = new SourcesChangedListener(); | 
| +    context.onSourcesChanged.listen(listener.onData); | 
| +    expect(context.sourcesNeedingProcessing, isEmpty); | 
| +    Source source = newSource('/test.dart'); | 
| +    ChangeSet changeSet1 = new ChangeSet(); | 
| +    changeSet1.addedSource(source); | 
| +    context.applyChanges(changeSet1); | 
| +    expect(context.sourcesNeedingProcessing, contains(source)); | 
| +    Source source2 = newSource('/test2.dart'); | 
| +    ChangeSet changeSet2 = new ChangeSet(); | 
| +    changeSet2.addedSource(source2); | 
| +    changeSet2.changedSource(source); | 
| +    context.applyChanges(changeSet2); | 
| +    return pumpEventQueue().then((_) { | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]); | 
| +      listener.assertNoMoreEvents(); | 
| +    }); | 
| +  } | 
| + | 
| +  Future test_applyChanges_change_content() { | 
| +    SourcesChangedListener listener = new SourcesChangedListener(); | 
| +    context.onSourcesChanged.listen(listener.onData); | 
| +    expect(context.sourcesNeedingProcessing, isEmpty); | 
| +    Source source = newSource('/test.dart'); | 
| +    ChangeSet changeSet1 = new ChangeSet(); | 
| +    changeSet1.addedSource(source); | 
| +    context.applyChanges(changeSet1); | 
| +    expect(context.sourcesNeedingProcessing, contains(source)); | 
| +    Source source2 = newSource('/test2.dart'); | 
| +    ChangeSet changeSet2 = new ChangeSet(); | 
| +    changeSet2.addedSource(source2); | 
| +    changeSet2.changedContent(source, 'library test;'); | 
| +    context.applyChanges(changeSet2); | 
| +    return pumpEventQueue().then((_) { | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]); | 
| +      listener.assertNoMoreEvents(); | 
| +    }); | 
| +  } | 
| + | 
| +  void test_applyChanges_change_flush_element() { | 
| +    Source librarySource = addSource( | 
| +        "/lib.dart", | 
| +        r''' | 
| +library lib; | 
| +int a = 0;'''); | 
| +    expect(context.computeLibraryElement(librarySource), isNotNull); | 
| +    context.setContents( | 
| +        librarySource, | 
| +        r''' | 
| +library lib; | 
| +int aa = 0;'''); | 
| +    expect(context.getLibraryElement(librarySource), isNull); | 
| +  } | 
| + | 
| +  Future test_applyChanges_change_multiple() { | 
| +    SourcesChangedListener listener = new SourcesChangedListener(); | 
| +    context.onSourcesChanged.listen(listener.onData); | 
| +    String libraryContents1 = r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +int a = 0;'''; | 
| +    Source librarySource = addSource("/lib.dart", libraryContents1); | 
| +    String partContents1 = r''' | 
| +part of lib; | 
| +int b = a;'''; | 
| +    Source partSource = addSource("/part.dart", partContents1); | 
| +    context.computeLibraryElement(librarySource); | 
| +    String libraryContents2 = r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +int aa = 0;'''; | 
| +    context.setContents(librarySource, libraryContents2); | 
| +    String partContents2 = r''' | 
| +part of lib; | 
| +int b = aa;'''; | 
| +    context.setContents(partSource, partContents2); | 
| +    context.computeLibraryElement(librarySource); | 
| +    CompilationUnit libraryUnit = | 
| +        context.resolveCompilationUnit2(librarySource, librarySource); | 
| +    expect(libraryUnit, isNotNull); | 
| +    CompilationUnit partUnit = | 
| +        context.resolveCompilationUnit2(partSource, librarySource); | 
| +    expect(partUnit, isNotNull); | 
| +    TopLevelVariableDeclaration declaration = | 
| +        libraryUnit.declarations[0] as TopLevelVariableDeclaration; | 
| +    Element declarationElement = declaration.variables.variables[0].element; | 
| +    TopLevelVariableDeclaration use = | 
| +        partUnit.declarations[0] as TopLevelVariableDeclaration; | 
| +    Element useElement = (use.variables.variables[0].initializer | 
| +        as SimpleIdentifier).staticElement; | 
| +    expect((useElement as PropertyAccessorElement).variable, | 
| +        same(declarationElement)); | 
| +    return pumpEventQueue().then((_) { | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(changedSources: [librarySource]); | 
| +      listener.assertEvent(changedSources: [partSource]); | 
| +      listener.assertNoMoreEvents(); | 
| +    }); | 
| +  } | 
| + | 
| +  Future test_applyChanges_change_range() { | 
| +    SourcesChangedListener listener = new SourcesChangedListener(); | 
| +    context.onSourcesChanged.listen(listener.onData); | 
| +    expect(context.sourcesNeedingProcessing, isEmpty); | 
| +    Source source = newSource('/test.dart'); | 
| +    ChangeSet changeSet1 = new ChangeSet(); | 
| +    changeSet1.addedSource(source); | 
| +    context.applyChanges(changeSet1); | 
| +    expect(context.sourcesNeedingProcessing, contains(source)); | 
| +    Source source2 = newSource('/test2.dart'); | 
| +    ChangeSet changeSet2 = new ChangeSet(); | 
| +    changeSet2.addedSource(source2); | 
| +    changeSet2.changedRange(source, 'library test;', 0, 0, 13); | 
| +    context.applyChanges(changeSet2); | 
| +    return pumpEventQueue().then((_) { | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]); | 
| +      listener.assertNoMoreEvents(); | 
| +    }); | 
| +  } | 
| + | 
| +  void test_applyChanges_empty() { | 
| +    context.applyChanges(new ChangeSet()); | 
| +    expect(context.performAnalysisTask().changeNotices, isNull); | 
| +  } | 
| + | 
| +  void test_applyChanges_overriddenSource() { | 
| +    // Note: addSource adds the source to the contentCache. | 
| +    Source source = addSource("/test.dart", "library test;"); | 
| +    context.computeErrors(source); | 
| +    while (!context.sourcesNeedingProcessing.isEmpty) { | 
| +      context.performAnalysisTask(); | 
| +    } | 
| +    // Adding the source as a changedSource should have no effect since | 
| +    // it is already overridden in the content cache. | 
| +    ChangeSet changeSet = new ChangeSet(); | 
| +    changeSet.changedSource(source); | 
| +    context.applyChanges(changeSet); | 
| +    expect(context.sourcesNeedingProcessing, hasLength(0)); | 
| +  } | 
| + | 
| +  Future test_applyChanges_remove() { | 
| +    SourcesChangedListener listener = new SourcesChangedListener(); | 
| +    context.onSourcesChanged.listen(listener.onData); | 
| +    String libAContents = r''' | 
| +library libA; | 
| +import 'libB.dart';'''; | 
| +    Source libA = addSource("/libA.dart", libAContents); | 
| +    String libBContents = "library libB;"; | 
| +    Source libB = addSource("/libB.dart", libBContents); | 
| +    LibraryElement libAElement = context.computeLibraryElement(libA); | 
| +    expect(libAElement, isNotNull); | 
| +    List<LibraryElement> importedLibraries = libAElement.importedLibraries; | 
| +    expect(importedLibraries, hasLength(2)); | 
| +    context.computeErrors(libA); | 
| +    context.computeErrors(libB); | 
| +    expect(context.sourcesNeedingProcessing, hasLength(0)); | 
| +    context.setContents(libB, null); | 
| +    _removeSource(libB); | 
| +    List<Source> sources = context.sourcesNeedingProcessing; | 
| +    expect(sources, hasLength(1)); | 
| +    expect(sources[0], same(libA)); | 
| +    libAElement = context.computeLibraryElement(libA); | 
| +    importedLibraries = libAElement.importedLibraries; | 
| +    expect(importedLibraries, hasLength(1)); | 
| +    return pumpEventQueue().then((_) { | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(wereSourcesRemovedOrDeleted: true); | 
| +      listener.assertNoMoreEvents(); | 
| +    }); | 
| +  } | 
| + | 
| +  /** | 
| +   * IDEA uses the following scenario: | 
| +   * 1. Add overlay. | 
| +   * 2. Change overlay. | 
| +   * 3. If the contents of the document buffer is the same as the contents | 
| +   *    of the file, remove overlay. | 
| +   * So, we need to try to use incremental resolution for removing overlays too. | 
| +   */ | 
| +  void test_applyChanges_remove_incremental() { | 
| +    MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); | 
| +    Source source = resourceProvider | 
| +        .newFile( | 
| +            '/test.dart', | 
| +            r''' | 
| +main() { | 
| +  print(1); | 
| +} | 
| +''') | 
| +        .createSource(); | 
| +    context.analysisOptions = new AnalysisOptionsImpl()..incremental = true; | 
| +    context.applyChanges(new ChangeSet()..addedSource(source)); | 
| +    // remember compilation unit | 
| +    _analyzeAll_assertFinished(); | 
| +    CompilationUnit unit = context.getResolvedCompilationUnit2(source, source); | 
| +    // add overlay | 
| +    context.setContents( | 
| +        source, | 
| +        r''' | 
| +main() { | 
| +  print(12); | 
| +} | 
| +'''); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(source, source), unit); | 
| +    // remove overlay | 
| +    context.setContents(source, null); | 
| +    context.validateCacheConsistency(); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(source, source), unit); | 
| +  } | 
| + | 
| +  Future test_applyChanges_removeContainer() { | 
| +    SourcesChangedListener listener = new SourcesChangedListener(); | 
| +    context.onSourcesChanged.listen(listener.onData); | 
| +    String libAContents = r''' | 
| +library libA; | 
| +import 'libB.dart';'''; | 
| +    Source libA = addSource("/libA.dart", libAContents); | 
| +    String libBContents = "library libB;"; | 
| +    Source libB = addSource("/libB.dart", libBContents); | 
| +    context.computeLibraryElement(libA); | 
| +    context.computeErrors(libA); | 
| +    context.computeErrors(libB); | 
| +    expect(context.sourcesNeedingProcessing, hasLength(0)); | 
| +    ChangeSet changeSet = new ChangeSet(); | 
| +    SourceContainer removedContainer = | 
| +        new _AnalysisContextImplTest_test_applyChanges_removeContainer(libB); | 
| +    changeSet.removedContainer(removedContainer); | 
| +    context.applyChanges(changeSet); | 
| +    List<Source> sources = context.sourcesNeedingProcessing; | 
| +    expect(sources, hasLength(1)); | 
| +    expect(sources[0], same(libA)); | 
| +    return pumpEventQueue().then((_) { | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(wereSourcesRemovedOrDeleted: true); | 
| +      listener.assertNoMoreEvents(); | 
| +    }); | 
| +  } | 
| + | 
| +  void test_computeDocumentationComment_block() { | 
| +    String comment = "/** Comment */"; | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        """ | 
| +$comment | 
| +class A {}"""); | 
| +    LibraryElement libraryElement = context.computeLibraryElement(source); | 
| +    expect(libraryElement, isNotNull); | 
| +    ClassElement classElement = libraryElement.definingCompilationUnit.types[0]; | 
| +    expect(libraryElement, isNotNull); | 
| +    expect(context.computeDocumentationComment(classElement), comment); | 
| +  } | 
| + | 
| +  void test_computeDocumentationComment_none() { | 
| +    Source source = addSource("/test.dart", "class A {}"); | 
| +    LibraryElement libraryElement = context.computeLibraryElement(source); | 
| +    expect(libraryElement, isNotNull); | 
| +    ClassElement classElement = libraryElement.definingCompilationUnit.types[0]; | 
| +    expect(libraryElement, isNotNull); | 
| +    expect(context.computeDocumentationComment(classElement), isNull); | 
| +  } | 
| + | 
| +  void test_computeDocumentationComment_null() { | 
| +    expect(context.computeDocumentationComment(null), isNull); | 
| +  } | 
| + | 
| +  void test_computeDocumentationComment_singleLine_multiple_EOL_n() { | 
| +    String comment = "/// line 1\n/// line 2\n/// line 3\n"; | 
| +    Source source = addSource("/test.dart", "${comment}class A {}"); | 
| +    LibraryElement libraryElement = context.computeLibraryElement(source); | 
| +    expect(libraryElement, isNotNull); | 
| +    ClassElement classElement = libraryElement.definingCompilationUnit.types[0]; | 
| +    expect(libraryElement, isNotNull); | 
| +    String actual = context.computeDocumentationComment(classElement); | 
| +    expect(actual, "/// line 1\n/// line 2\n/// line 3"); | 
| +  } | 
| + | 
| +  void test_computeDocumentationComment_singleLine_multiple_EOL_rn() { | 
| +    String comment = "/// line 1\r\n/// line 2\r\n/// line 3\r\n"; | 
| +    Source source = addSource("/test.dart", "${comment}class A {}"); | 
| +    LibraryElement libraryElement = context.computeLibraryElement(source); | 
| +    expect(libraryElement, isNotNull); | 
| +    ClassElement classElement = libraryElement.definingCompilationUnit.types[0]; | 
| +    expect(libraryElement, isNotNull); | 
| +    String actual = context.computeDocumentationComment(classElement); | 
| +    expect(actual, "/// line 1\n/// line 2\n/// line 3"); | 
| +  } | 
| + | 
| +  void test_computeErrors_dart_none() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    List<AnalysisError> errors = context.computeErrors(source); | 
| +    expect(errors, hasLength(0)); | 
| +  } | 
| + | 
| +  void test_computeErrors_dart_part() { | 
| +    Source librarySource = | 
| +        addSource("/lib.dart", "library lib; part 'part.dart';"); | 
| +    Source partSource = addSource("/part.dart", "part of 'lib';"); | 
| +    context.parseCompilationUnit(librarySource); | 
| +    List<AnalysisError> errors = context.computeErrors(partSource); | 
| +    expect(errors, isNotNull); | 
| +    expect(errors.length > 0, isTrue); | 
| +  } | 
| + | 
| +  void test_computeErrors_dart_some() { | 
| +    Source source = addSource("/lib.dart", "library 'lib';"); | 
| +    List<AnalysisError> errors = context.computeErrors(source); | 
| +    expect(errors, isNotNull); | 
| +    expect(errors.length > 0, isTrue); | 
| +  } | 
| + | 
| +  void test_computeErrors_html_none() { | 
| +    Source source = addSource("/test.html", "<!DOCTYPE html><html></html>"); | 
| +    List<AnalysisError> errors = context.computeErrors(source); | 
| +    expect(errors, hasLength(0)); | 
| +  } | 
| + | 
| +  void test_computeExportedLibraries_none() { | 
| +    Source source = addSource("/test.dart", "library test;"); | 
| +    expect(context.computeExportedLibraries(source), hasLength(0)); | 
| +  } | 
| + | 
| +  void test_computeExportedLibraries_some() { | 
| +    //    addSource("/lib1.dart", "library lib1;"); | 
| +    //    addSource("/lib2.dart", "library lib2;"); | 
| +    Source source = addSource( | 
| +        "/test.dart", "library test; export 'lib1.dart'; export 'lib2.dart';"); | 
| +    expect(context.computeExportedLibraries(source), hasLength(2)); | 
| +  } | 
| + | 
| +  void test_computeImportedLibraries_none() { | 
| +    Source source = addSource("/test.dart", "library test;"); | 
| +    expect(context.computeImportedLibraries(source), hasLength(0)); | 
| +  } | 
| + | 
| +  void test_computeImportedLibraries_some() { | 
| +    Source source = addSource( | 
| +        "/test.dart", "library test; import 'lib1.dart'; import 'lib2.dart';"); | 
| +    expect(context.computeImportedLibraries(source), hasLength(2)); | 
| +  } | 
| + | 
| +  void test_computeKindOf_html() { | 
| +    Source source = addSource("/test.html", ""); | 
| +    expect(context.computeKindOf(source), same(SourceKind.HTML)); | 
| +  } | 
| + | 
| +  void test_computeKindOf_library() { | 
| +    Source source = addSource("/test.dart", "library lib;"); | 
| +    expect(context.computeKindOf(source), same(SourceKind.LIBRARY)); | 
| +  } | 
| + | 
| +  void test_computeKindOf_libraryAndPart() { | 
| +    Source source = addSource("/test.dart", "library lib; part of lib;"); | 
| +    expect(context.computeKindOf(source), same(SourceKind.LIBRARY)); | 
| +  } | 
| + | 
| +  void test_computeKindOf_part() { | 
| +    Source source = addSource("/test.dart", "part of lib;"); | 
| +    expect(context.computeKindOf(source), same(SourceKind.PART)); | 
| +  } | 
| + | 
| +  void test_computeLibraryElement() { | 
| +    Source source = addSource("/test.dart", "library lib;"); | 
| +    LibraryElement element = context.computeLibraryElement(source); | 
| +    expect(element, isNotNull); | 
| +  } | 
| + | 
| +  void test_computeLineInfo_dart() { | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        r''' | 
| +library lib; | 
| + | 
| +main() {}'''); | 
| +    LineInfo info = context.computeLineInfo(source); | 
| +    expect(info, isNotNull); | 
| +  } | 
| + | 
| +  void test_computeLineInfo_html() { | 
| +    Source source = addSource( | 
| +        "/test.html", | 
| +        r''' | 
| +<html> | 
| +  <body> | 
| +    <h1>A</h1> | 
| +  </body> | 
| +</html>'''); | 
| +    LineInfo info = context.computeLineInfo(source); | 
| +    expect(info, isNotNull); | 
| +  } | 
| + | 
| +  Future test_computeResolvedCompilationUnitAsync() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    // Complete all pending analysis tasks and flush the AST so that it won't | 
| +    // be available immediately. | 
| +    _performPendingAnalysisTasks(); | 
| +    _flushAst(source); | 
| +    bool completed = false; | 
| +    context | 
| +        .computeResolvedCompilationUnitAsync(source, source) | 
| +        .then((CompilationUnit unit) { | 
| +      expect(unit, isNotNull); | 
| +      completed = true; | 
| +    }); | 
| +    return pumpEventQueue().then((_) { | 
| +      expect(completed, isFalse); | 
| +      _performPendingAnalysisTasks(); | 
| +    }).then((_) => pumpEventQueue()).then((_) { | 
| +      expect(completed, isTrue); | 
| +    }); | 
| +  } | 
| + | 
| +  Future test_computeResolvedCompilationUnitAsync_afterDispose() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    // Complete all pending analysis tasks and flush the AST so that it won't | 
| +    // be available immediately. | 
| +    _performPendingAnalysisTasks(); | 
| +    _flushAst(source); | 
| +    // Dispose of the context. | 
| +    context.dispose(); | 
| +    // Any attempt to start an asynchronous computation should return a future | 
| +    // which completes with error. | 
| +    CancelableFuture<CompilationUnit> future = | 
| +        context.computeResolvedCompilationUnitAsync(source, source); | 
| +    bool completed = false; | 
| +    future.then((CompilationUnit unit) { | 
| +      fail('Future should have completed with error'); | 
| +    }, onError: (error) { | 
| +      expect(error, new isInstanceOf<AnalysisNotScheduledError>()); | 
| +      completed = true; | 
| +    }); | 
| +    return pumpEventQueue().then((_) { | 
| +      expect(completed, isTrue); | 
| +    }); | 
| +  } | 
| + | 
| +  Future test_computeResolvedCompilationUnitAsync_cancel() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    // Complete all pending analysis tasks and flush the AST so that it won't | 
| +    // be available immediately. | 
| +    _performPendingAnalysisTasks(); | 
| +    _flushAst(source); | 
| +    CancelableFuture<CompilationUnit> future = | 
| +        context.computeResolvedCompilationUnitAsync(source, source); | 
| +    bool completed = false; | 
| +    future.then((CompilationUnit unit) { | 
| +      fail('Future should have been canceled'); | 
| +    }, onError: (error) { | 
| +      expect(error, new isInstanceOf<FutureCanceledError>()); | 
| +      completed = true; | 
| +    }); | 
| +    expect(completed, isFalse); | 
| +    expect(context.pendingFutureSources_forTesting, isNotEmpty); | 
| +    future.cancel(); | 
| +    expect(context.pendingFutureSources_forTesting, isEmpty); | 
| +    return pumpEventQueue().then((_) { | 
| +      expect(completed, isTrue); | 
| +      expect(context.pendingFutureSources_forTesting, isEmpty); | 
| +    }); | 
| +  } | 
| + | 
| +  Future test_computeResolvedCompilationUnitAsync_dispose() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    // Complete all pending analysis tasks and flush the AST so that it won't | 
| +    // be available immediately. | 
| +    _performPendingAnalysisTasks(); | 
| +    _flushAst(source); | 
| +    bool completed = false; | 
| +    CancelableFuture<CompilationUnit> future = | 
| +        context.computeResolvedCompilationUnitAsync(source, source); | 
| +    future.then((CompilationUnit unit) { | 
| +      fail('Future should have completed with error'); | 
| +    }, onError: (error) { | 
| +      expect(error, new isInstanceOf<AnalysisNotScheduledError>()); | 
| +      completed = true; | 
| +    }); | 
| +    expect(completed, isFalse); | 
| +    expect(context.pendingFutureSources_forTesting, isNotEmpty); | 
| +    // Disposing of the context should cause all pending futures to complete | 
| +    // with AnalysisNotScheduled, so that no clients are left hanging. | 
| +    context.dispose(); | 
| +    expect(context.pendingFutureSources_forTesting, isEmpty); | 
| +    return pumpEventQueue().then((_) { | 
| +      expect(completed, isTrue); | 
| +      expect(context.pendingFutureSources_forTesting, isEmpty); | 
| +    }); | 
| +  } | 
| + | 
| +  Future test_computeResolvedCompilationUnitAsync_noCacheEntry() { | 
| +    Source librarySource = addSource("/lib.dart", "library lib;"); | 
| +    Source partSource = addSource("/part.dart", "part of foo;"); | 
| +    bool completed = false; | 
| +    context | 
| +        .computeResolvedCompilationUnitAsync(partSource, librarySource) | 
| +        .then((CompilationUnit unit) { | 
| +      expect(unit, isNotNull); | 
| +      completed = true; | 
| +    }); | 
| +    return pumpEventQueue().then((_) { | 
| +      expect(completed, isFalse); | 
| +      _performPendingAnalysisTasks(); | 
| +    }).then((_) => pumpEventQueue()).then((_) { | 
| +      expect(completed, isTrue); | 
| +    }); | 
| +  } | 
| + | 
| +  void test_dispose() { | 
| +    expect(context.isDisposed, isFalse); | 
| +    context.dispose(); | 
| +    expect(context.isDisposed, isTrue); | 
| +  } | 
| + | 
| +  void test_ensureResolvedDartUnits_definingUnit_hasResolved() { | 
| +    Source source = addSource('/test.dart', ''); | 
| +    LibrarySpecificUnit libTarget = new LibrarySpecificUnit(source, source); | 
| +    analysisDriver.computeResult(libTarget, RESOLVED_UNIT); | 
| +    CompilationUnit unit = | 
| +        context.getCacheEntry(libTarget).getValue(RESOLVED_UNIT); | 
| +    List<CompilationUnit> units = context.ensureResolvedDartUnits(source); | 
| +    expect(units, unorderedEquals([unit])); | 
| +  } | 
| + | 
| +  void test_ensureResolvedDartUnits_definingUnit_notResolved() { | 
| +    Source source = addSource('/test.dart', ''); | 
| +    LibrarySpecificUnit libTarget = new LibrarySpecificUnit(source, source); | 
| +    analysisDriver.computeResult(libTarget, RESOLVED_UNIT); | 
| +    // flush | 
| +    context | 
| +        .getCacheEntry(libTarget) | 
| +        .setState(RESOLVED_UNIT, CacheState.FLUSHED); | 
| +    // schedule recomputing | 
| +    List<CompilationUnit> units = context.ensureResolvedDartUnits(source); | 
| +    expect(units, isNull); | 
| +    // should be the next result to compute | 
| +    TargetedResult nextResult = context.dartWorkManager.getNextResult(); | 
| +    expect(nextResult.target, libTarget); | 
| +    expect(nextResult.result, RESOLVED_UNIT); | 
| +  } | 
| + | 
| +  void test_ensureResolvedDartUnits_partUnit_hasResolved() { | 
| +    Source libSource1 = addSource( | 
| +        '/lib1.dart', | 
| +        r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +'''); | 
| +    Source libSource2 = addSource( | 
| +        '/lib2.dart', | 
| +        r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +'''); | 
| +    Source partSource = addSource( | 
| +        '/part.dart', | 
| +        r''' | 
| +part of lib; | 
| +'''); | 
| +    LibrarySpecificUnit partTarget1 = | 
| +        new LibrarySpecificUnit(libSource1, partSource); | 
| +    LibrarySpecificUnit partTarget2 = | 
| +        new LibrarySpecificUnit(libSource2, partSource); | 
| +    analysisDriver.computeResult(partTarget1, RESOLVED_UNIT); | 
| +    analysisDriver.computeResult(partTarget2, RESOLVED_UNIT); | 
| +    CompilationUnit unit1 = | 
| +        context.getCacheEntry(partTarget1).getValue(RESOLVED_UNIT); | 
| +    CompilationUnit unit2 = | 
| +        context.getCacheEntry(partTarget2).getValue(RESOLVED_UNIT); | 
| +    List<CompilationUnit> units = context.ensureResolvedDartUnits(partSource); | 
| +    expect(units, unorderedEquals([unit1, unit2])); | 
| +  } | 
| + | 
| +  void test_ensureResolvedDartUnits_partUnit_notResolved() { | 
| +    Source libSource1 = addSource( | 
| +        '/lib1.dart', | 
| +        r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +'''); | 
| +    Source libSource2 = addSource( | 
| +        '/lib2.dart', | 
| +        r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +'''); | 
| +    Source partSource = addSource( | 
| +        '/part.dart', | 
| +        r''' | 
| +part of lib; | 
| +'''); | 
| +    LibrarySpecificUnit partTarget1 = | 
| +        new LibrarySpecificUnit(libSource1, partSource); | 
| +    LibrarySpecificUnit partTarget2 = | 
| +        new LibrarySpecificUnit(libSource2, partSource); | 
| +    analysisDriver.computeResult(partTarget1, RESOLVED_UNIT); | 
| +    analysisDriver.computeResult(partTarget2, RESOLVED_UNIT); | 
| +    // flush | 
| +    context | 
| +        .getCacheEntry(partTarget1) | 
| +        .setState(RESOLVED_UNIT, CacheState.FLUSHED); | 
| +    context | 
| +        .getCacheEntry(partTarget2) | 
| +        .setState(RESOLVED_UNIT, CacheState.FLUSHED); | 
| +    // schedule recomputing | 
| +    List<CompilationUnit> units = context.ensureResolvedDartUnits(partSource); | 
| +    expect(units, isNull); | 
| +    // should be the next result to compute | 
| +    TargetedResult nextResult = context.dartWorkManager.getNextResult(); | 
| +    expect(nextResult.target, anyOf(partTarget1, partTarget2)); | 
| +    expect(nextResult.result, RESOLVED_UNIT); | 
| +  } | 
| + | 
| +  void test_exists_false() { | 
| +    TestSource source = new TestSource(); | 
| +    source.exists2 = false; | 
| +    expect(context.exists(source), isFalse); | 
| +  } | 
| + | 
| +  void test_exists_null() { | 
| +    expect(context.exists(null), isFalse); | 
| +  } | 
| + | 
| +  void test_exists_overridden() { | 
| +    Source source = new TestSource(); | 
| +    context.setContents(source, ""); | 
| +    expect(context.exists(source), isTrue); | 
| +  } | 
| + | 
| +  void test_exists_true() { | 
| +    expect(context.exists(new AnalysisContextImplTest_Source_exists_true()), | 
| +        isTrue); | 
| +  } | 
| + | 
| +  void test_getAnalysisOptions() { | 
| +    expect(context.analysisOptions, isNotNull); | 
| +  } | 
| + | 
| +  void test_getContents_fromSource() { | 
| +    String content = "library lib;"; | 
| +    TimestampedData<String> contents = | 
| +        context.getContents(new TestSource('/test.dart', content)); | 
| +    expect(contents.data.toString(), content); | 
| +  } | 
| + | 
| +  void test_getContents_overridden() { | 
| +    String content = "library lib;"; | 
| +    Source source = new TestSource(); | 
| +    context.setContents(source, content); | 
| +    TimestampedData<String> contents = context.getContents(source); | 
| +    expect(contents.data.toString(), content); | 
| +  } | 
| + | 
| +  void test_getContents_unoverridden() { | 
| +    String content = "library lib;"; | 
| +    Source source = new TestSource('/test.dart', content); | 
| +    context.setContents(source, "part of lib;"); | 
| +    context.setContents(source, null); | 
| +    TimestampedData<String> contents = context.getContents(source); | 
| +    expect(contents.data.toString(), content); | 
| +  } | 
| + | 
| +  void test_getDeclaredVariables() { | 
| +    expect(context.declaredVariables, isNotNull); | 
| +  } | 
| + | 
| +  void test_getElement() { | 
| +    LibraryElement core = | 
| +        context.computeLibraryElement(sourceFactory.forUri("dart:core")); | 
| +    expect(core, isNotNull); | 
| +    ClassElement classObject = | 
| +        _findClass(core.definingCompilationUnit, "Object"); | 
| +    expect(classObject, isNotNull); | 
| +    ElementLocation location = classObject.location; | 
| +    Element element = context.getElement(location); | 
| +    expect(element, same(classObject)); | 
| +  } | 
| + | 
| +  void test_getElement_constructor_named() { | 
| +    Source source = addSource( | 
| +        "/lib.dart", | 
| +        r''' | 
| +class A { | 
| +  A.named() {} | 
| +}'''); | 
| +    _analyzeAll_assertFinished(); | 
| +    LibraryElement library = context.computeLibraryElement(source); | 
| +    ClassElement classA = _findClass(library.definingCompilationUnit, "A"); | 
| +    ConstructorElement constructor = classA.constructors[0]; | 
| +    ElementLocation location = constructor.location; | 
| +    Element element = context.getElement(location); | 
| +    expect(element, same(constructor)); | 
| +  } | 
| + | 
| +  void test_getElement_constructor_unnamed() { | 
| +    Source source = addSource( | 
| +        "/lib.dart", | 
| +        r''' | 
| +class A { | 
| +  A() {} | 
| +}'''); | 
| +    _analyzeAll_assertFinished(); | 
| +    LibraryElement library = context.computeLibraryElement(source); | 
| +    ClassElement classA = _findClass(library.definingCompilationUnit, "A"); | 
| +    ConstructorElement constructor = classA.constructors[0]; | 
| +    ElementLocation location = constructor.location; | 
| +    Element element = context.getElement(location); | 
| +    expect(element, same(constructor)); | 
| +  } | 
| + | 
| +  void test_getElement_enum() { | 
| +    Source source = addSource('/test.dart', 'enum MyEnum {A, B, C}'); | 
| +    _analyzeAll_assertFinished(); | 
| +    LibraryElement library = context.computeLibraryElement(source); | 
| +    ClassElement myEnum = library.definingCompilationUnit.getEnum('MyEnum'); | 
| +    ElementLocation location = myEnum.location; | 
| +    Element element = context.getElement(location); | 
| +    expect(element, same(myEnum)); | 
| +  } | 
| + | 
| +  void test_getErrors_dart_none() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    var errorInfo = context.getErrors(source); | 
| +    expect(errorInfo, isNotNull); | 
| +    List<AnalysisError> errors = errorInfo.errors; | 
| +    expect(errors, hasLength(0)); | 
| +    context.computeErrors(source); | 
| +    errors = errorInfo.errors; | 
| +    expect(errors, hasLength(0)); | 
| +  } | 
| + | 
| +  void test_getErrors_dart_some() { | 
| +    Source source = addSource("/lib.dart", "library 'lib';"); | 
| +    var errorInfo = context.getErrors(source); | 
| +    expect(errorInfo, isNotNull); | 
| +    List<AnalysisError> errors = errorInfo.errors; | 
| +    expect(errors, hasLength(0)); | 
| +    errors = context.computeErrors(source); | 
| +    expect(errors, hasLength(1)); | 
| +  } | 
| + | 
| +  void test_getErrors_html_none() { | 
| +    Source source = addSource("/test.html", "<html></html>"); | 
| +    AnalysisErrorInfo errorInfo = context.getErrors(source); | 
| +    expect(errorInfo, isNotNull); | 
| +    List<AnalysisError> errors = errorInfo.errors; | 
| +    expect(errors, hasLength(0)); | 
| +    context.computeErrors(source); | 
| +    errors = errorInfo.errors; | 
| +    expect(errors, hasLength(0)); | 
| +  } | 
| + | 
| +  void test_getErrors_html_some() { | 
| +    Source source = addSource( | 
| +        "/test.html", | 
| +        r''' | 
| +<html><head> | 
| +<script type='application/dart' src='test.dart'/> | 
| +</head></html>'''); | 
| +    AnalysisErrorInfo errorInfo = context.getErrors(source); | 
| +    expect(errorInfo, isNotNull); | 
| +    List<AnalysisError> errors = errorInfo.errors; | 
| +    expect(errors, hasLength(0)); | 
| +    errors = context.computeErrors(source); | 
| +    expect(errors, hasLength(3)); | 
| +  } | 
| + | 
| +  void test_getHtmlFilesReferencing_html() { | 
| +    Source htmlSource = addSource( | 
| +        "/test.html", | 
| +        r''' | 
| +<html><head> | 
| +<script type='application/dart' src='test.dart'/> | 
| +<script type='application/dart' src='test.js'/> | 
| +</head></html>'''); | 
| +    Source librarySource = addSource("/test.dart", "library lib;"); | 
| +    Source secondHtmlSource = addSource("/test.html", "<html></html>"); | 
| +    context.computeLibraryElement(librarySource); | 
| +    List<Source> result = context.getHtmlFilesReferencing(secondHtmlSource); | 
| +    expect(result, hasLength(0)); | 
| +    context.parseHtmlDocument(htmlSource); | 
| +    result = context.getHtmlFilesReferencing(secondHtmlSource); | 
| +    expect(result, hasLength(0)); | 
| +  } | 
| + | 
| +  void test_getHtmlFilesReferencing_library() { | 
| +    Source htmlSource = addSource( | 
| +        "/test.html", | 
| +        r''' | 
| +<!DOCTYPE html> | 
| +<html><head> | 
| +<script type='application/dart' src='test.dart'/> | 
| +<script type='application/dart' src='test.js'/> | 
| +</head></html>'''); | 
| +    Source librarySource = addSource("/test.dart", "library lib;"); | 
| +    context.computeLibraryElement(librarySource); | 
| +    List<Source> result = context.getHtmlFilesReferencing(librarySource); | 
| +    expect(result, hasLength(0)); | 
| +    // Indirectly force the data to be computed. | 
| +    context.computeErrors(htmlSource); | 
| +    result = context.getHtmlFilesReferencing(librarySource); | 
| +    expect(result, hasLength(1)); | 
| +    expect(result[0], htmlSource); | 
| +  } | 
| + | 
| +  void test_getHtmlFilesReferencing_part() { | 
| +    Source htmlSource = addSource( | 
| +        "/test.html", | 
| +        r''' | 
| +<!DOCTYPE html> | 
| +<html><head> | 
| +<script type='application/dart' src='test.dart'/> | 
| +<script type='application/dart' src='test.js'/> | 
| +</head></html>'''); | 
| +    Source librarySource = | 
| +        addSource("/test.dart", "library lib; part 'part.dart';"); | 
| +    Source partSource = addSource("/part.dart", "part of lib;"); | 
| +    context.computeLibraryElement(librarySource); | 
| +    List<Source> result = context.getHtmlFilesReferencing(partSource); | 
| +    expect(result, hasLength(0)); | 
| +    // Indirectly force the data to be computed. | 
| +    context.computeErrors(htmlSource); | 
| +    result = context.getHtmlFilesReferencing(partSource); | 
| +    expect(result, hasLength(1)); | 
| +    expect(result[0], htmlSource); | 
| +  } | 
| + | 
| +  void test_getHtmlSources() { | 
| +    List<Source> sources = context.htmlSources; | 
| +    expect(sources, hasLength(0)); | 
| +    Source source = addSource("/test.html", ""); | 
| +    sources = context.htmlSources; | 
| +    expect(sources, hasLength(1)); | 
| +    expect(sources[0], source); | 
| +  } | 
| + | 
| +  void test_getKindOf_html() { | 
| +    Source source = addSource("/test.html", ""); | 
| +    expect(context.getKindOf(source), same(SourceKind.HTML)); | 
| +  } | 
| + | 
| +  void test_getKindOf_library() { | 
| +    Source source = addSource("/test.dart", "library lib;"); | 
| +    expect(context.getKindOf(source), same(SourceKind.UNKNOWN)); | 
| +    context.computeKindOf(source); | 
| +    expect(context.getKindOf(source), same(SourceKind.LIBRARY)); | 
| +  } | 
| + | 
| +  void test_getKindOf_part() { | 
| +    Source source = addSource("/test.dart", "part of lib;"); | 
| +    expect(context.getKindOf(source), same(SourceKind.UNKNOWN)); | 
| +    context.computeKindOf(source); | 
| +    expect(context.getKindOf(source), same(SourceKind.PART)); | 
| +  } | 
| + | 
| +  void test_getKindOf_unknown() { | 
| +    Source source = addSource("/test.css", ""); | 
| +    expect(context.getKindOf(source), same(SourceKind.UNKNOWN)); | 
| +  } | 
| + | 
| +  void test_getLaunchableClientLibrarySources_doesNotImportHtml() { | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        r''' | 
| +main() {}'''); | 
| +    context.computeLibraryElement(source); | 
| +    List<Source> sources = context.launchableClientLibrarySources; | 
| +    expect(sources, isEmpty); | 
| +  } | 
| + | 
| +  void test_getLaunchableClientLibrarySources_importsHtml_explicitly() { | 
| +    List<Source> sources = context.launchableClientLibrarySources; | 
| +    expect(sources, isEmpty); | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        r''' | 
| +import 'dart:html'; | 
| +main() {}'''); | 
| +    context.computeLibraryElement(source); | 
| +    sources = context.launchableClientLibrarySources; | 
| +    expect(sources, unorderedEquals([source])); | 
| +  } | 
| + | 
| +  void test_getLaunchableClientLibrarySources_importsHtml_implicitly() { | 
| +    List<Source> sources = context.launchableClientLibrarySources; | 
| +    expect(sources, isEmpty); | 
| +    addSource( | 
| +        "/a.dart", | 
| +        r''' | 
| +import 'dart:html'; | 
| +'''); | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        r''' | 
| +import 'a.dart'; | 
| +main() {}'''); | 
| +    context.computeLibraryElement(source); | 
| +    sources = context.launchableClientLibrarySources; | 
| +    expect(sources, unorderedEquals([source])); | 
| +  } | 
| + | 
| +  void test_getLaunchableClientLibrarySources_importsHtml_implicitly2() { | 
| +    List<Source> sources = context.launchableClientLibrarySources; | 
| +    expect(sources, isEmpty); | 
| +    addSource( | 
| +        "/a.dart", | 
| +        r''' | 
| +export 'dart:html'; | 
| +'''); | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        r''' | 
| +import 'a.dart'; | 
| +main() {}'''); | 
| +    context.computeLibraryElement(source); | 
| +    sources = context.launchableClientLibrarySources; | 
| +    expect(sources, unorderedEquals([source])); | 
| +  } | 
| + | 
| +  void test_getLaunchableServerLibrarySources() { | 
| +    expect(context.launchableServerLibrarySources, isEmpty); | 
| +    Source source = addSource("/test.dart", "main() {}"); | 
| +    context.computeLibraryElement(source); | 
| +    expect(context.launchableServerLibrarySources, unorderedEquals([source])); | 
| +  } | 
| + | 
| +  void test_getLaunchableServerLibrarySources_importsHtml_explicitly() { | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        r''' | 
| +import 'dart:html'; | 
| +main() {} | 
| +'''); | 
| +    context.computeLibraryElement(source); | 
| +    expect(context.launchableServerLibrarySources, isEmpty); | 
| +  } | 
| + | 
| +  void test_getLaunchableServerLibrarySources_importsHtml_implicitly() { | 
| +    addSource( | 
| +        "/imports_html.dart", | 
| +        r''' | 
| +import 'dart:html'; | 
| +'''); | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        r''' | 
| +import 'imports_html.dart'; | 
| +main() {}'''); | 
| +    context.computeLibraryElement(source); | 
| +    expect(context.launchableServerLibrarySources, isEmpty); | 
| +  } | 
| + | 
| +  void test_getLaunchableServerLibrarySources_noMain() { | 
| +    Source source = addSource("/test.dart", ''); | 
| +    context.computeLibraryElement(source); | 
| +    expect(context.launchableServerLibrarySources, isEmpty); | 
| +  } | 
| + | 
| +  void test_getLibrariesContaining() { | 
| +    Source librarySource = addSource( | 
| +        "/lib.dart", | 
| +        r''' | 
| +library lib; | 
| +part 'part.dart';'''); | 
| +    Source partSource = addSource("/part.dart", "part of lib;"); | 
| +    context.computeLibraryElement(librarySource); | 
| +    List<Source> result = context.getLibrariesContaining(librarySource); | 
| +    expect(result, hasLength(1)); | 
| +    expect(result[0], librarySource); | 
| +    result = context.getLibrariesContaining(partSource); | 
| +    expect(result, hasLength(1)); | 
| +    expect(result[0], librarySource); | 
| +  } | 
| + | 
| +  void test_getLibrariesDependingOn() { | 
| +    Source libASource = addSource("/libA.dart", "library libA;"); | 
| +    addSource("/libB.dart", "library libB;"); | 
| +    Source lib1Source = addSource( | 
| +        "/lib1.dart", | 
| +        r''' | 
| +library lib1; | 
| +import 'libA.dart'; | 
| +export 'libB.dart';'''); | 
| +    Source lib2Source = addSource( | 
| +        "/lib2.dart", | 
| +        r''' | 
| +library lib2; | 
| +import 'libB.dart'; | 
| +export 'libA.dart';'''); | 
| +    context.computeLibraryElement(lib1Source); | 
| +    context.computeLibraryElement(lib2Source); | 
| +    List<Source> result = context.getLibrariesDependingOn(libASource); | 
| +    expect(result, unorderedEquals([lib1Source, lib2Source])); | 
| +  } | 
| + | 
| +  void test_getLibrariesReferencedFromHtml() { | 
| +    Source htmlSource = addSource( | 
| +        "/test.html", | 
| +        r''' | 
| +<!DOCTYPE html> | 
| +<html><head> | 
| +<script type='application/dart' src='test.dart'/> | 
| +<script type='application/dart' src='test.js'/> | 
| +</head></html>'''); | 
| +    Source librarySource = addSource("/test.dart", "library lib;"); | 
| +    context.computeLibraryElement(librarySource); | 
| +    // Indirectly force the data to be computed. | 
| +    context.computeErrors(htmlSource); | 
| +    List<Source> result = context.getLibrariesReferencedFromHtml(htmlSource); | 
| +    expect(result, hasLength(1)); | 
| +    expect(result[0], librarySource); | 
| +  } | 
| + | 
| +  void test_getLibrariesReferencedFromHtml_none() { | 
| +    Source htmlSource = addSource( | 
| +        "/test.html", | 
| +        r''' | 
| +<html><head> | 
| +<script type='application/dart' src='test.js'/> | 
| +</head></html>'''); | 
| +    addSource("/test.dart", "library lib;"); | 
| +    context.parseHtmlDocument(htmlSource); | 
| +    List<Source> result = context.getLibrariesReferencedFromHtml(htmlSource); | 
| +    expect(result, hasLength(0)); | 
| +  } | 
| + | 
| +  void test_getLibraryElement() { | 
| +    Source source = addSource("/test.dart", "library lib;"); | 
| +    LibraryElement element = context.getLibraryElement(source); | 
| +    expect(element, isNull); | 
| +    context.computeLibraryElement(source); | 
| +    element = context.getLibraryElement(source); | 
| +    expect(element, isNotNull); | 
| +  } | 
| + | 
| +  void test_getLibrarySources() { | 
| +    List<Source> sources = context.librarySources; | 
| +    int originalLength = sources.length; | 
| +    Source source = addSource("/test.dart", "library lib;"); | 
| +    context.computeKindOf(source); | 
| +    sources = context.librarySources; | 
| +    expect(sources, hasLength(originalLength + 1)); | 
| +    for (Source returnedSource in sources) { | 
| +      if (returnedSource == source) { | 
| +        return; | 
| +      } | 
| +    } | 
| +    fail("The added source was not in the list of library sources"); | 
| +  } | 
| + | 
| +  void test_getLineInfo() { | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        r''' | 
| +library lib; | 
| + | 
| +main() {}'''); | 
| +    LineInfo info = context.getLineInfo(source); | 
| +    expect(info, isNull); | 
| +    context.parseCompilationUnit(source); | 
| +    info = context.getLineInfo(source); | 
| +    expect(info, isNotNull); | 
| +  } | 
| + | 
| +  void test_getModificationStamp_fromSource() { | 
| +    int stamp = 42; | 
| +    expect( | 
| +        context.getModificationStamp( | 
| +            new AnalysisContextImplTest_Source_getModificationStamp_fromSource( | 
| +                stamp)), | 
| +        stamp); | 
| +  } | 
| + | 
| +  void test_getModificationStamp_overridden() { | 
| +    int stamp = 42; | 
| +    Source source = | 
| +        new AnalysisContextImplTest_Source_getModificationStamp_overridden( | 
| +            stamp); | 
| +    context.setContents(source, ""); | 
| +    expect(stamp != context.getModificationStamp(source), isTrue); | 
| +  } | 
| + | 
| +  void test_getPublicNamespace_element() { | 
| +    Source source = addSource("/test.dart", "class A {}"); | 
| +    LibraryElement library = context.computeLibraryElement(source); | 
| +    expect(library, isNotNull); | 
| +    Namespace namespace = context.getPublicNamespace(library); | 
| +    expect(namespace, isNotNull); | 
| +    EngineTestCase.assertInstanceOf( | 
| +        (obj) => obj is ClassElement, ClassElement, namespace.get("A")); | 
| +  } | 
| + | 
| +  void test_getResolvedCompilationUnit_library() { | 
| +    Source source = addSource("/lib.dart", "library libb;"); | 
| +    LibraryElement library = context.computeLibraryElement(source); | 
| +    context.computeErrors(source); // Force the resolved unit to be built. | 
| +    expect(context.getResolvedCompilationUnit(source, library), isNotNull); | 
| +    context.setContents(source, "library lib;"); | 
| +    expect(context.getResolvedCompilationUnit(source, library), isNull); | 
| +  } | 
| + | 
| +  void test_getResolvedCompilationUnit_library_null() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    expect(context.getResolvedCompilationUnit(source, null), isNull); | 
| +  } | 
| + | 
| +  void test_getResolvedCompilationUnit_source_dart() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    expect(context.getResolvedCompilationUnit2(source, source), isNull); | 
| +    context.resolveCompilationUnit2(source, source); | 
| +    expect(context.getResolvedCompilationUnit2(source, source), isNotNull); | 
| +  } | 
| + | 
| +  void test_getSourceFactory() { | 
| +    expect(context.sourceFactory, same(sourceFactory)); | 
| +  } | 
| + | 
| +  void test_getSourcesWithFullName() { | 
| +    String filePath = '/foo/lib/file.dart'; | 
| +    List<Source> expected = <Source>[]; | 
| +    ChangeSet changeSet = new ChangeSet(); | 
| + | 
| +    TestSourceWithUri source1 = | 
| +        new TestSourceWithUri(filePath, Uri.parse('file://$filePath')); | 
| +    expected.add(source1); | 
| +    changeSet.addedSource(source1); | 
| + | 
| +    TestSourceWithUri source2 = | 
| +        new TestSourceWithUri(filePath, Uri.parse('package:foo/file.dart')); | 
| +    expected.add(source2); | 
| +    changeSet.addedSource(source2); | 
| + | 
| +    context.applyChanges(changeSet); | 
| +    expect(context.getSourcesWithFullName(filePath), unorderedEquals(expected)); | 
| +  } | 
| + | 
| +  void test_getStatistics() { | 
| +    AnalysisContextStatistics statistics = context.statistics; | 
| +    expect(statistics, isNotNull); | 
| +    // The following lines are fragile. | 
| +    // The values depend on the number of libraries in the SDK. | 
| +//    assertLength(0, statistics.getCacheRows()); | 
| +//    assertLength(0, statistics.getExceptions()); | 
| +//    assertLength(0, statistics.getSources()); | 
| +  } | 
| + | 
| +  void test_handleContentsChanged() { | 
| +    ContentCache contentCache = new ContentCache(); | 
| +    context.contentCache = contentCache; | 
| +    String oldContents = 'foo() {}'; | 
| +    String newContents = 'bar() {}'; | 
| +    // old contents | 
| +    Source source = addSource("/test.dart", oldContents); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(source, source), isNotNull); | 
| +    // new contents | 
| +    contentCache.setContents(source, newContents); | 
| +    context.handleContentsChanged(source, oldContents, newContents, true); | 
| +    // there is some work to do | 
| +    AnalysisResult analysisResult = context.performAnalysisTask(); | 
| +    expect(analysisResult.changeNotices, isNotNull); | 
| +  } | 
| + | 
| +  Future test_implicitAnalysisEvents_added() async { | 
| +    AnalyzedSourcesListener listener = new AnalyzedSourcesListener(); | 
| +    context.implicitAnalysisEvents.listen(listener.onData); | 
| +    // | 
| +    // Create a file that references an file that is not explicitly being | 
| +    // analyzed and fully analyze it. Ensure that the listener is told about | 
| +    // the implicitly analyzed file. | 
| +    // | 
| +    Source sourceA = newSource('/a.dart', "library a; import 'b.dart';"); | 
| +    Source sourceB = newSource('/b.dart', "library b;"); | 
| +    ChangeSet changeSet = new ChangeSet(); | 
| +    changeSet.addedSource(sourceA); | 
| +    context.applyChanges(changeSet); | 
| +    context.computeErrors(sourceA); | 
| +    await pumpEventQueue(); | 
| +    listener.expectAnalyzed(sourceB); | 
| +  } | 
| + | 
| +  void test_isClientLibrary_dart() { | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        r''' | 
| +import 'dart:html'; | 
| + | 
| +main() {}'''); | 
| +    expect(context.isClientLibrary(source), isFalse); | 
| +    expect(context.isServerLibrary(source), isFalse); | 
| +    context.computeLibraryElement(source); | 
| +    expect(context.isClientLibrary(source), isTrue); | 
| +    expect(context.isServerLibrary(source), isFalse); | 
| +  } | 
| + | 
| +  void test_isClientLibrary_html() { | 
| +    Source source = addSource("/test.html", "<html></html>"); | 
| +    expect(context.isClientLibrary(source), isFalse); | 
| +  } | 
| + | 
| +  void test_isServerLibrary_dart() { | 
| +    Source source = addSource( | 
| +        "/test.dart", | 
| +        r''' | 
| +library lib; | 
| + | 
| +main() {}'''); | 
| +    expect(context.isClientLibrary(source), isFalse); | 
| +    expect(context.isServerLibrary(source), isFalse); | 
| +    context.computeLibraryElement(source); | 
| +    expect(context.isClientLibrary(source), isFalse); | 
| +    expect(context.isServerLibrary(source), isTrue); | 
| +  } | 
| + | 
| +  void test_isServerLibrary_html() { | 
| +    Source source = addSource("/test.html", "<html></html>"); | 
| +    expect(context.isServerLibrary(source), isFalse); | 
| +  } | 
| + | 
| +  void test_parseCompilationUnit_errors() { | 
| +    Source source = addSource("/lib.dart", "library {"); | 
| +    CompilationUnit compilationUnit = context.parseCompilationUnit(source); | 
| +    expect(compilationUnit, isNotNull); | 
| +    var errorInfo = context.getErrors(source); | 
| +    expect(errorInfo, isNotNull); | 
| +    List<AnalysisError> errors = errorInfo.errors; | 
| +    expect(errors, isNotNull); | 
| +    expect(errors.length > 0, isTrue); | 
| +  } | 
| + | 
| +  void test_parseCompilationUnit_exception() { | 
| +    Source source = _addSourceWithException("/test.dart"); | 
| +    try { | 
| +      context.parseCompilationUnit(source); | 
| +      fail("Expected AnalysisException"); | 
| +    } on AnalysisException { | 
| +      // Expected | 
| +    } | 
| +  } | 
| + | 
| +  void test_parseCompilationUnit_html() { | 
| +    Source source = addSource("/test.html", "<html></html>"); | 
| +    expect(context.parseCompilationUnit(source), isNull); | 
| +  } | 
| + | 
| +  void test_parseCompilationUnit_noErrors() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    CompilationUnit compilationUnit = context.parseCompilationUnit(source); | 
| +    expect(compilationUnit, isNotNull); | 
| +    AnalysisErrorInfo errorInfo = context.getErrors(source); | 
| +    expect(errorInfo, isNotNull); | 
| +    expect(errorInfo.errors, hasLength(0)); | 
| +  } | 
| + | 
| +  void test_parseCompilationUnit_nonExistentSource() { | 
| +    Source source = newSource('/test.dart'); | 
| +    resourceProvider.deleteFile('/test.dart'); | 
| +    try { | 
| +      context.parseCompilationUnit(source); | 
| +      fail("Expected AnalysisException because file does not exist"); | 
| +    } on AnalysisException { | 
| +      // Expected result | 
| +    } | 
| +  } | 
| + | 
| +  void test_parseHtmlDocument() { | 
| +    Source source = addSource("/lib.html", "<!DOCTYPE html><html></html>"); | 
| +    Document document = context.parseHtmlDocument(source); | 
| +    expect(document, isNotNull); | 
| +  } | 
| + | 
| +  void test_parseHtmlUnit_resolveDirectives() { | 
| +    Source libSource = addSource( | 
| +        "/lib.dart", | 
| +        r''' | 
| +library lib; | 
| +class ClassA {}'''); | 
| +    Source source = addSource( | 
| +        "/lib.html", | 
| +        r''' | 
| +<!DOCTYPE html> | 
| +<html> | 
| +<head> | 
| +  <script type='application/dart'> | 
| +    import 'lib.dart'; | 
| +    ClassA v = null; | 
| +  </script> | 
| +</head> | 
| +<body> | 
| +</body> | 
| +</html>'''); | 
| +    Document document = context.parseHtmlDocument(source); | 
| +    expect(document, isNotNull); | 
| +    List<DartScript> scripts = context.computeResult(source, DART_SCRIPTS); | 
| +    expect(scripts, hasLength(1)); | 
| +    CompilationUnit unit = context.computeResult(scripts[0], PARSED_UNIT); | 
| +    ImportDirective importNode = unit.directives[0] as ImportDirective; | 
| +    expect(importNode.uriContent, isNotNull); | 
| +    expect(importNode.source, libSource); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_addPart() { | 
| +    Source libSource = addSource( | 
| +        "/lib.dart", | 
| +        r''' | 
| +library lib; | 
| +part 'part.dart';'''); | 
| +    // run all tasks without part | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libSource)), | 
| +        isTrue, | 
| +        reason: "lib has errors"); | 
| +    // add part and run all tasks | 
| +    Source partSource = addSource( | 
| +        "/part.dart", | 
| +        r''' | 
| +part of lib; | 
| +'''); | 
| +    _analyzeAll_assertFinished(); | 
| +    // "libSource" should be here | 
| +    List<Source> librariesWithPart = context.getLibrariesContaining(partSource); | 
| +    expect(librariesWithPart, unorderedEquals([libSource])); | 
| +    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libSource)), | 
| +        isFalse, | 
| +        reason: "lib doesn't have errors"); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, | 
| +        reason: "part resolved"); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_changeLibraryContents() { | 
| +    Source libSource = | 
| +        addSource("/test.dart", "library lib; part 'test-part.dart';"); | 
| +    Source partSource = addSource("/test-part.dart", "part of lib;"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +        reason: "library resolved 1"); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, | 
| +        reason: "part resolved 1"); | 
| +    // update and analyze #1 | 
| +    context.setContents(libSource, "library lib;"); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, | 
| +        reason: "library changed 2"); | 
| +    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, | 
| +        reason: "part changed 2"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +        reason: "library resolved 2"); | 
| +    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, | 
| +        reason: "part resolved 2"); | 
| +    // update and analyze #2 | 
| +    context.setContents(libSource, "library lib; part 'test-part.dart';"); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, | 
| +        reason: "library changed 3"); | 
| +    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, | 
| +        reason: "part changed 3"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +        reason: "library resolved 3"); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, | 
| +        reason: "part resolved 3"); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_changeLibraryThenPartContents() { | 
| +    Source libSource = | 
| +        addSource("/test.dart", "library lib; part 'test-part.dart';"); | 
| +    Source partSource = addSource("/test-part.dart", "part of lib;"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +        reason: "library resolved 1"); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, | 
| +        reason: "part resolved 1"); | 
| +    // update and analyze #1 | 
| +    context.setContents(libSource, "library lib;"); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, | 
| +        reason: "library changed 2"); | 
| +    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, | 
| +        reason: "part changed 2"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +        reason: "library resolved 2"); | 
| +    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, | 
| +        reason: "part resolved 2"); | 
| +    // update and analyze #2 | 
| +    context.setContents(partSource, "part of lib; // 1"); | 
| +    // Assert that changing the part's content does not effect the library | 
| +    // now that it is no longer part of that library | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +        reason: "library changed 3"); | 
| +    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, | 
| +        reason: "part changed 3"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +        reason: "library resolved 3"); | 
| +    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, | 
| +        reason: "part resolved 3"); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_changePartContents_makeItAPart() { | 
| +    Source libSource = addSource( | 
| +        "/lib.dart", | 
| +        r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +void f(x) {}'''); | 
| +    Source partSource = addSource("/part.dart", "void g() { f(null); }"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +        reason: "library resolved 1"); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(partSource, partSource), isNotNull, | 
| +        reason: "part resolved 1"); | 
| +    // update and analyze | 
| +    context.setContents( | 
| +        partSource, | 
| +        r''' | 
| +part of lib; | 
| +void g() { f(null); }'''); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, | 
| +        reason: "library changed 2"); | 
| +    expect(context.getResolvedCompilationUnit2(partSource, partSource), isNull, | 
| +        reason: "part changed 2"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +        reason: "library resolved 2"); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, | 
| +        reason: "part resolved 2"); | 
| +    expect(context.getErrors(libSource).errors, hasLength(0)); | 
| +    expect(context.getErrors(partSource).errors, hasLength(0)); | 
| +  } | 
| + | 
| +  /** | 
| +   * https://code.google.com/p/dart/issues/detail?id=12424 | 
| +   */ | 
| +  void test_performAnalysisTask_changePartContents_makeItNotPart() { | 
| +    Source libSource = addSource( | 
| +        "/lib.dart", | 
| +        r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +void f(x) {}'''); | 
| +    Source partSource = addSource( | 
| +        "/part.dart", | 
| +        r''' | 
| +part of lib; | 
| +void g() { f(null); }'''); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getErrors(libSource).errors, hasLength(0)); | 
| +    expect(context.getErrors(partSource).errors, hasLength(0)); | 
| +    // Remove 'part' directive, which should make "f(null)" an error. | 
| +    context.setContents( | 
| +        partSource, | 
| +        r''' | 
| +//part of lib; | 
| +void g() { f(null); }'''); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getErrors(libSource).errors.length != 0, isTrue); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_changePartContents_noSemanticChanges() { | 
| +    Source libSource = | 
| +        addSource("/test.dart", "library lib; part 'test-part.dart';"); | 
| +    Source partSource = addSource("/test-part.dart", "part of lib;"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +        reason: "library resolved 1"); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, | 
| +        reason: "part resolved 1"); | 
| +    // update and analyze #1 | 
| +    context.setContents(partSource, "part of lib; // 1"); | 
| +    if (AnalysisEngine.instance.limitInvalidationInTaskModel) { | 
| +      expect( | 
| +          context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +          reason: "library changed 2"); | 
| +      expect( | 
| +          context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, | 
| +          reason: "part changed 2"); | 
| +    } else { | 
| +      expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, | 
| +          reason: "library changed 2"); | 
| +      expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, | 
| +          reason: "part changed 2"); | 
| +      _analyzeAll_assertFinished(); | 
| +      expect( | 
| +          context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +          reason: "library resolved 2"); | 
| +      expect( | 
| +          context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, | 
| +          reason: "part resolved 2"); | 
| +    } | 
| +    // update and analyze #2 | 
| +    context.setContents(partSource, "part of lib; // 12"); | 
| +    if (AnalysisEngine.instance.limitInvalidationInTaskModel) { | 
| +      expect( | 
| +          context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +          reason: "library changed 3"); | 
| +      expect( | 
| +          context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, | 
| +          reason: "part changed 3"); | 
| +    } else { | 
| +      expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, | 
| +          reason: "library changed 3"); | 
| +      expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, | 
| +          reason: "part changed 3"); | 
| +      _analyzeAll_assertFinished(); | 
| +      expect( | 
| +          context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, | 
| +          reason: "library resolved 3"); | 
| +      expect( | 
| +          context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, | 
| +          reason: "part resolved 3"); | 
| +    } | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_getContentException_dart() { | 
| +    Source source = _addSourceWithException('test.dart'); | 
| +    // prepare errors | 
| +    _analyzeAll_assertFinished(); | 
| +    List<AnalysisError> errors = context.getErrors(source).errors; | 
| +    // validate errors | 
| +    expect(errors, hasLength(1)); | 
| +    AnalysisError error = errors[0]; | 
| +    expect(error.source, same(source)); | 
| +    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_getContentException_html() { | 
| +    Source source = _addSourceWithException('test.html'); | 
| +    // prepare errors | 
| +    _analyzeAll_assertFinished(); | 
| +    List<AnalysisError> errors = context.getErrors(source).errors; | 
| +    // validate errors | 
| +    expect(errors, hasLength(1)); | 
| +    AnalysisError error = errors[0]; | 
| +    expect(error.source, same(source)); | 
| +    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_importedLibraryAdd() { | 
| +    Source libASource = | 
| +        addSource("/libA.dart", "library libA; import 'libB.dart';"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, | 
| +        reason: "libA resolved 1"); | 
| +    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)), | 
| +        isTrue, | 
| +        reason: "libA has an error"); | 
| +    // add libB.dart and analyze | 
| +    Source libBSource = addSource("/libB.dart", "library libB;"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, | 
| +        reason: "libA resolved 2"); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, | 
| +        reason: "libB resolved 2"); | 
| +    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)), | 
| +        isFalse, | 
| +        reason: "libA doesn't have errors"); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_importedLibraryAdd_html() { | 
| +    Source htmlSource = addSource( | 
| +        "/page.html", | 
| +        r''' | 
| +<html><body><script type="application/dart"> | 
| +  import '/libB.dart'; | 
| +  main() {print('hello dart');} | 
| +</script></body></html>'''); | 
| +    _analyzeAll_assertFinished(); | 
| +    context.computeErrors(htmlSource); | 
| +    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)), | 
| +        isTrue, | 
| +        reason: "htmlSource has an error"); | 
| +    // add libB.dart and analyze | 
| +    Source libBSource = addSource("/libB.dart", "library libB;"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, | 
| +        reason: "libB resolved 2"); | 
| +    // TODO (danrubel) commented out to fix red bots | 
| +//    context.computeErrors(htmlSource); | 
| +//    AnalysisErrorInfo errors = _context.getErrors(htmlSource); | 
| +//    expect( | 
| +//        !_hasAnalysisErrorWithErrorSeverity(errors), | 
| +//        isTrue, | 
| +//        reason: "htmlSource doesn't have errors"); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_importedLibraryDelete() { | 
| +    Source libASource = | 
| +        addSource("/libA.dart", "library libA; import 'libB.dart';"); | 
| +    Source libBSource = addSource("/libB.dart", "library libB;"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, | 
| +        reason: "libA resolved 1"); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, | 
| +        reason: "libB resolved 1"); | 
| +    expect(!_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)), | 
| +        isTrue, | 
| +        reason: "libA doesn't have errors"); | 
| +    // remove libB.dart and analyze | 
| +    _removeSource(libBSource); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, | 
| +        reason: "libA resolved 2"); | 
| +    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)), | 
| +        isTrue, | 
| +        reason: "libA has an error"); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_IOException() { | 
| +    TestSource source = _addSourceWithException2("/test.dart", "library test;"); | 
| +    source.generateExceptionOnRead = false; | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(source.readCount, 2); | 
| +    _changeSource(source, ""); | 
| +    source.generateExceptionOnRead = true; | 
| +    _analyzeAll_assertFinished(); | 
| +    if (AnalysisEngine.instance.limitInvalidationInTaskModel) { | 
| +      expect(source.readCount, 7); | 
| +    } else { | 
| +      expect(source.readCount, 5); | 
| +    } | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_missingPart() { | 
| +    Source source = | 
| +        addSource("/test.dart", "library lib; part 'no-such-file.dart';"); | 
| +    _analyzeAll_assertFinished(); | 
| +    expect(context.getLibraryElement(source), isNotNull, | 
| +        reason: "performAnalysisTask failed to compute an element model"); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_modifiedAfterParse() { | 
| +    // TODO(scheglov) no threads in Dart | 
| +//    Source source = _addSource("/test.dart", "library lib;"); | 
| +//    int initialTime = _context.getModificationStamp(source); | 
| +//    List<Source> sources = <Source>[]; | 
| +//    sources.add(source); | 
| +//    _context.analysisPriorityOrder = sources; | 
| +//    _context.parseCompilationUnit(source); | 
| +//    while (initialTime == JavaSystem.currentTimeMillis()) { | 
| +//      Thread.sleep(1); | 
| +//      // Force the modification time to be different. | 
| +//    } | 
| +//    _context.setContents(source, "library test;"); | 
| +//    JUnitTestCase.assertTrue(initialTime != _context.getModificationStamp(source)); | 
| +//    _analyzeAll_assertFinished(); | 
| +//    JUnitTestCase.assertNotNullMsg("performAnalysisTask failed to compute an element model", _context.getLibraryElement(source)); | 
| +  } | 
| + | 
| +  void test_performAnalysisTask_onResultComputed() { | 
| +    Set<String> libraryElementUris = new Set<String>(); | 
| +    Set<String> parsedUnitUris = new Set<String>(); | 
| +    Set<String> resolvedUnitUris = new Set<String>(); | 
| +    // listen | 
| +    context.onResultComputed(LIBRARY_ELEMENT).listen((event) { | 
| +      Source librarySource = event.target; | 
| +      libraryElementUris.add(librarySource.uri.toString()); | 
| +    }); | 
| +    context.onResultComputed(PARSED_UNIT).listen((event) { | 
| +      Source source = event.target; | 
| +      parsedUnitUris.add(source.uri.toString()); | 
| +    }); | 
| +    context.onResultComputed(RESOLVED_UNIT).listen((event) { | 
| +      LibrarySpecificUnit target = event.target; | 
| +      Source librarySource = target.library; | 
| +      resolvedUnitUris.add(librarySource.uri.toString()); | 
| +    }); | 
| +    // analyze | 
| +    addSource('/test.dart', 'main() {}'); | 
| +    _analyzeAll_assertFinished(); | 
| +    // verify | 
| +    expect(libraryElementUris, contains('dart:core')); | 
| +    expect(libraryElementUris, contains('file:///test.dart')); | 
| +    expect(parsedUnitUris, contains('dart:core')); | 
| +    expect(parsedUnitUris, contains('file:///test.dart')); | 
| +    expect(resolvedUnitUris, contains('dart:core')); | 
| +    expect(resolvedUnitUris, contains('file:///test.dart')); | 
| +  } | 
| + | 
| +  void test_resolveCompilationUnit_import_relative() { | 
| +    Source sourceA = | 
| +        addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}"); | 
| +    addSource("/libB.dart", "library libB; class B{}"); | 
| +    CompilationUnit compilationUnit = | 
| +        context.resolveCompilationUnit2(sourceA, sourceA); | 
| +    expect(compilationUnit, isNotNull); | 
| +    LibraryElement library = compilationUnit.element.library; | 
| +    List<LibraryElement> importedLibraries = library.importedLibraries; | 
| +    assertNamedElements(importedLibraries, ["dart.core", "libB"]); | 
| +    List<LibraryElement> visibleLibraries = library.visibleLibraries; | 
| +    assertNamedElements(visibleLibraries, | 
| +        ["dart.core", "dart.async", "dart.math", "libA", "libB"]); | 
| +  } | 
| + | 
| +  void test_resolveCompilationUnit_import_relative_cyclic() { | 
| +    Source sourceA = | 
| +        addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}"); | 
| +    addSource("/libB.dart", "library libB; import 'libA.dart'; class B{}"); | 
| +    CompilationUnit compilationUnit = | 
| +        context.resolveCompilationUnit2(sourceA, sourceA); | 
| +    expect(compilationUnit, isNotNull); | 
| +    LibraryElement library = compilationUnit.element.library; | 
| +    List<LibraryElement> importedLibraries = library.importedLibraries; | 
| +    assertNamedElements(importedLibraries, ["dart.core", "libB"]); | 
| +    List<LibraryElement> visibleLibraries = library.visibleLibraries; | 
| +    assertNamedElements(visibleLibraries, | 
| +        ["dart.core", "dart.async", "dart.math", "libA", "libB"]); | 
| +  } | 
| + | 
| +  void test_resolveCompilationUnit_library() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    LibraryElement library = context.computeLibraryElement(source); | 
| +    CompilationUnit compilationUnit = | 
| +        context.resolveCompilationUnit(source, library); | 
| +    expect(compilationUnit, isNotNull); | 
| +    expect(compilationUnit.element, isNotNull); | 
| +  } | 
| + | 
| +//  void test_resolveCompilationUnit_sourceChangeDuringResolution() { | 
| +//    _context = new _AnalysisContext_sourceChangeDuringResolution(); | 
| +//    AnalysisContextFactory.initContextWithCore(_context); | 
| +//    _sourceFactory = _context.sourceFactory; | 
| +//    Source source = _addSource("/lib.dart", "library lib;"); | 
| +//    CompilationUnit compilationUnit = | 
| +//        _context.resolveCompilationUnit2(source, source); | 
| +//    expect(compilationUnit, isNotNull); | 
| +//    expect(_context.getLineInfo(source), isNotNull); | 
| +//  } | 
| + | 
| +  void test_resolveCompilationUnit_source() { | 
| +    Source source = addSource("/lib.dart", "library lib;"); | 
| +    CompilationUnit compilationUnit = | 
| +        context.resolveCompilationUnit2(source, source); | 
| +    expect(compilationUnit, isNotNull); | 
| +  } | 
| + | 
| +  void test_setAnalysisOptions() { | 
| +    AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | 
| +    options.cacheSize = 42; | 
| +    options.dart2jsHint = false; | 
| +    options.hint = false; | 
| +    context.analysisOptions = options; | 
| +    AnalysisOptions result = context.analysisOptions; | 
| +    expect(result.cacheSize, options.cacheSize); | 
| +    expect(result.dart2jsHint, options.dart2jsHint); | 
| +    expect(result.hint, options.hint); | 
| +  } | 
| + | 
| +  void test_setAnalysisPriorityOrder() { | 
| +    int priorityCount = 4; | 
| +    List<Source> sources = <Source>[]; | 
| +    for (int index = 0; index < priorityCount; index++) { | 
| +      sources.add(addSource("/lib.dart$index", "")); | 
| +    } | 
| +    context.analysisPriorityOrder = sources; | 
| +    expect(_getPriorityOrder(context).length, priorityCount); | 
| +  } | 
| + | 
| +  void test_setAnalysisPriorityOrder_empty() { | 
| +    context.analysisPriorityOrder = <Source>[]; | 
| +  } | 
| + | 
| +  void test_setAnalysisPriorityOrder_nonEmpty() { | 
| +    List<Source> sources = <Source>[]; | 
| +    sources.add(addSource("/lib.dart", "library lib;")); | 
| +    context.analysisPriorityOrder = sources; | 
| +  } | 
| + | 
| +  void test_setAnalysisPriorityOrder_resetAnalysisDriver() { | 
| +    Source source = addSource('/lib.dart', 'library lib;'); | 
| +    // start analysis | 
| +    context.performAnalysisTask(); | 
| +    expect(context.driver.currentWorkOrder, isNotNull); | 
| +    // set priority sources, AnalysisDriver is reset | 
| +    context.analysisPriorityOrder = <Source>[source]; | 
| +    expect(context.driver.currentWorkOrder, isNull); | 
| +    // analysis continues | 
| +    context.performAnalysisTask(); | 
| +    expect(context.driver.currentWorkOrder, isNotNull); | 
| +  } | 
| + | 
| +  Future test_setChangedContents_libraryWithPart() { | 
| +    AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | 
| +    options.incremental = true; | 
| +    context.analysisOptions = options; | 
| +    SourcesChangedListener listener = new SourcesChangedListener(); | 
| +    context.onSourcesChanged.listen(listener.onData); | 
| +    String oldCode = r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +int a = 0;'''; | 
| +    Source librarySource = addSource("/lib.dart", oldCode); | 
| +    String partContents = r''' | 
| +part of lib; | 
| +int b = a;'''; | 
| +    Source partSource = addSource("/part.dart", partContents); | 
| +    LibraryElement element = context.computeLibraryElement(librarySource); | 
| +    CompilationUnit unit = | 
| +        context.resolveCompilationUnit(librarySource, element); | 
| +    expect(unit, isNotNull); | 
| +    int offset = oldCode.indexOf("int a") + 4; | 
| +    String newCode = r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +int ya = 0;'''; | 
| +    context.setChangedContents(librarySource, newCode, offset, 0, 1); | 
| +    expect(context.getContents(librarySource).data, newCode); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(partSource, librarySource), isNull); | 
| +    return pumpEventQueue().then((_) { | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(changedSources: [librarySource]); | 
| +      listener.assertNoMoreEvents(); | 
| +    }); | 
| +  } | 
| + | 
| +  void test_setChangedContents_notResolved() { | 
| +    AnalysisOptionsImpl options = | 
| +        new AnalysisOptionsImpl.from(context.analysisOptions); | 
| +    options.incremental = true; | 
| +    context.analysisOptions = options; | 
| +    String oldCode = r''' | 
| +library lib; | 
| +int a = 0;'''; | 
| +    Source librarySource = addSource("/lib.dart", oldCode); | 
| +    int offset = oldCode.indexOf("int a") + 4; | 
| +    String newCode = r''' | 
| +library lib; | 
| +int ya = 0;'''; | 
| +    context.setChangedContents(librarySource, newCode, offset, 0, 1); | 
| +    expect(context.getContents(librarySource).data, newCode); | 
| +  } | 
| + | 
| +  Future test_setContents_libraryWithPart() { | 
| +    SourcesChangedListener listener = new SourcesChangedListener(); | 
| +    context.onSourcesChanged.listen(listener.onData); | 
| +    String libraryContents1 = r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +int a = 0;'''; | 
| +    Source librarySource = addSource("/lib.dart", libraryContents1); | 
| +    String partContents1 = r''' | 
| +part of lib; | 
| +int b = a;'''; | 
| +    Source partSource = addSource("/part.dart", partContents1); | 
| +    context.computeLibraryElement(librarySource); | 
| +    String libraryContents2 = r''' | 
| +library lib; | 
| +part 'part.dart'; | 
| +int aa = 0;'''; | 
| +    context.setContents(librarySource, libraryContents2); | 
| +    expect( | 
| +        context.getResolvedCompilationUnit2(partSource, librarySource), isNull); | 
| +    return pumpEventQueue().then((_) { | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(wereSourcesAdded: true); | 
| +      listener.assertEvent(changedSources: [librarySource]); | 
| +      listener.assertNoMoreEvents(); | 
| +    }); | 
| +  } | 
| + | 
| +  void test_setContents_null() { | 
| +    Source librarySource = addSource( | 
| +        "/lib.dart", | 
| +        r''' | 
| +library lib; | 
| +int a = 0;'''); | 
| +    context.setContents(librarySource, '// different'); | 
| +    context.computeLibraryElement(librarySource); | 
| +    context.setContents(librarySource, null); | 
| +    expect(context.getResolvedCompilationUnit2(librarySource, librarySource), | 
| +        isNull); | 
| +  } | 
| + | 
| +  void test_setContents_unchanged_consistentModificationTime() { | 
| +    String contents = "// foo"; | 
| +    Source source = addSource("/test.dart", contents); | 
| +    context.setContents(source, contents); | 
| +    // do all, no tasks | 
| +    _analyzeAll_assertFinished(); | 
| +    { | 
| +      AnalysisResult result = context.performAnalysisTask(); | 
| +      expect(result.changeNotices, isNull); | 
| +    } | 
| +    // set the same contents, still no tasks | 
| +    context.setContents(source, contents); | 
| +    { | 
| +      AnalysisResult result = context.performAnalysisTask(); | 
| +      expect(result.changeNotices, isNull); | 
| +    } | 
| +  } | 
| + | 
| +  void test_setSourceFactory() { | 
| +    expect(context.sourceFactory, sourceFactory); | 
| +    SourceFactory factory = new SourceFactory([]); | 
| +    context.sourceFactory = factory; | 
| +    expect(context.sourceFactory, factory); | 
| +  } | 
| + | 
| +  void test_updateAnalysis() { | 
| +    expect(context.sourcesNeedingProcessing, isEmpty); | 
| +    Source source = newSource('/test.dart'); | 
| +    AnalysisDelta delta = new AnalysisDelta(); | 
| +    delta.setAnalysisLevel(source, AnalysisLevel.ALL); | 
| +    context.applyAnalysisDelta(delta); | 
| +    expect(context.sourcesNeedingProcessing, contains(source)); | 
| +    delta = new AnalysisDelta(); | 
| +    delta.setAnalysisLevel(source, AnalysisLevel.NONE); | 
| +    context.applyAnalysisDelta(delta); | 
| +    expect(context.sourcesNeedingProcessing.contains(source), isFalse); | 
| +  } | 
| + | 
| +  void test_validateCacheConsistency_deletedSource() { | 
| +    MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); | 
| +    var fileA = resourceProvider.newFile('/a.dart', ""); | 
| +    var fileB = resourceProvider.newFile('/b.dart', "import 'a.dart';"); | 
| +    Source sourceA = fileA.createSource(); | 
| +    Source sourceB = fileB.createSource(); | 
| +    context.applyChanges( | 
| +        new ChangeSet()..addedSource(sourceA)..addedSource(sourceB)); | 
| +    // analyze everything | 
| +    _analyzeAll_assertFinished(); | 
| +    // delete a.dart | 
| +    resourceProvider.deleteFile('/a.dart'); | 
| +    // analysis should eventually stop | 
| +    _analyzeAll_assertFinished(); | 
| +  } | 
| + | 
| +  void xtest_performAnalysisTask_stress() { | 
| +    int maxCacheSize = 4; | 
| +    AnalysisOptionsImpl options = | 
| +        new AnalysisOptionsImpl.from(context.analysisOptions); | 
| +    options.cacheSize = maxCacheSize; | 
| +    context.analysisOptions = options; | 
| +    int sourceCount = maxCacheSize + 2; | 
| +    List<Source> sources = <Source>[]; | 
| +    ChangeSet changeSet = new ChangeSet(); | 
| +    for (int i = 0; i < sourceCount; i++) { | 
| +      Source source = addSource("/lib$i.dart", "library lib$i;"); | 
| +      sources.add(source); | 
| +      changeSet.addedSource(source); | 
| +    } | 
| +    context.applyChanges(changeSet); | 
| +    context.analysisPriorityOrder = sources; | 
| +    for (int i = 0; i < 1000; i++) { | 
| +      List<ChangeNotice> notice = context.performAnalysisTask().changeNotices; | 
| +      if (notice == null) { | 
| +        //System.out.println("test_performAnalysisTask_stress: " + i); | 
| +        break; | 
| +      } | 
| +    } | 
| +    List<ChangeNotice> notice = context.performAnalysisTask().changeNotices; | 
| +    if (notice != null) { | 
| +      fail( | 
| +          "performAnalysisTask failed to terminate after analyzing all sources"); | 
| +    } | 
| +  } | 
| + | 
| +  TestSource _addSourceWithException(String fileName) { | 
| +    return _addSourceWithException2(fileName, ""); | 
| +  } | 
| + | 
| +  TestSource _addSourceWithException2(String fileName, String contents) { | 
| +    TestSource source = new TestSource(fileName, contents); | 
| +    source.generateExceptionOnRead = true; | 
| +    ChangeSet changeSet = new ChangeSet(); | 
| +    changeSet.addedSource(source); | 
| +    context.applyChanges(changeSet); | 
| +    return source; | 
| +  } | 
| + | 
| +  /** | 
| +   * Perform analysis tasks up to 512 times and assert that it was enough. | 
| +   */ | 
| +  void _analyzeAll_assertFinished([int maxIterations = 512]) { | 
| +    for (int i = 0; i < maxIterations; i++) { | 
| +      List<ChangeNotice> notice = context.performAnalysisTask().changeNotices; | 
| +      if (notice == null) { | 
| +        bool inconsistent = context.validateCacheConsistency(); | 
| +        if (!inconsistent) { | 
| +          return; | 
| +        } | 
| +      } | 
| +    } | 
| +    fail("performAnalysisTask failed to terminate after analyzing all sources"); | 
| +  } | 
| + | 
| +  void _changeSource(TestSource source, String contents) { | 
| +    source.setContents(contents); | 
| +    ChangeSet changeSet = new ChangeSet(); | 
| +    changeSet.changedSource(source); | 
| +    context.applyChanges(changeSet); | 
| +  } | 
| + | 
| +  /** | 
| +   * Search the given compilation unit for a class with the given name. Return the class with the | 
| +   * given name, or `null` if the class cannot be found. | 
| +   * | 
| +   * @param unit the compilation unit being searched | 
| +   * @param className the name of the class being searched for | 
| +   * @return the class with the given name | 
| +   */ | 
| +  ClassElement _findClass(CompilationUnitElement unit, String className) { | 
| +    for (ClassElement classElement in unit.types) { | 
| +      if (classElement.displayName == className) { | 
| +        return classElement; | 
| +      } | 
| +    } | 
| +    return null; | 
| +  } | 
| + | 
| +  void _flushAst(Source source) { | 
| +    CacheEntry entry = | 
| +        context.getCacheEntry(new LibrarySpecificUnit(source, source)); | 
| +    entry.setState(RESOLVED_UNIT, CacheState.FLUSHED); | 
| +  } | 
| + | 
| +  List<Source> _getPriorityOrder(AnalysisContextImpl context) { | 
| +    return context.test_priorityOrder; | 
| +  } | 
| + | 
| +  void _performPendingAnalysisTasks([int maxTasks = 512]) { | 
| +    for (int i = 0; context.performAnalysisTask().hasMoreWork; i++) { | 
| +      if (i > maxTasks) { | 
| +        fail('Analysis did not terminate.'); | 
| +      } | 
| +    } | 
| +  } | 
| + | 
| +  void _removeSource(Source source) { | 
| +    resourceProvider.deleteFile(source.fullName); | 
| +    ChangeSet changeSet = new ChangeSet(); | 
| +    changeSet.removedSource(source); | 
| +    context.applyChanges(changeSet); | 
| +  } | 
| + | 
| +  /** | 
| +   * Returns `true` if there is an [AnalysisError] with [ErrorSeverity.ERROR] in | 
| +   * the given [AnalysisErrorInfo]. | 
| +   */ | 
| +  static bool _hasAnalysisErrorWithErrorSeverity(AnalysisErrorInfo errorInfo) { | 
| +    List<AnalysisError> errors = errorInfo.errors; | 
| +    for (AnalysisError analysisError in errors) { | 
| +      if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) { | 
| +        return true; | 
| +      } | 
| +    } | 
| +    return false; | 
| +  } | 
| +} | 
| + | 
| +@reflectiveTest | 
| +class LimitedInvalidateTest extends AbstractContextTest { | 
| +  @override | 
| +  void setUp() { | 
| +    AnalysisEngine.instance.limitInvalidationInTaskModel = true; | 
| +    super.setUp(); | 
| +    AnalysisOptionsImpl options = | 
| +        new AnalysisOptionsImpl.from(context.analysisOptions); | 
| +    options.incremental = true; | 
| +    context.analysisOptions = options; | 
| +  } | 
| + | 
| +  @override | 
| +  void tearDown() { | 
| +    AnalysisEngine.instance.limitInvalidationInTaskModel = false; | 
| +    super.tearDown(); | 
| +  } | 
| + | 
| +  void test_noChange_thenChange() { | 
| +    Source sourceA = addSource( | 
| +        "/a.dart", | 
| +        r''' | 
| +library lib_a; | 
| + | 
| +class A { | 
| +  A(); | 
| +} | 
| +class B { | 
| +  B(); | 
| +} | 
| +'''); | 
| +    Source sourceB = addSource( | 
| +        "/b.dart", | 
| +        r''' | 
| +library lib_b; | 
| +import 'a.dart'; | 
| +main() { | 
| +  new A(); | 
| +} | 
| +'''); | 
| +    _performPendingAnalysisTasks(); | 
| +    expect(context.getErrors(sourceA).errors, hasLength(0)); | 
| +    expect(context.getErrors(sourceB).errors, hasLength(0)); | 
| +    var unitA = context.getResolvedCompilationUnit2(sourceA, sourceA); | 
| +    var unitElementA = unitA.element; | 
| +    var libraryElementA = unitElementA.library; | 
| +    // Update a.dart, no declaration changes. | 
| +    context.setContents( | 
| +        sourceA, | 
| +        r''' | 
| +library lib_a; | 
| +class A { | 
| +  A(); | 
| +} | 
| +class B { | 
| +  B(); | 
| +} | 
| +'''); | 
| +    _assertInvalid(sourceA, LIBRARY_ERRORS_READY); | 
| +    _assertValid(sourceB, LIBRARY_ELEMENT); | 
| +    // The a.dart's unit and element are updated incrementally. | 
| +    // They are the same instances as initially. | 
| +    // So, all the references from other units are still valid. | 
| +    { | 
| +      LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA); | 
| +      expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA)); | 
| +      expect(unitA.element, same(unitElementA)); | 
| +      expect(unitElementA.library, same(libraryElementA)); | 
| +    } | 
| +    // Analyze. | 
| +    _performPendingAnalysisTasks(); | 
| +    expect(context.getErrors(sourceA).errors, hasLength(0)); | 
| +    expect(context.getErrors(sourceB).errors, hasLength(0)); | 
| +    // The a.dart's unit and element are the same. | 
| +    { | 
| +      LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA); | 
| +      expect(analysisCache.getValue(target, RESOLVED_UNIT), same(unitA)); | 
| +      expect(unitA.element, same(unitElementA)); | 
| +      expect(unitElementA.library, same(libraryElementA)); | 
| +    } | 
| +    // Update a.dart, rename A to A2, invalidates b.dart, so | 
| +    // we know that the previous update did not damage dependencies. | 
| +    context.setContents( | 
| +        sourceA, | 
| +        r''' | 
| +library lib_a; | 
| +class A { | 
| +  A(); | 
| +  m() {} | 
| +} | 
| +class B { | 
| +  B(); | 
| +} | 
| +'''); | 
| +    _assertInvalid(sourceA, LIBRARY_ERRORS_READY); | 
| +    _assertInvalid(sourceB, LIBRARY_ELEMENT); | 
| +    // The a.dart's unit and element are the same. | 
| +    { | 
| +      LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA); | 
| +      expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA)); | 
| +      expect(unitA.element, same(unitElementA)); | 
| +      expect(unitElementA.library, same(libraryElementA)); | 
| +    } | 
| +    // Analyze. | 
| +    _performPendingAnalysisTasks(); | 
| +    expect(context.getErrors(sourceA).errors, hasLength(0)); | 
| +    expect(context.getErrors(sourceB).errors, hasLength(0)); | 
| +  } | 
| + | 
| +  void test_unusedName() { | 
| +    Source sourceA = addSource( | 
| +        "/a.dart", | 
| +        r''' | 
| +library lib_a; | 
| +class A {} | 
| +class B {} | 
| +class C {} | 
| +'''); | 
| +    Source sourceB = addSource( | 
| +        "/b.dart", | 
| +        r''' | 
| +library lib_b; | 
| +import 'a.dart'; | 
| +main() { | 
| +  new A(); | 
| +  new C(); | 
| +} | 
| +'''); | 
| +    _performPendingAnalysisTasks(); | 
| +    // Update A. | 
| +    context.setContents( | 
| +        sourceA, | 
| +        r''' | 
| +library lib_a; | 
| +class A {} | 
| +class B2 {} | 
| +class C {} | 
| +'''); | 
| +    // Only a.dart is invalidated. | 
| +    // Because b.dart does not use B, so it is valid. | 
| +    _assertInvalid(sourceA, LIBRARY_ERRORS_READY); | 
| +    _assertValid(sourceB, LIBRARY_ERRORS_READY); | 
| +  } | 
| + | 
| +  void test_usedName_directUser() { | 
| +    Source sourceA = addSource( | 
| +        "/a.dart", | 
| +        r''' | 
| +library lib_a; | 
| +class A {} | 
| +class B {} | 
| +class C {} | 
| +'''); | 
| +    Source sourceB = addSource( | 
| +        "/b.dart", | 
| +        r''' | 
| +library lib_b; | 
| +import 'a.dart'; | 
| +main() { | 
| +  new A(); | 
| +  new C2(); | 
| +} | 
| +'''); | 
| +    _performPendingAnalysisTasks(); | 
| +    expect(context.getErrors(sourceB).errors, hasLength(1)); | 
| +    // Update a.dart, invalidates b.dart because it references "C2". | 
| +    context.setContents( | 
| +        sourceA, | 
| +        r''' | 
| +library lib_a; | 
| +class A {} | 
| +class B {} | 
| +class C2 {} | 
| +'''); | 
| +    _assertInvalid(sourceA, LIBRARY_ERRORS_READY); | 
| +    _assertInvalid(sourceB, LIBRARY_ERRORS_READY); | 
| +    // Now b.dart is analyzed and the error is fixed. | 
| +    _performPendingAnalysisTasks(); | 
| +    expect(context.getErrors(sourceB).errors, hasLength(0)); | 
| +    // Update a.dart, invalidates b.dart because it references "C". | 
| +    context.setContents( | 
| +        sourceA, | 
| +        r''' | 
| +library lib_a; | 
| +class A {} | 
| +class B {} | 
| +class C {} | 
| +'''); | 
| +    _assertInvalid(sourceA, LIBRARY_ERRORS_READY); | 
| +    _assertInvalid(sourceB, LIBRARY_ERRORS_READY); | 
| +    _performPendingAnalysisTasks(); | 
| +    // Now b.dart is analyzed and it again has the error. | 
| +    expect(context.getErrors(sourceB).errors, hasLength(1)); | 
| +  } | 
| + | 
| +  void test_usedName_directUser_withIncremental() { | 
| +    Source sourceA = addSource( | 
| +        "/a.dart", | 
| +        r''' | 
| +library lib_a; | 
| +class A { | 
| +  m() {} | 
| +} | 
| +'''); | 
| +    Source sourceB = addSource( | 
| +        "/b.dart", | 
| +        r''' | 
| +library lib_b; | 
| +import 'a.dart'; | 
| +main() { | 
| +  A a = new A(); | 
| +  a.m(); | 
| +} | 
| +'''); | 
| +    _performPendingAnalysisTasks(); | 
| +    // Update A. | 
| +    context.setContents( | 
| +        sourceA, | 
| +        r''' | 
| +library lib_a; | 
| +class A { | 
| +  m2() {} | 
| +} | 
| +'''); | 
| +    _assertInvalid(sourceA, LIBRARY_ERRORS_READY); | 
| +    _assertInvalid(sourceB, LIBRARY_ERRORS_READY); | 
| +  } | 
| + | 
| +  void test_usedName_indirectUser() { | 
| +    Source sourceA = addSource( | 
| +        "/a.dart", | 
| +        r''' | 
| +library lib_a; | 
| +class A { | 
| +  m() {} | 
| +} | 
| +'''); | 
| +    Source sourceB = addSource( | 
| +        "/b.dart", | 
| +        r''' | 
| +library lib_b; | 
| +import 'a.dart'; | 
| +class B extends A {} | 
| +'''); | 
| +    Source sourceC = addSource( | 
| +        "/c.dart", | 
| +        r''' | 
| +library lib_c; | 
| +import 'b.dart'; | 
| +class C extends B { | 
| +  main() { | 
| +    m(); | 
| +  } | 
| +} | 
| +'''); | 
| +    // No errors, "A.m" exists. | 
| +    _performPendingAnalysisTasks(); | 
| +    expect(context.getErrors(sourceC).errors, hasLength(0)); | 
| +    // Replace "A.m" with "A.m2", invalidate both b.dart and c.dart files. | 
| +    context.setContents( | 
| +        sourceA, | 
| +        r''' | 
| +library lib_a; | 
| +class A { | 
| +  m2() {} | 
| +} | 
| +'''); | 
| +    _assertInvalid(sourceA, LIBRARY_ERRORS_READY); | 
| +    _assertInvalid(sourceB, LIBRARY_ERRORS_READY); | 
| +    _assertInvalid(sourceC, LIBRARY_ERRORS_READY); | 
| +    // There is an error in c.dart, "A.m" does not exist. | 
| +    _performPendingAnalysisTasks(); | 
| +    expect(context.getErrors(sourceB).errors, hasLength(0)); | 
| +    expect(context.getErrors(sourceC).errors, hasLength(1)); | 
| +    // Restore "A.m", invalidate both b.dart and c.dart files. | 
| +    context.setContents( | 
| +        sourceA, | 
| +        r''' | 
| +library lib_a; | 
| +class A { | 
| +  m() {} | 
| +} | 
| +'''); | 
| +    _assertInvalid(sourceA, LIBRARY_ERRORS_READY); | 
| +    _assertInvalid(sourceB, LIBRARY_ERRORS_READY); | 
| +    _assertInvalid(sourceC, LIBRARY_ERRORS_READY); | 
| +    // No errors, "A.m" exists. | 
| +    _performPendingAnalysisTasks(); | 
| +    expect(context.getErrors(sourceC).errors, hasLength(0)); | 
| +  } | 
| + | 
| +  void _assertInvalid(AnalysisTarget target, ResultDescriptor descriptor) { | 
| +    CacheState state = analysisCache.getState(target, descriptor); | 
| +    expect(state, CacheState.INVALID); | 
| +  } | 
| + | 
| +  void _assertValid(AnalysisTarget target, ResultDescriptor descriptor) { | 
| +    CacheState state = analysisCache.getState(target, descriptor); | 
| +    expect(state, CacheState.VALID); | 
| +  } | 
| + | 
| +  void _performPendingAnalysisTasks([int maxTasks = 512]) { | 
| +    for (int i = 0; context.performAnalysisTask().hasMoreWork; i++) { | 
| +      if (i > maxTasks) { | 
| +        fail('Analysis did not terminate.'); | 
| +      } | 
| +    } | 
| +  } | 
| +} | 
| + | 
| +class _AnalysisContextImplTest_test_applyChanges_removeContainer | 
| +    implements SourceContainer { | 
| +  Source libB; | 
| +  _AnalysisContextImplTest_test_applyChanges_removeContainer(this.libB); | 
| +  @override | 
| +  bool contains(Source source) => source == libB; | 
| +} | 
|  |