Index: pkg/analysis_server/test/services/search/search_engine_test.dart |
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart |
index d3e19e8c83a3242b68beae73e6bb4b14e830c7a9..1ad67ca172f003c6608aaac4ce031f6723f71ef5 100644 |
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart |
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart |
@@ -1,90 +1,70 @@ |
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |
import 'dart:async'; |
-import 'package:analysis_server/src/services/index/index.dart'; |
import 'package:analysis_server/src/services/search/search_engine.dart'; |
-import 'package:analysis_server/src/services/search/search_engine_internal.dart'; |
+import 'package:analysis_server/src/services/search/search_engine_internal2.dart'; |
import 'package:analyzer/dart/element/element.dart'; |
-import 'package:analyzer/src/dart/analysis/ast_provider_context.dart'; |
-import 'package:analyzer/src/dart/element/element.dart'; |
-import 'package:analyzer/src/dart/element/member.dart'; |
+import 'package:analyzer/file_system/file_system.dart'; |
+import 'package:analyzer/file_system/memory_file_system.dart'; |
+import 'package:analyzer/src/dart/analysis/driver.dart'; |
+import 'package:analyzer/src/dart/analysis/file_state.dart'; |
+import 'package:analyzer/src/generated/engine.dart'; |
+import 'package:analyzer/src/generated/sdk.dart'; |
import 'package:analyzer/src/generated/source.dart'; |
+import 'package:front_end/src/base/performace_logger.dart'; |
+import 'package:front_end/src/incremental/byte_store.dart'; |
import 'package:test/test.dart'; |
import 'package:test_reflective_loader/test_reflective_loader.dart'; |
-import '../../abstract_single_unit.dart'; |
+import '../../mock_sdk.dart'; |
main() { |
defineReflectiveSuite(() { |
- defineReflectiveTests(SearchEngineImplTest); |
+ defineReflectiveTests(SearchEngineImpl2Test); |
}); |
} |
-class ExpectedMatch { |
- final Element element; |
- final MatchKind kind; |
- SourceRange range; |
- final bool isResolved; |
- final bool isQualified; |
- |
- ExpectedMatch(this.element, this.kind, int offset, int length, |
- {this.isResolved: true, this.isQualified: false}) { |
- this.range = new SourceRange(offset, length); |
- } |
- |
- bool operator ==(Object match) { |
- return match is SearchMatch && |
- match.element == this.element && |
- match.kind == this.kind && |
- match.isResolved == this.isResolved && |
- match.isQualified == this.isQualified && |
- match.sourceRange == this.range; |
- } |
- |
- @override |
- String toString() { |
- StringBuffer buffer = new StringBuffer(); |
- buffer.write("ExpectedMatch(kind="); |
- buffer.write(kind); |
- buffer.write(", element="); |
- buffer.write(element != null ? element.displayName : 'null'); |
- buffer.write(", range="); |
- buffer.write(range); |
- buffer.write(", isResolved="); |
- buffer.write(isResolved); |
- buffer.write(", isQualified="); |
- buffer.write(isQualified); |
- buffer.write(")"); |
- return buffer.toString(); |
- } |
-} |
- |
@reflectiveTest |
-class SearchEngineImplTest extends AbstractSingleUnitTest { |
- Index index; |
- SearchEngineImpl searchEngine; |
+class SearchEngineImpl2Test { |
+ final MemoryResourceProvider provider = new MemoryResourceProvider(); |
+ DartSdk sdk; |
+ final ByteStore byteStore = new MemoryByteStore(); |
+ final FileContentOverlay contentOverlay = new FileContentOverlay(); |
+ |
+ final StringBuffer logBuffer = new StringBuffer(); |
+ PerformanceLog logger; |
- @override |
- bool get enableNewAnalysisDriver => false; |
+ AnalysisDriverScheduler scheduler; |
void setUp() { |
- super.setUp(); |
- index = createMemoryIndex(); |
- searchEngine = |
- new SearchEngineImpl(index, (_) => new AstProviderForContext(context)); |
+ sdk = new MockSdk(resourceProvider: provider); |
+ logger = new PerformanceLog(logBuffer); |
+ scheduler = new AnalysisDriverScheduler(logger); |
+ scheduler.start(); |
} |
test_searchAllSubtypes() async { |
- await _indexTestUnit(''' |
+ var p = _p('/test.dart'); |
+ |
+ provider.newFile( |
+ p, |
+ ''' |
class T {} |
class A extends T {} |
class B extends A {} |
class C implements B {} |
'''); |
- ClassElement element = findElement('T'); |
+ |
+ var driver = _newDriver(); |
+ driver.addFile(p); |
+ |
+ var resultA = await driver.getResult(p); |
+ ClassElement element = resultA.unit.element.types[0]; |
+ |
+ var searchEngine = new SearchEngineImpl2([driver]); |
Set<ClassElement> subtypes = await searchEngine.searchAllSubtypes(element); |
expect(subtypes, hasLength(3)); |
expect(subtypes, contains(predicate((ClassElement e) => e.name == 'A'))); |
@@ -92,863 +72,226 @@ class C implements B {} |
expect(subtypes, contains(predicate((ClassElement e) => e.name == 'C'))); |
} |
- test_searchMemberDeclarations() async { |
- await _indexTestUnit(''' |
-class A { |
- test() {} |
-} |
-class B { |
- int test = 1; |
- int testTwo = 2; |
- main() { |
- int test = 3; |
- } |
-} |
-'''); |
- ClassElement elementA = findElement('A'); |
- ClassElement elementB = findElement('B'); |
- var expected = [ |
- _expectId(elementA.methods[0], MatchKind.DECLARATION, 'test() {}'), |
- _expectId(elementB.fields[0], MatchKind.DECLARATION, 'test = 1;') |
- ]; |
- List<SearchMatch> matches = |
- await searchEngine.searchMemberDeclarations('test'); |
- _assertMatches(matches, expected); |
- } |
- |
- test_searchMemberReferences_qualified_resolved() async { |
- await _indexTestUnit(''' |
-class C { |
- var test; |
-} |
-main(C c) { |
- print(c.test); |
- c.test = 1; |
- c.test += 2; |
- c.test(); |
-} |
-'''); |
- List<SearchMatch> matches = |
- await searchEngine.searchMemberReferences('test'); |
- expect(matches, isEmpty); |
- } |
- |
- test_searchMemberReferences_qualified_unresolved() async { |
- await _indexTestUnit(''' |
-main(p) { |
- print(p.test); |
- p.test = 1; |
- p.test += 2; |
- p.test(); |
-} |
-'''); |
- Element main = findElement('main'); |
- var expected = [ |
- _expectIdQU(main, MatchKind.READ, 'test);'), |
- _expectIdQU(main, MatchKind.WRITE, 'test = 1;'), |
- _expectIdQU(main, MatchKind.READ_WRITE, 'test += 2;'), |
- _expectIdQU(main, MatchKind.INVOCATION, 'test();'), |
- ]; |
- List<SearchMatch> matches = |
- await searchEngine.searchMemberReferences('test'); |
- _assertMatches(matches, expected); |
- } |
- |
- test_searchMemberReferences_unqualified_resolved() async { |
- await _indexTestUnit(''' |
-class C { |
- var test; |
- main() { |
- print(test); |
- test = 1; |
- test += 2; |
- test(); |
- } |
-} |
-'''); |
- List<SearchMatch> matches = |
- await searchEngine.searchMemberReferences('test'); |
- expect(matches, isEmpty); |
- } |
- |
- test_searchMemberReferences_unqualified_unresolved() async { |
- verifyNoTestUnitErrors = false; |
- await _indexTestUnit(''' |
-class C { |
- main() { |
- print(test); |
- test = 1; |
- test += 2; |
- test(); |
- } |
-} |
-'''); |
- Element main = findElement('main'); |
- var expected = [ |
- _expectIdU(main, MatchKind.READ, 'test);'), |
- _expectIdU(main, MatchKind.WRITE, 'test = 1;'), |
- _expectIdU(main, MatchKind.READ_WRITE, 'test += 2;'), |
- _expectIdU(main, MatchKind.INVOCATION, 'test();'), |
- ]; |
- List<SearchMatch> matches = |
- await searchEngine.searchMemberReferences('test'); |
- _assertMatches(matches, expected); |
- } |
- |
- test_searchReferences_ClassElement() async { |
- await _indexTestUnit(''' |
-class A {} |
-main(A p) { |
- A v; |
-} |
-'''); |
- ClassElement element = findElement('A'); |
- Element pElement = findElement('p'); |
- Element vElement = findElement('v'); |
- var expected = [ |
- _expectId(pElement, MatchKind.REFERENCE, 'A p'), |
- _expectId(vElement, MatchKind.REFERENCE, 'A v') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ test_searchAllSubtypes_acrossDrivers() async { |
+ var a = _p('/test/a.dart'); |
+ var b = _p('/test/b.dart'); |
- test_searchReferences_CompilationUnitElement() async { |
- addSource( |
- '/my_part.dart', |
+ provider.newFile( |
+ a, |
''' |
-part of lib; |
+class T {} |
+class A extends T {} |
'''); |
- await _indexTestUnit(''' |
-library lib; |
-part 'my_part.dart'; |
+ provider.newFile( |
+ b, |
+ ''' |
+import 'a.dart'; |
+class B extends A {} |
+class C extends B {} |
'''); |
- CompilationUnitElement element = testLibraryElement.parts[0]; |
- var expected = [ |
- _expectIdQ(testUnitElement, MatchKind.REFERENCE, "'my_part.dart'", |
- length: "'my_part.dart'".length) |
- ]; |
- await _verifyReferences(element, expected); |
- } |
- test_searchReferences_ConstructorElement() async { |
- await _indexTestUnit(''' |
-class A { |
- A.named() {} |
-} |
-main() { |
- new A.named(); |
-} |
-'''); |
- ConstructorElement element = findElement('named'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectIdQ(mainElement, MatchKind.REFERENCE, '.named();', length: 6) |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ var driver1 = _newDriver(); |
+ var driver2 = _newDriver(); |
- test_searchReferences_ConstructorElement_synthetic() async { |
- await _indexTestUnit(''' |
-class A { |
-} |
-main() { |
- new A(); |
-} |
-'''); |
- ClassElement classElement = findElement('A'); |
- ConstructorElement element = classElement.unnamedConstructor; |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectIdQ(mainElement, MatchKind.REFERENCE, '();', length: 0) |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ driver1.addFile(a); |
+ driver2.addFile(b); |
- test_searchReferences_Element_unknown() async { |
- await _verifyReferences(DynamicElementImpl.instance, []); |
- } |
+ var resultA = await driver1.getResult(a); |
+ ClassElement element = resultA.unit.element.types[0]; |
- test_searchReferences_FieldElement() async { |
- await _indexTestUnit(''' |
-class A { |
- var field; |
- A({this.field}); |
- main() { |
- new A(field: 1); |
- // getter |
- print(field); // ref-nq |
- print(this.field); // ref-q |
- field(); // inv-nq |
- this.field(); // inv-q |
- // setter |
- field = 2; // ref-nq; |
- this.field = 3; // ref-q; |
- } |
-} |
-'''); |
- FieldElement element = findElement('field', ElementKind.FIELD); |
- Element main = findElement('main'); |
- Element fieldParameter = findElement('field', ElementKind.PARAMETER); |
- var expected = [ |
- _expectIdQ(fieldParameter, MatchKind.WRITE, 'field}'), |
- _expectIdQ(main, MatchKind.REFERENCE, 'field: 1'), |
- _expectId(main, MatchKind.READ, 'field); // ref-nq'), |
- _expectIdQ(main, MatchKind.READ, 'field); // ref-q'), |
- _expectId(main, MatchKind.INVOCATION, 'field(); // inv-nq'), |
- _expectIdQ(main, MatchKind.INVOCATION, 'field(); // inv-q'), |
- _expectId(main, MatchKind.WRITE, 'field = 2; // ref-nq'), |
- _expectIdQ(main, MatchKind.WRITE, 'field = 3; // ref-q'), |
- ]; |
- await _verifyReferences(element, expected); |
+ var searchEngine = new SearchEngineImpl2([driver1, driver2]); |
+ Set<ClassElement> subtypes = await searchEngine.searchAllSubtypes(element); |
+ expect(subtypes, hasLength(3)); |
+ expect(subtypes, contains(predicate((ClassElement e) => e.name == 'A'))); |
+ expect(subtypes, contains(predicate((ClassElement e) => e.name == 'B'))); |
+ expect(subtypes, contains(predicate((ClassElement e) => e.name == 'C'))); |
} |
- test_searchReferences_FieldElement_ofEnum() async { |
- await _indexTestUnit(''' |
-enum MyEnum { |
- A, B, C |
-} |
-main() { |
- print(MyEnum.A.index); |
- print(MyEnum.values); |
- print(MyEnum.A); |
- print(MyEnum.B); |
-} |
-'''); |
- ClassElement enumElement = findElement('MyEnum'); |
- Element mainElement = findElement('main'); |
- await _verifyReferences(enumElement.getField('index'), |
- [_expectIdQ(mainElement, MatchKind.READ, 'index);')]); |
- await _verifyReferences(enumElement.getField('values'), |
- [_expectIdQ(mainElement, MatchKind.READ, 'values);')]); |
- await _verifyReferences(enumElement.getField('A'), [ |
- _expectIdQ(mainElement, MatchKind.READ, 'A.index);'), |
- _expectIdQ(mainElement, MatchKind.READ, 'A);') |
- ]); |
- await _verifyReferences(enumElement.getField('B'), |
- [_expectIdQ(mainElement, MatchKind.READ, 'B);')]); |
- } |
+ test_searchMemberDeclarations() async { |
+ var a = _p('/test/a.dart'); |
+ var b = _p('/test/b.dart'); |
- test_searchReferences_FieldElement_synthetic() async { |
- await _indexTestUnit(''' |
+ var codeA = ''' |
class A { |
- get field => null; |
- set field(x) {} |
- main() { |
- // getter |
- print(field); // ref-nq |
- print(this.field); // ref-q |
- field(); // inv-nq |
- this.field(); // inv-q |
- // setter |
- field = 2; // ref-nq; |
- this.field = 3; // ref-q; |
- } |
+ int test; // 1 |
+ int testTwo; |
} |
-'''); |
- FieldElement element = findElement('field', ElementKind.FIELD); |
- Element main = findElement('main'); |
- var expected = [ |
- _expectId(main, MatchKind.READ, 'field); // ref-nq'), |
- _expectIdQ(main, MatchKind.READ, 'field); // ref-q'), |
- _expectId(main, MatchKind.INVOCATION, 'field(); // inv-nq'), |
- _expectIdQ(main, MatchKind.INVOCATION, 'field(); // inv-q'), |
- _expectId(main, MatchKind.WRITE, 'field = 2; // ref-nq'), |
- _expectIdQ(main, MatchKind.WRITE, 'field = 3; // ref-q'), |
- ]; |
- await _verifyReferences(element, expected); |
- } |
- |
- test_searchReferences_FunctionElement() async { |
- await _indexTestUnit(''' |
-test() {} |
-main() { |
- test(); |
- print(test); |
+'''; |
+ var codeB = ''' |
+class B { |
+ void test() {} // 2 |
+ void testTwo() {} |
} |
-'''); |
- FunctionElement element = findElement('test'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(mainElement, MatchKind.INVOCATION, 'test();'), |
- _expectId(mainElement, MatchKind.REFERENCE, 'test);') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+int test; |
+'''; |
- test_searchReferences_FunctionElement_local() async { |
- await _indexTestUnit(''' |
-main() { |
- test() {} |
- test(); |
- print(test); |
-} |
-'''); |
- FunctionElement element = findElement('test'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(mainElement, MatchKind.INVOCATION, 'test();'), |
- _expectId(mainElement, MatchKind.REFERENCE, 'test);') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ provider.newFile(a, codeA); |
+ provider.newFile(b, codeB); |
- test_searchReferences_FunctionTypeAliasElement() async { |
- await _indexTestUnit(''' |
-typedef Test(); |
-main() { |
- Test a; |
- Test b; |
-} |
-'''); |
- FunctionTypeAliasElement element = findElement('Test'); |
- Element aElement = findElement('a'); |
- Element bElement = findElement('b'); |
- var expected = [ |
- _expectId(aElement, MatchKind.REFERENCE, 'Test a;'), |
- _expectId(bElement, MatchKind.REFERENCE, 'Test b;') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ var driver1 = _newDriver(); |
+ var driver2 = _newDriver(); |
- test_searchReferences_ImportElement_noPrefix() async { |
- await _indexTestUnit(''' |
-import 'dart:math' show max, PI, Random hide min; |
-export 'dart:math' show max, PI, Random hide min; |
-main() { |
- print(PI); |
- print(new Random()); |
- print(max(1, 2)); |
-} |
-Random bar() => null; |
-'''); |
- ImportElement element = testLibraryElement.imports[0]; |
- Element mainElement = findElement('main'); |
- Element barElement = findElement('bar'); |
- var kind = MatchKind.REFERENCE; |
- var expected = [ |
- _expectId(mainElement, kind, 'PI);', length: 0), |
- _expectId(mainElement, kind, 'Random()', length: 0), |
- _expectId(mainElement, kind, 'max(', length: 0), |
- _expectId(barElement, kind, 'Random bar()', length: 0), |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ driver1.addFile(a); |
+ driver2.addFile(b); |
- test_searchReferences_ImportElement_withPrefix() async { |
- await _indexTestUnit(''' |
-import 'dart:math' as math show max, PI, Random hide min; |
-export 'dart:math' show max, PI, Random hide min; |
-main() { |
- print(math.PI); |
- print(new math.Random()); |
- print(math.max(1, 2)); |
-} |
-math.Random bar() => null; |
-'''); |
- ImportElement element = testLibraryElement.imports[0]; |
- Element mainElement = findElement('main'); |
- Element barElement = findElement('bar'); |
- var kind = MatchKind.REFERENCE; |
- var length = 'math.'.length; |
- var expected = [ |
- _expectId(mainElement, kind, 'math.PI);', length: length), |
- _expectId(mainElement, kind, 'math.Random()', length: length), |
- _expectId(mainElement, kind, 'math.max(', length: length), |
- _expectId(barElement, kind, 'math.Random bar()', length: length), |
- ]; |
- await _verifyReferences(element, expected); |
- } |
- |
- test_searchReferences_ImportElement_withPrefix_forMultipleImports() async { |
- await _indexTestUnit(''' |
-import 'dart:async' as p; |
-import 'dart:math' as p; |
-main() { |
- p.Random; |
- p.Future; |
-} |
-'''); |
- Element mainElement = findElement('main'); |
- var kind = MatchKind.REFERENCE; |
- var length = 'p.'.length; |
- { |
- ImportElement element = testLibraryElement.imports[0]; |
- var expected = [ |
- _expectId(mainElement, kind, 'p.Future;', length: length), |
- ]; |
- await _verifyReferences(element, expected); |
- } |
- { |
- ImportElement element = testLibraryElement.imports[1]; |
- var expected = [ |
- _expectId(mainElement, kind, 'p.Random', length: length), |
- ]; |
- await _verifyReferences(element, expected); |
+ while (scheduler.isAnalyzing) { |
+ await new Future.delayed(new Duration(milliseconds: 1)); |
} |
- } |
- test_searchReferences_LabelElement() async { |
- await _indexTestUnit(''' |
-main() { |
-label: |
- while (true) { |
- if (true) { |
- break label; // 1 |
+ var searchEngine = new SearchEngineImpl2([driver1, driver2]); |
+ List<SearchMatch> matches = |
+ await searchEngine.searchMemberDeclarations('test'); |
+ expect(matches, hasLength(2)); |
+ |
+ void assertHasElement(String name, int nameOffset) { |
+ expect( |
+ matches, |
+ contains(predicate((SearchMatch m) => |
+ m.kind == MatchKind.DECLARATION && |
+ m.element.name == name && |
+ m.element.nameOffset == nameOffset))); |
} |
- break label; // 2 |
- } |
-} |
-'''); |
- LabelElement element = findElement('label'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(mainElement, MatchKind.REFERENCE, 'label; // 1'), |
- _expectId(mainElement, MatchKind.REFERENCE, 'label; // 2') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
- |
- test_searchReferences_LibraryElement() async { |
- var codeA = 'part of lib; // A'; |
- var codeB = 'part of lib; // B'; |
- var sourceA = addSource('/unitA.dart', codeA); |
- var sourceB = addSource('/unitB.dart', codeB); |
- await _indexTestUnit(''' |
-library lib; |
-part 'unitA.dart'; |
-part 'unitB.dart'; |
-'''); |
- LibraryElement element = testLibraryElement; |
- CompilationUnitElement unitElementA = element.parts[0]; |
- CompilationUnitElement unitElementB = element.parts[1]; |
- index.indexUnit( |
- context.resolveCompilationUnit2(sourceA, testLibraryElement.source)); |
- index.indexUnit( |
- context.resolveCompilationUnit2(sourceB, testLibraryElement.source)); |
- var expected = [ |
- new ExpectedMatch(unitElementA, MatchKind.REFERENCE, |
- codeA.indexOf('lib; // A'), 'lib'.length), |
- new ExpectedMatch(unitElementB, MatchKind.REFERENCE, |
- codeB.indexOf('lib; // B'), 'lib'.length), |
- ]; |
- await _verifyReferences(element, expected); |
- } |
- test_searchReferences_LocalVariableElement() async { |
- await _indexTestUnit(''' |
-main() { |
- var v; |
- v = 1; |
- v += 2; |
- print(v); |
- v(); |
-} |
-'''); |
- LocalVariableElement element = findElement('v'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(mainElement, MatchKind.WRITE, 'v = 1;'), |
- _expectId(mainElement, MatchKind.READ_WRITE, 'v += 2;'), |
- _expectId(mainElement, MatchKind.READ, 'v);'), |
- _expectId(mainElement, MatchKind.INVOCATION, 'v();') |
- ]; |
- await _verifyReferences(element, expected); |
+ assertHasElement('test', codeA.indexOf('test; // 1')); |
+ assertHasElement('test', codeB.indexOf('test() {} // 2')); |
} |
- test_searchReferences_LocalVariableElement_inForEachLoop() async { |
- await _indexTestUnit(''' |
-main() { |
- for (var v in []) { |
- v = 1; |
- v += 2; |
- print(v); |
- v(); |
- } |
-} |
-'''); |
- LocalVariableElement element = findElement('v'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(mainElement, MatchKind.WRITE, 'v = 1;'), |
- _expectId(mainElement, MatchKind.READ_WRITE, 'v += 2;'), |
- _expectId(mainElement, MatchKind.READ, 'v);'), |
- _expectId(mainElement, MatchKind.INVOCATION, 'v();') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ test_searchMemberReferences() async { |
+ var a = _p('/test/a.dart'); |
+ var b = _p('/test/b.dart'); |
- test_searchReferences_MethodElement() async { |
- await _indexTestUnit(''' |
+ provider.newFile( |
+ a, |
+ ''' |
class A { |
- m() {} |
- main() { |
- m(); // 1 |
- this.m(); // 2 |
- print(m); // 3 |
- print(this.m); // 4 |
- } |
+ int test; |
} |
-'''); |
- MethodElement method = findElement('m'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(mainElement, MatchKind.INVOCATION, 'm(); // 1'), |
- _expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // 2'), |
- _expectId(mainElement, MatchKind.REFERENCE, 'm); // 3'), |
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'm); // 4') |
- ]; |
- await _verifyReferences(method, expected); |
- } |
- |
- test_searchReferences_MethodMember() async { |
- await _indexTestUnit(''' |
-class A<T> { |
- T m() => null; |
-} |
-main(A<int> a) { |
- a.m(); // ref |
+foo(p) { |
+ p.test; |
} |
'''); |
- MethodMember method = findNodeElementAtString('m(); // ref'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // ref') |
- ]; |
- await _verifyReferences(method, expected); |
- } |
- |
- test_searchReferences_null_noUnitElement() async { |
- await _indexTestUnit(''' |
-class A { |
- m() {} |
-} |
-main(A a) { |
- a.m(); |
+ provider.newFile( |
+ b, |
+ ''' |
+import 'a.dart'; |
+bar(p) { |
+ p.test = 1; |
} |
'''); |
- MethodElement method = findElement('m'); |
- List<SearchMatch> matches = await searchEngine.searchReferences(method); |
- expect(matches, hasLength(1)); |
- // Set the source contents, so the element is invalidated. |
- context.setContents(testSource, ''); |
- expect(matches.single.element, isNull); |
- } |
- test_searchReferences_ParameterElement_ofConstructor() async { |
- await _indexTestUnit(''' |
-class C { |
- var f; |
- C({p}) : f = p + 1 { |
- p = 2; |
- p += 3; |
- print(p); |
- p(); |
- } |
-} |
-main() { |
- new C(p: 42); |
-} |
-'''); |
- ParameterElement element = findElement('p'); |
- ClassElement classC = findElement('C'); |
- ConstructorElement constructorA = classC.unnamedConstructor; |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(constructorA, MatchKind.READ, 'p + 1 {'), |
- _expectId(constructorA, MatchKind.WRITE, 'p = 2;'), |
- _expectId(constructorA, MatchKind.READ_WRITE, 'p += 3;'), |
- _expectId(constructorA, MatchKind.READ, 'p);'), |
- _expectId(constructorA, MatchKind.INVOCATION, 'p();'), |
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ var driver1 = _newDriver(); |
+ var driver2 = _newDriver(); |
- test_searchReferences_ParameterElement_ofLocalFunction() async { |
- await _indexTestUnit(''' |
-main() { |
- foo({p}) { |
- p = 1; |
- p += 2; |
- print(p); |
- p(); |
- } |
- foo(p: 42); |
-} |
-'''); |
- ParameterElement element = findElement('p'); |
- Element fooElement = findElement('foo'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(fooElement, MatchKind.WRITE, 'p = 1;'), |
- _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'), |
- _expectId(fooElement, MatchKind.READ, 'p);'), |
- _expectId(fooElement, MatchKind.INVOCATION, 'p();'), |
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ driver1.addFile(a); |
+ driver2.addFile(b); |
- test_searchReferences_ParameterElement_ofMethod() async { |
- await _indexTestUnit(''' |
-class C { |
- foo({p}) { |
- p = 1; |
- p += 2; |
- print(p); |
- p(); |
- } |
-} |
-main(C c) { |
- c.foo(p: 42); |
-} |
+ var searchEngine = new SearchEngineImpl2([driver1, driver2]); |
+ List<SearchMatch> matches = |
+ await searchEngine.searchMemberReferences('test'); |
+ expect(matches, hasLength(2)); |
+ expect( |
+ matches, |
+ contains(predicate((SearchMatch m) => |
+ m.element.name == 'foo' || m.kind == MatchKind.READ))); |
+ expect( |
+ matches, |
+ contains(predicate((SearchMatch m) => |
+ m.element.name == 'bar' || m.kind == MatchKind.WRITE))); |
+ } |
+ |
+ test_searchReferences() async { |
+ var a = _p('/test/a.dart'); |
+ var b = _p('/test/b.dart'); |
+ |
+ provider.newFile( |
+ a, |
+ ''' |
+class T {} |
+T a; |
'''); |
- ParameterElement element = findElement('p'); |
- Element fooElement = findElement('foo'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(fooElement, MatchKind.WRITE, 'p = 1;'), |
- _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'), |
- _expectId(fooElement, MatchKind.READ, 'p);'), |
- _expectId(fooElement, MatchKind.INVOCATION, 'p();'), |
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
- |
- test_searchReferences_ParameterElement_ofTopLevelFunction() async { |
- await _indexTestUnit(''' |
-foo({p}) { |
- p = 1; |
- p += 2; |
- print(p); |
- p(); |
-} |
-main() { |
- foo(p: 42); |
-} |
+ provider.newFile( |
+ b, |
+ ''' |
+import 'a.dart'; |
+T b; |
'''); |
- ParameterElement element = findElement('p'); |
- Element fooElement = findElement('foo'); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(fooElement, MatchKind.WRITE, 'p = 1;'), |
- _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'), |
- _expectId(fooElement, MatchKind.READ, 'p);'), |
- _expectId(fooElement, MatchKind.INVOCATION, 'p();'), |
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
- test_searchReferences_PrefixElement() async { |
- await _indexTestUnit(''' |
-import 'dart:async' as ppp; |
-main() { |
- ppp.Future a; |
- ppp.Stream b; |
-} |
-'''); |
- PrefixElement element = findNodeElementAtString('ppp;'); |
- Element elementA = findElement('a'); |
- Element elementB = findElement('b'); |
- var expected = [ |
- _expectId(elementA, MatchKind.REFERENCE, 'ppp.Future'), |
- _expectId(elementB, MatchKind.REFERENCE, 'ppp.Stream') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ var driver1 = _newDriver(); |
+ var driver2 = _newDriver(); |
- test_searchReferences_PropertyAccessorElement_getter() async { |
- await _indexTestUnit(''' |
-class A { |
- get ggg => null; |
- main() { |
- print(ggg); // ref-nq |
- print(this.ggg); // ref-q |
- ggg(); // inv-nq |
- this.ggg(); // inv-q |
- } |
-} |
-'''); |
- PropertyAccessorElement element = findElement('ggg', ElementKind.GETTER); |
- Element main = findElement('main'); |
- var expected = [ |
- _expectId(main, MatchKind.REFERENCE, 'ggg); // ref-nq'), |
- _expectIdQ(main, MatchKind.REFERENCE, 'ggg); // ref-q'), |
- _expectId(main, MatchKind.INVOCATION, 'ggg(); // inv-nq'), |
- _expectIdQ(main, MatchKind.INVOCATION, 'ggg(); // inv-q'), |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ driver1.addFile(a); |
+ driver2.addFile(b); |
- test_searchReferences_PropertyAccessorElement_setter() async { |
- await _indexTestUnit(''' |
-class A { |
- set s(x) {} |
- main() { |
- s = 1; |
- this.s = 2; |
- } |
-} |
-'''); |
- PropertyAccessorElement element = findElement('s='); |
- Element mainElement = findElement('main'); |
- var expected = [ |
- _expectId(mainElement, MatchKind.REFERENCE, 's = 1'), |
- _expectIdQ(mainElement, MatchKind.REFERENCE, 's = 2') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ var resultA = await driver1.getResult(a); |
+ ClassElement element = resultA.unit.element.types[0]; |
- test_searchReferences_TopLevelVariableElement() async { |
- addSource( |
- '/lib.dart', |
- ''' |
-library lib; |
-var V; |
-'''); |
- await _indexTestUnit(''' |
-import 'lib.dart' show V; // imp |
-import 'lib.dart' as pref; |
-main() { |
- pref.V = 1; // q |
- print(pref.V); // q |
- pref.V(); // q |
- V = 1; // nq |
- print(V); // nq |
- V(); // nq |
-} |
-'''); |
- ImportElement importElement = testLibraryElement.imports[0]; |
- CompilationUnitElement impUnit = |
- importElement.importedLibrary.definingCompilationUnit; |
- TopLevelVariableElement variable = impUnit.topLevelVariables[0]; |
- Element main = findElement('main'); |
- var expected = [ |
- _expectIdQ(testUnitElement, MatchKind.REFERENCE, 'V; // imp'), |
- _expectIdQ(main, MatchKind.WRITE, 'V = 1; // q'), |
- _expectIdQ(main, MatchKind.READ, 'V); // q'), |
- _expectIdQ(main, MatchKind.INVOCATION, 'V(); // q'), |
- _expectId(main, MatchKind.WRITE, 'V = 1; // nq'), |
- _expectId(main, MatchKind.READ, 'V); // nq'), |
- _expectId(main, MatchKind.INVOCATION, 'V(); // nq'), |
- ]; |
- await _verifyReferences(variable, expected); |
+ var searchEngine = new SearchEngineImpl2([driver1, driver2]); |
+ List<SearchMatch> matches = await searchEngine.searchReferences(element); |
+ expect(matches, hasLength(2)); |
+ expect( |
+ matches, contains(predicate((SearchMatch m) => m.element.name == 'a'))); |
+ expect( |
+ matches, contains(predicate((SearchMatch m) => m.element.name == 'b'))); |
} |
- test_searchReferences_TypeParameterElement() async { |
- await _indexTestUnit(''' |
-class A<T> { |
- main(T a, T b) {} |
-} |
-'''); |
- TypeParameterElement element = findElement('T'); |
- Element aElement = findElement('a'); |
- Element bElement = findElement('b'); |
- var expected = [ |
- _expectId(aElement, MatchKind.REFERENCE, 'T a'), |
- _expectId(bElement, MatchKind.REFERENCE, 'T b') |
- ]; |
- await _verifyReferences(element, expected); |
- } |
+ test_searchTopLevelDeclarations() async { |
+ var a = _p('/test/a.dart'); |
+ var b = _p('/test/b.dart'); |
- test_searchSubtypes() async { |
- await _indexTestUnit(''' |
-class T {} |
-class A extends T {} // A |
-class B = Object with T; // B |
-class C implements T {} // C |
+ provider.newFile( |
+ a, |
+ ''' |
+class A {} |
+int a; |
'''); |
- ClassElement element = findElement('T'); |
- ClassElement elementA = findElement('A'); |
- ClassElement elementB = findElement('B'); |
- ClassElement elementC = findElement('C'); |
- var expected = [ |
- _expectId(elementA, MatchKind.REFERENCE, 'T {} // A'), |
- _expectId(elementB, MatchKind.REFERENCE, 'T; // B'), |
- _expectId(elementC, MatchKind.REFERENCE, 'T {} // C') |
- ]; |
- List<SearchMatch> matches = await searchEngine.searchSubtypes(element); |
- _assertMatches(matches, expected); |
- } |
- |
- test_searchTopLevelDeclarations() async { |
- await _indexTestUnit(''' |
-class A {} // A |
-class B = Object with A; |
-typedef C(); |
-D() {} |
-var E = null; |
-class NoMatchABCDE {} |
+ provider.newFile( |
+ b, |
+ ''' |
+class B {} |
+get b => 42; |
'''); |
- Element topA = findElement('A'); |
- Element topB = findElement('B'); |
- Element topC = findElement('C'); |
- Element topD = findElement('D'); |
- Element topE = findElement('E'); |
- var expected = [ |
- _expectId(topA, MatchKind.DECLARATION, 'A {} // A'), |
- _expectId(topB, MatchKind.DECLARATION, 'B ='), |
- _expectId(topC, MatchKind.DECLARATION, 'C()'), |
- _expectId(topD, MatchKind.DECLARATION, 'D() {}'), |
- _expectId(topE, MatchKind.DECLARATION, 'E = null') |
- ]; |
- List<SearchMatch> matches = |
- await searchEngine.searchTopLevelDeclarations(r'^[A-E]$'); |
- _assertMatches(matches, expected); |
- } |
- ExpectedMatch _expectId(Element element, MatchKind kind, String search, |
- {int length, bool isResolved: true, bool isQualified: false}) { |
- int offset = findOffset(search); |
- if (length == null) { |
- length = getLeadingIdentifierLength(search); |
- } |
- return new ExpectedMatch(element, kind, offset, length, |
- isResolved: isResolved, isQualified: isQualified); |
- } |
- |
- /** |
- * Create [ExpectedMatch] for a qualified and resolved match. |
- */ |
- ExpectedMatch _expectIdQ(Element element, MatchKind kind, String search, |
- {int length, bool isResolved: true}) { |
- return _expectId(element, kind, search, isQualified: true, length: length); |
- } |
+ var driver1 = _newDriver(); |
+ var driver2 = _newDriver(); |
- /** |
- * Create [ExpectedMatch] for a qualified and unresolved match. |
- */ |
- ExpectedMatch _expectIdQU(Element element, MatchKind kind, String search, |
- {int length}) { |
- return _expectId(element, kind, search, |
- isQualified: true, isResolved: false, length: length); |
- } |
+ driver1.addFile(a); |
+ driver2.addFile(b); |
- /** |
- * Create [ExpectedMatch] for a unqualified and unresolved match. |
- */ |
- ExpectedMatch _expectIdU(Element element, MatchKind kind, String search, |
- {int length}) { |
- return _expectId(element, kind, search, |
- isQualified: false, isResolved: false, length: length); |
- } |
- |
- Future<Null> _indexTestUnit(String code) async { |
- await resolveTestUnit(code); |
- index.indexUnit(testUnit); |
- } |
+ while (scheduler.isAnalyzing) { |
+ await new Future.delayed(new Duration(milliseconds: 1)); |
+ } |
- Future _verifyReferences( |
- Element element, List<ExpectedMatch> expectedMatches) async { |
- List<SearchMatch> matches = await searchEngine.searchReferences(element); |
- _assertMatches(matches, expectedMatches); |
- expect(matches, hasLength(expectedMatches.length)); |
- } |
+ var searchEngine = new SearchEngineImpl2([driver1, driver2]); |
+ List<SearchMatch> matches = |
+ await searchEngine.searchTopLevelDeclarations('.*'); |
+ expect( |
+ matches.where((match) => !match.libraryElement.isInSdk), hasLength(4)); |
+ |
+ void assertHasElement(String name) { |
+ expect( |
+ matches, |
+ contains(predicate((SearchMatch m) => |
+ m.kind == MatchKind.DECLARATION && m.element.name == name))); |
+ } |
- static void _assertMatches( |
- List<SearchMatch> matches, List<ExpectedMatch> expectedMatches) { |
- expect(matches, unorderedEquals(expectedMatches)); |
- } |
+ assertHasElement('A'); |
+ assertHasElement('a'); |
+ assertHasElement('B'); |
+ assertHasElement('b'); |
+ } |
+ |
+ AnalysisDriver _newDriver() => new AnalysisDriver( |
+ scheduler, |
+ logger, |
+ provider, |
+ byteStore, |
+ contentOverlay, |
+ null, |
+ new SourceFactory( |
+ [new DartUriResolver(sdk), new ResourceUriResolver(provider)], |
+ null, |
+ provider), |
+ new AnalysisOptionsImpl()..strongMode = true); |
+ |
+ String _p(String path) => provider.convertPath(path); |
} |