| OLD | NEW | 
 | (Empty) | 
|    1 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file |  | 
|    2 // for details. All rights reserved. Use of this source code is governed by a |  | 
|    3 // BSD-style license that can be found in the LICENSE file. |  | 
|    4  |  | 
|    5 library test.services.src.search.search_engine2; |  | 
|    6  |  | 
|    7 import 'dart:async'; |  | 
|    8  |  | 
|    9 import 'package:analysis_server/src/services/index2/index2.dart'; |  | 
|   10 import 'package:analysis_server/src/services/search/search_engine.dart'; |  | 
|   11 import 'package:analysis_server/src/services/search/search_engine_internal2.dart
     '; |  | 
|   12 import 'package:analyzer/dart/element/element.dart'; |  | 
|   13 import 'package:analyzer/src/dart/element/element.dart'; |  | 
|   14 import 'package:analyzer/src/dart/element/member.dart'; |  | 
|   15 import 'package:analyzer/src/generated/source.dart'; |  | 
|   16 import 'package:test_reflective_loader/test_reflective_loader.dart'; |  | 
|   17 import 'package:unittest/unittest.dart'; |  | 
|   18  |  | 
|   19 import '../../abstract_single_unit.dart'; |  | 
|   20 import '../../utils.dart'; |  | 
|   21  |  | 
|   22 main() { |  | 
|   23   initializeTestEnvironment(); |  | 
|   24   defineReflectiveTests(SearchEngineImpl2Test); |  | 
|   25 } |  | 
|   26  |  | 
|   27 class ExpectedMatch { |  | 
|   28   final Element element; |  | 
|   29   final MatchKind kind; |  | 
|   30   SourceRange range; |  | 
|   31   final bool isResolved; |  | 
|   32   final bool isQualified; |  | 
|   33  |  | 
|   34   ExpectedMatch(this.element, this.kind, int offset, int length, |  | 
|   35       {this.isResolved: true, this.isQualified: false}) { |  | 
|   36     this.range = new SourceRange(offset, length); |  | 
|   37   } |  | 
|   38  |  | 
|   39   bool operator ==(SearchMatch match) { |  | 
|   40     return match.element == this.element && |  | 
|   41         match.kind == this.kind && |  | 
|   42         match.isResolved == this.isResolved && |  | 
|   43         match.isQualified == this.isQualified && |  | 
|   44         match.sourceRange == this.range; |  | 
|   45   } |  | 
|   46  |  | 
|   47   @override |  | 
|   48   String toString() { |  | 
|   49     StringBuffer buffer = new StringBuffer(); |  | 
|   50     buffer.write("ExpectedMatch(kind="); |  | 
|   51     buffer.write(kind); |  | 
|   52     buffer.write(", element="); |  | 
|   53     buffer.write(element != null ? element.displayName : 'null'); |  | 
|   54     buffer.write(", range="); |  | 
|   55     buffer.write(range); |  | 
|   56     buffer.write(", isResolved="); |  | 
|   57     buffer.write(isResolved); |  | 
|   58     buffer.write(", isQualified="); |  | 
|   59     buffer.write(isQualified); |  | 
|   60     buffer.write(")"); |  | 
|   61     return buffer.toString(); |  | 
|   62   } |  | 
|   63 } |  | 
|   64  |  | 
|   65 @reflectiveTest |  | 
|   66 class SearchEngineImpl2Test extends AbstractSingleUnitTest { |  | 
|   67   Index2 index; |  | 
|   68   SearchEngineImpl2 searchEngine; |  | 
|   69  |  | 
|   70   void setUp() { |  | 
|   71     super.setUp(); |  | 
|   72     index = createMemoryIndex2(); |  | 
|   73     searchEngine = new SearchEngineImpl2(index); |  | 
|   74   } |  | 
|   75  |  | 
|   76   test_searchAllSubtypes() async { |  | 
|   77     _indexTestUnit(''' |  | 
|   78 class T {} |  | 
|   79 class A extends T {} |  | 
|   80 class B extends A {} |  | 
|   81 class C implements B {} |  | 
|   82 '''); |  | 
|   83     ClassElement element = findElement('T'); |  | 
|   84     ClassElement elementA = findElement('A'); |  | 
|   85     ClassElement elementB = findElement('B'); |  | 
|   86     ClassElement elementC = findElement('C'); |  | 
|   87     var expected = [ |  | 
|   88       _expectId(elementA, MatchKind.DECLARATION, 'A extends T'), |  | 
|   89       _expectId(elementB, MatchKind.DECLARATION, 'B extends A'), |  | 
|   90       _expectId(elementC, MatchKind.DECLARATION, 'C implements B') |  | 
|   91     ]; |  | 
|   92     List<SearchMatch> matches = await searchEngine.searchAllSubtypes(element); |  | 
|   93     _assertMatches(matches, expected); |  | 
|   94   } |  | 
|   95  |  | 
|   96   test_searchMemberDeclarations() async { |  | 
|   97     _indexTestUnit(''' |  | 
|   98 class A { |  | 
|   99   test() {} |  | 
|  100 } |  | 
|  101 class B { |  | 
|  102   int test = 1; |  | 
|  103   main() { |  | 
|  104     int test = 2; |  | 
|  105   } |  | 
|  106 } |  | 
|  107 '''); |  | 
|  108     ClassElement elementA = findElement('A'); |  | 
|  109     ClassElement elementB = findElement('B'); |  | 
|  110     var expected = [ |  | 
|  111       _expectId(elementA.methods[0], MatchKind.DECLARATION, 'test() {}'), |  | 
|  112       _expectId(elementB.fields[0], MatchKind.DECLARATION, 'test = 1;') |  | 
|  113     ]; |  | 
|  114     List<SearchMatch> matches = |  | 
|  115         await searchEngine.searchMemberDeclarations('test'); |  | 
|  116     _assertMatches(matches, expected); |  | 
|  117   } |  | 
|  118  |  | 
|  119   test_searchMemberReferences_qualified_resolved() async { |  | 
|  120     _indexTestUnit(''' |  | 
|  121 class C { |  | 
|  122   var test; |  | 
|  123 } |  | 
|  124 main(C c) { |  | 
|  125   print(c.test); |  | 
|  126   c.test = 1; |  | 
|  127   c.test += 2; |  | 
|  128   c.test(); |  | 
|  129 } |  | 
|  130 '''); |  | 
|  131     List<SearchMatch> matches = |  | 
|  132         await searchEngine.searchMemberReferences('test'); |  | 
|  133     expect(matches, isEmpty); |  | 
|  134   } |  | 
|  135  |  | 
|  136   test_searchMemberReferences_qualified_unresolved() async { |  | 
|  137     _indexTestUnit(''' |  | 
|  138 main(p) { |  | 
|  139   print(p.test); |  | 
|  140   p.test = 1; |  | 
|  141   p.test += 2; |  | 
|  142   p.test(); |  | 
|  143 } |  | 
|  144 '''); |  | 
|  145     Element main = findElement('main'); |  | 
|  146     var expected = [ |  | 
|  147       _expectIdQU(main, MatchKind.READ, 'test);'), |  | 
|  148       _expectIdQU(main, MatchKind.WRITE, 'test = 1;'), |  | 
|  149       _expectIdQU(main, MatchKind.READ_WRITE, 'test += 2;'), |  | 
|  150       _expectIdQU(main, MatchKind.INVOCATION, 'test();'), |  | 
|  151     ]; |  | 
|  152     List<SearchMatch> matches = |  | 
|  153         await searchEngine.searchMemberReferences('test'); |  | 
|  154     _assertMatches(matches, expected); |  | 
|  155   } |  | 
|  156  |  | 
|  157   test_searchMemberReferences_unqualified_resolved() async { |  | 
|  158     _indexTestUnit(''' |  | 
|  159 class C { |  | 
|  160   var test; |  | 
|  161   main() { |  | 
|  162     print(test); |  | 
|  163     test = 1; |  | 
|  164     test += 2; |  | 
|  165     test(); |  | 
|  166   } |  | 
|  167 } |  | 
|  168 '''); |  | 
|  169     List<SearchMatch> matches = |  | 
|  170         await searchEngine.searchMemberReferences('test'); |  | 
|  171     expect(matches, isEmpty); |  | 
|  172   } |  | 
|  173  |  | 
|  174   test_searchMemberReferences_unqualified_unresolved() async { |  | 
|  175     verifyNoTestUnitErrors = false; |  | 
|  176     _indexTestUnit(''' |  | 
|  177 class C { |  | 
|  178   main() { |  | 
|  179     print(test); |  | 
|  180     test = 1; |  | 
|  181     test += 2; |  | 
|  182     test(); |  | 
|  183   } |  | 
|  184 } |  | 
|  185 '''); |  | 
|  186     Element main = findElement('main'); |  | 
|  187     var expected = [ |  | 
|  188       _expectIdU(main, MatchKind.READ, 'test);'), |  | 
|  189       _expectIdU(main, MatchKind.WRITE, 'test = 1;'), |  | 
|  190       _expectIdU(main, MatchKind.READ_WRITE, 'test += 2;'), |  | 
|  191       _expectIdU(main, MatchKind.INVOCATION, 'test();'), |  | 
|  192     ]; |  | 
|  193     List<SearchMatch> matches = |  | 
|  194         await searchEngine.searchMemberReferences('test'); |  | 
|  195     _assertMatches(matches, expected); |  | 
|  196   } |  | 
|  197  |  | 
|  198   test_searchReferences_ClassElement() async { |  | 
|  199     _indexTestUnit(''' |  | 
|  200 class A {} |  | 
|  201 main(A p) { |  | 
|  202   A v; |  | 
|  203 } |  | 
|  204 '''); |  | 
|  205     ClassElement element = findElement('A'); |  | 
|  206     Element pElement = findElement('p'); |  | 
|  207     Element vElement = findElement('v'); |  | 
|  208     var expected = [ |  | 
|  209       _expectId(pElement, MatchKind.REFERENCE, 'A p'), |  | 
|  210       _expectId(vElement, MatchKind.REFERENCE, 'A v') |  | 
|  211     ]; |  | 
|  212     await _verifyReferences(element, expected); |  | 
|  213   } |  | 
|  214  |  | 
|  215   test_searchReferences_CompilationUnitElement() async { |  | 
|  216     addSource( |  | 
|  217         '/my_part.dart', |  | 
|  218         ''' |  | 
|  219 part of lib; |  | 
|  220 '''); |  | 
|  221     _indexTestUnit(''' |  | 
|  222 library lib; |  | 
|  223 part 'my_part.dart'; |  | 
|  224 '''); |  | 
|  225     CompilationUnitElement element = testLibraryElement.parts[0]; |  | 
|  226     var expected = [ |  | 
|  227       _expectIdQ(testUnitElement, MatchKind.REFERENCE, "'my_part.dart'", |  | 
|  228           length: "'my_part.dart'".length) |  | 
|  229     ]; |  | 
|  230     await _verifyReferences(element, expected); |  | 
|  231   } |  | 
|  232  |  | 
|  233   test_searchReferences_ConstructorElement() async { |  | 
|  234     _indexTestUnit(''' |  | 
|  235 class A { |  | 
|  236   A.named() {} |  | 
|  237 } |  | 
|  238 main() { |  | 
|  239   new A.named(); |  | 
|  240 } |  | 
|  241 '''); |  | 
|  242     ConstructorElement element = findElement('named'); |  | 
|  243     Element mainElement = findElement('main'); |  | 
|  244     var expected = [ |  | 
|  245       _expectIdQ(mainElement, MatchKind.REFERENCE, '.named();', length: 6) |  | 
|  246     ]; |  | 
|  247     await _verifyReferences(element, expected); |  | 
|  248   } |  | 
|  249  |  | 
|  250   test_searchReferences_ConstructorElement_synthetic() async { |  | 
|  251     _indexTestUnit(''' |  | 
|  252 class A { |  | 
|  253 } |  | 
|  254 main() { |  | 
|  255   new A(); |  | 
|  256 } |  | 
|  257 '''); |  | 
|  258     ClassElement classElement = findElement('A'); |  | 
|  259     ConstructorElement element = classElement.unnamedConstructor; |  | 
|  260     Element mainElement = findElement('main'); |  | 
|  261     var expected = [ |  | 
|  262       _expectIdQ(mainElement, MatchKind.REFERENCE, '();', length: 0) |  | 
|  263     ]; |  | 
|  264     await _verifyReferences(element, expected); |  | 
|  265   } |  | 
|  266  |  | 
|  267   test_searchReferences_Element_unknown() async { |  | 
|  268     await _verifyReferences(DynamicElementImpl.instance, []); |  | 
|  269   } |  | 
|  270  |  | 
|  271   test_searchReferences_FieldElement() async { |  | 
|  272     _indexTestUnit(''' |  | 
|  273 class A { |  | 
|  274   var field; |  | 
|  275   A({this.field}); |  | 
|  276   main() { |  | 
|  277     new A(field: 1); |  | 
|  278     // getter |  | 
|  279     print(field); // ref-nq |  | 
|  280     print(this.field); // ref-q |  | 
|  281     field(); // inv-nq |  | 
|  282     this.field(); // inv-q |  | 
|  283     // setter |  | 
|  284     field = 2; // ref-nq; |  | 
|  285     this.field = 3; // ref-q; |  | 
|  286   } |  | 
|  287 } |  | 
|  288 '''); |  | 
|  289     FieldElement element = findElement('field'); |  | 
|  290     Element main = findElement('main'); |  | 
|  291     Element fieldParameter = findElement('field', ElementKind.PARAMETER); |  | 
|  292     var expected = [ |  | 
|  293       _expectIdQ(fieldParameter, MatchKind.WRITE, 'field}'), |  | 
|  294       _expectIdQ(main, MatchKind.REFERENCE, 'field: 1'), |  | 
|  295       _expectId(main, MatchKind.READ, 'field); // ref-nq'), |  | 
|  296       _expectIdQ(main, MatchKind.READ, 'field); // ref-q'), |  | 
|  297       _expectId(main, MatchKind.INVOCATION, 'field(); // inv-nq'), |  | 
|  298       _expectIdQ(main, MatchKind.INVOCATION, 'field(); // inv-q'), |  | 
|  299       _expectId(main, MatchKind.WRITE, 'field = 2; // ref-nq'), |  | 
|  300       _expectIdQ(main, MatchKind.WRITE, 'field = 3; // ref-q'), |  | 
|  301     ]; |  | 
|  302     await _verifyReferences(element, expected); |  | 
|  303   } |  | 
|  304  |  | 
|  305   test_searchReferences_FieldElement_ofEnum() async { |  | 
|  306     _indexTestUnit(''' |  | 
|  307 enum MyEnum { |  | 
|  308   A, B, C |  | 
|  309 } |  | 
|  310 main() { |  | 
|  311   print(MyEnum.A.index); |  | 
|  312   print(MyEnum.values); |  | 
|  313   print(MyEnum.A); |  | 
|  314   print(MyEnum.B); |  | 
|  315 } |  | 
|  316 '''); |  | 
|  317     ClassElement enumElement = findElement('MyEnum'); |  | 
|  318     Element mainElement = findElement('main'); |  | 
|  319     await _verifyReferences(enumElement.getField('index'), |  | 
|  320         [_expectIdQ(mainElement, MatchKind.READ, 'index);')]); |  | 
|  321     await _verifyReferences(enumElement.getField('values'), |  | 
|  322         [_expectIdQ(mainElement, MatchKind.READ, 'values);')]); |  | 
|  323     await _verifyReferences(enumElement.getField('A'), [ |  | 
|  324       _expectIdQ(mainElement, MatchKind.READ, 'A.index);'), |  | 
|  325       _expectIdQ(mainElement, MatchKind.READ, 'A);') |  | 
|  326     ]); |  | 
|  327     await _verifyReferences(enumElement.getField('B'), |  | 
|  328         [_expectIdQ(mainElement, MatchKind.READ, 'B);')]); |  | 
|  329   } |  | 
|  330  |  | 
|  331   test_searchReferences_FieldElement_synthetic() async { |  | 
|  332     _indexTestUnit(''' |  | 
|  333 class A { |  | 
|  334   get field => null; |  | 
|  335   set field(x) {} |  | 
|  336   main() { |  | 
|  337     // getter |  | 
|  338     print(field); // ref-nq |  | 
|  339     print(this.field); // ref-q |  | 
|  340     field(); // inv-nq |  | 
|  341     this.field(); // inv-q |  | 
|  342     // setter |  | 
|  343     field = 2; // ref-nq; |  | 
|  344     this.field = 3; // ref-q; |  | 
|  345   } |  | 
|  346 } |  | 
|  347 '''); |  | 
|  348     FieldElement element = findElement('field', ElementKind.FIELD); |  | 
|  349     Element main = findElement('main'); |  | 
|  350     var expected = [ |  | 
|  351       _expectId(main, MatchKind.READ, 'field); // ref-nq'), |  | 
|  352       _expectIdQ(main, MatchKind.READ, 'field); // ref-q'), |  | 
|  353       _expectId(main, MatchKind.INVOCATION, 'field(); // inv-nq'), |  | 
|  354       _expectIdQ(main, MatchKind.INVOCATION, 'field(); // inv-q'), |  | 
|  355       _expectId(main, MatchKind.WRITE, 'field = 2; // ref-nq'), |  | 
|  356       _expectIdQ(main, MatchKind.WRITE, 'field = 3; // ref-q'), |  | 
|  357     ]; |  | 
|  358     await _verifyReferences(element, expected); |  | 
|  359   } |  | 
|  360  |  | 
|  361   test_searchReferences_FunctionElement() async { |  | 
|  362     _indexTestUnit(''' |  | 
|  363 test() {} |  | 
|  364 main() { |  | 
|  365   test(); |  | 
|  366   print(test); |  | 
|  367 } |  | 
|  368 '''); |  | 
|  369     FunctionElement element = findElement('test'); |  | 
|  370     Element mainElement = findElement('main'); |  | 
|  371     var expected = [ |  | 
|  372       _expectId(mainElement, MatchKind.INVOCATION, 'test();'), |  | 
|  373       _expectId(mainElement, MatchKind.REFERENCE, 'test);') |  | 
|  374     ]; |  | 
|  375     await _verifyReferences(element, expected); |  | 
|  376   } |  | 
|  377  |  | 
|  378   test_searchReferences_FunctionElement_local() async { |  | 
|  379     _indexTestUnit(''' |  | 
|  380 main() { |  | 
|  381   test() {} |  | 
|  382   test(); |  | 
|  383   print(test); |  | 
|  384 } |  | 
|  385 '''); |  | 
|  386     FunctionElement element = findElement('test'); |  | 
|  387     Element mainElement = findElement('main'); |  | 
|  388     var expected = [ |  | 
|  389       _expectId(mainElement, MatchKind.INVOCATION, 'test();'), |  | 
|  390       _expectId(mainElement, MatchKind.REFERENCE, 'test);') |  | 
|  391     ]; |  | 
|  392     await _verifyReferences(element, expected); |  | 
|  393   } |  | 
|  394  |  | 
|  395   test_searchReferences_FunctionTypeAliasElement() async { |  | 
|  396     _indexTestUnit(''' |  | 
|  397 typedef Test(); |  | 
|  398 main() { |  | 
|  399   Test a; |  | 
|  400   Test b; |  | 
|  401 } |  | 
|  402 '''); |  | 
|  403     FunctionTypeAliasElement element = findElement('Test'); |  | 
|  404     Element aElement = findElement('a'); |  | 
|  405     Element bElement = findElement('b'); |  | 
|  406     var expected = [ |  | 
|  407       _expectId(aElement, MatchKind.REFERENCE, 'Test a;'), |  | 
|  408       _expectId(bElement, MatchKind.REFERENCE, 'Test b;') |  | 
|  409     ]; |  | 
|  410     await _verifyReferences(element, expected); |  | 
|  411   } |  | 
|  412  |  | 
|  413   test_searchReferences_ImportElement_noPrefix() async { |  | 
|  414     _indexTestUnit(''' |  | 
|  415 import 'dart:math' show max, PI, Random hide min; |  | 
|  416 export 'dart:math' show max, PI, Random hide min; |  | 
|  417 main() { |  | 
|  418   print(PI); |  | 
|  419   print(new Random()); |  | 
|  420   print(max(1, 2)); |  | 
|  421 } |  | 
|  422 Random bar() => null; |  | 
|  423 '''); |  | 
|  424     ImportElement element = testLibraryElement.imports[0]; |  | 
|  425     Element mainElement = findElement('main'); |  | 
|  426     Element barElement = findElement('bar'); |  | 
|  427     var kind = MatchKind.REFERENCE; |  | 
|  428     var expected = [ |  | 
|  429       _expectId(mainElement, kind, 'PI);', length: 0), |  | 
|  430       _expectId(mainElement, kind, 'Random()', length: 0), |  | 
|  431       _expectId(mainElement, kind, 'max(', length: 0), |  | 
|  432       _expectId(barElement, kind, 'Random bar()', length: 0), |  | 
|  433     ]; |  | 
|  434     await _verifyReferences(element, expected); |  | 
|  435   } |  | 
|  436  |  | 
|  437   test_searchReferences_ImportElement_withPrefix() async { |  | 
|  438     _indexTestUnit(''' |  | 
|  439 import 'dart:math' as math show max, PI, Random hide min; |  | 
|  440 export 'dart:math' show max, PI, Random hide min; |  | 
|  441 main() { |  | 
|  442   print(math.PI); |  | 
|  443   print(new math.Random()); |  | 
|  444   print(math.max(1, 2)); |  | 
|  445 } |  | 
|  446 math.Random bar() => null; |  | 
|  447 '''); |  | 
|  448     ImportElement element = testLibraryElement.imports[0]; |  | 
|  449     Element mainElement = findElement('main'); |  | 
|  450     Element barElement = findElement('bar'); |  | 
|  451     var kind = MatchKind.REFERENCE; |  | 
|  452     var length = 'math.'.length; |  | 
|  453     var expected = [ |  | 
|  454       _expectId(mainElement, kind, 'math.PI);', length: length), |  | 
|  455       _expectId(mainElement, kind, 'math.Random()', length: length), |  | 
|  456       _expectId(mainElement, kind, 'math.max(', length: length), |  | 
|  457       _expectId(barElement, kind, 'math.Random bar()', length: length), |  | 
|  458     ]; |  | 
|  459     await _verifyReferences(element, expected); |  | 
|  460   } |  | 
|  461  |  | 
|  462   test_searchReferences_LabelElement() async { |  | 
|  463     _indexTestUnit(''' |  | 
|  464 main() { |  | 
|  465 label: |  | 
|  466   while (true) { |  | 
|  467     if (true) { |  | 
|  468       break label; // 1 |  | 
|  469     } |  | 
|  470     break label; // 2 |  | 
|  471   } |  | 
|  472 } |  | 
|  473 '''); |  | 
|  474     LabelElement element = findElement('label'); |  | 
|  475     Element mainElement = findElement('main'); |  | 
|  476     var expected = [ |  | 
|  477       _expectId(mainElement, MatchKind.REFERENCE, 'label; // 1'), |  | 
|  478       _expectId(mainElement, MatchKind.REFERENCE, 'label; // 2') |  | 
|  479     ]; |  | 
|  480     await _verifyReferences(element, expected); |  | 
|  481   } |  | 
|  482  |  | 
|  483   test_searchReferences_LibraryElement() async { |  | 
|  484     var codeA = 'part of lib; // A'; |  | 
|  485     var codeB = 'part of lib; // B'; |  | 
|  486     addSource('/unitA.dart', codeA); |  | 
|  487     addSource('/unitB.dart', codeB); |  | 
|  488     _indexTestUnit(''' |  | 
|  489 library lib; |  | 
|  490 part 'unitA.dart'; |  | 
|  491 part 'unitB.dart'; |  | 
|  492 '''); |  | 
|  493     LibraryElement element = testLibraryElement; |  | 
|  494     CompilationUnitElement unitElementA = element.parts[0]; |  | 
|  495     CompilationUnitElement unitElementB = element.parts[1]; |  | 
|  496     index.indexUnit(unitElementA.computeNode()); |  | 
|  497     index.indexUnit(unitElementB.computeNode()); |  | 
|  498     var expected = [ |  | 
|  499       new ExpectedMatch(unitElementA, MatchKind.REFERENCE, |  | 
|  500           codeA.indexOf('lib; // A'), 'lib'.length), |  | 
|  501       new ExpectedMatch(unitElementB, MatchKind.REFERENCE, |  | 
|  502           codeB.indexOf('lib; // B'), 'lib'.length), |  | 
|  503     ]; |  | 
|  504     await _verifyReferences(element, expected); |  | 
|  505   } |  | 
|  506  |  | 
|  507   test_searchReferences_LocalVariableElement() async { |  | 
|  508     _indexTestUnit(''' |  | 
|  509 main() { |  | 
|  510   var v; |  | 
|  511   v = 1; |  | 
|  512   v += 2; |  | 
|  513   print(v); |  | 
|  514   v(); |  | 
|  515 } |  | 
|  516 '''); |  | 
|  517     LocalVariableElement element = findElement('v'); |  | 
|  518     Element mainElement = findElement('main'); |  | 
|  519     var expected = [ |  | 
|  520       _expectId(mainElement, MatchKind.WRITE, 'v = 1;'), |  | 
|  521       _expectId(mainElement, MatchKind.READ_WRITE, 'v += 2;'), |  | 
|  522       _expectId(mainElement, MatchKind.READ, 'v);'), |  | 
|  523       _expectId(mainElement, MatchKind.INVOCATION, 'v();') |  | 
|  524     ]; |  | 
|  525     await _verifyReferences(element, expected); |  | 
|  526   } |  | 
|  527  |  | 
|  528   test_searchReferences_MethodElement() async { |  | 
|  529     _indexTestUnit(''' |  | 
|  530 class A { |  | 
|  531   m() {} |  | 
|  532   main() { |  | 
|  533     m(); // 1 |  | 
|  534     this.m(); // 2 |  | 
|  535     print(m); // 3 |  | 
|  536     print(this.m); // 4 |  | 
|  537   } |  | 
|  538 } |  | 
|  539 '''); |  | 
|  540     MethodElement method = findElement('m'); |  | 
|  541     Element mainElement = findElement('main'); |  | 
|  542     var expected = [ |  | 
|  543       _expectId(mainElement, MatchKind.INVOCATION, 'm(); // 1'), |  | 
|  544       _expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // 2'), |  | 
|  545       _expectId(mainElement, MatchKind.REFERENCE, 'm); // 3'), |  | 
|  546       _expectIdQ(mainElement, MatchKind.REFERENCE, 'm); // 4') |  | 
|  547     ]; |  | 
|  548     await _verifyReferences(method, expected); |  | 
|  549   } |  | 
|  550  |  | 
|  551   test_searchReferences_MethodMember() async { |  | 
|  552     _indexTestUnit(''' |  | 
|  553 class A<T> { |  | 
|  554   T m() => null; |  | 
|  555 } |  | 
|  556 main(A<int> a) { |  | 
|  557   a.m(); // ref |  | 
|  558 } |  | 
|  559 '''); |  | 
|  560     MethodMember method = findNodeElementAtString('m(); // ref'); |  | 
|  561     Element mainElement = findElement('main'); |  | 
|  562     var expected = [ |  | 
|  563       _expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // ref') |  | 
|  564     ]; |  | 
|  565     await _verifyReferences(method, expected); |  | 
|  566   } |  | 
|  567  |  | 
|  568   test_searchReferences_ParameterElement_ofLocalFunction() async { |  | 
|  569     _indexTestUnit(''' |  | 
|  570 main() { |  | 
|  571   foo({p}) { |  | 
|  572     p = 1; |  | 
|  573     p += 2; |  | 
|  574     print(p); |  | 
|  575     p(); |  | 
|  576   } |  | 
|  577   foo(p: 42); |  | 
|  578 } |  | 
|  579 '''); |  | 
|  580     ParameterElement element = findElement('p'); |  | 
|  581     Element fooElement = findElement('foo'); |  | 
|  582     Element mainElement = findElement('main'); |  | 
|  583     var expected = [ |  | 
|  584       _expectId(fooElement, MatchKind.WRITE, 'p = 1;'), |  | 
|  585       _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'), |  | 
|  586       _expectId(fooElement, MatchKind.READ, 'p);'), |  | 
|  587       _expectId(fooElement, MatchKind.INVOCATION, 'p();'), |  | 
|  588       _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42') |  | 
|  589     ]; |  | 
|  590     await _verifyReferences(element, expected); |  | 
|  591   } |  | 
|  592  |  | 
|  593   test_searchReferences_ParameterElement_ofMethod() async { |  | 
|  594     _indexTestUnit(''' |  | 
|  595 class C { |  | 
|  596   foo({p}) { |  | 
|  597     p = 1; |  | 
|  598     p += 2; |  | 
|  599     print(p); |  | 
|  600     p(); |  | 
|  601   } |  | 
|  602 } |  | 
|  603 main(C c) { |  | 
|  604   c.foo(p: 42); |  | 
|  605 } |  | 
|  606 '''); |  | 
|  607     ParameterElement element = findElement('p'); |  | 
|  608     Element fooElement = findElement('foo'); |  | 
|  609     Element mainElement = findElement('main'); |  | 
|  610     var expected = [ |  | 
|  611       _expectId(fooElement, MatchKind.WRITE, 'p = 1;'), |  | 
|  612       _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'), |  | 
|  613       _expectId(fooElement, MatchKind.READ, 'p);'), |  | 
|  614       _expectId(fooElement, MatchKind.INVOCATION, 'p();'), |  | 
|  615       _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42') |  | 
|  616     ]; |  | 
|  617     await _verifyReferences(element, expected); |  | 
|  618   } |  | 
|  619  |  | 
|  620   test_searchReferences_ParameterElement_ofTopLevelFunction() async { |  | 
|  621     _indexTestUnit(''' |  | 
|  622 foo({p}) { |  | 
|  623   p = 1; |  | 
|  624   p += 2; |  | 
|  625   print(p); |  | 
|  626   p(); |  | 
|  627 } |  | 
|  628 main() { |  | 
|  629   foo(p: 42); |  | 
|  630 } |  | 
|  631 '''); |  | 
|  632     ParameterElement element = findElement('p'); |  | 
|  633     Element fooElement = findElement('foo'); |  | 
|  634     Element mainElement = findElement('main'); |  | 
|  635     var expected = [ |  | 
|  636       _expectId(fooElement, MatchKind.WRITE, 'p = 1;'), |  | 
|  637       _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'), |  | 
|  638       _expectId(fooElement, MatchKind.READ, 'p);'), |  | 
|  639       _expectId(fooElement, MatchKind.INVOCATION, 'p();'), |  | 
|  640       _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42') |  | 
|  641     ]; |  | 
|  642     await _verifyReferences(element, expected); |  | 
|  643   } |  | 
|  644  |  | 
|  645   test_searchReferences_PrefixElement() async { |  | 
|  646     _indexTestUnit(''' |  | 
|  647 import 'dart:async' as ppp; |  | 
|  648 main() { |  | 
|  649   ppp.Future a; |  | 
|  650   ppp.Stream b; |  | 
|  651 } |  | 
|  652 '''); |  | 
|  653     PrefixElement element = findNodeElementAtString('ppp;'); |  | 
|  654     Element elementA = findElement('a'); |  | 
|  655     Element elementB = findElement('b'); |  | 
|  656     var expected = [ |  | 
|  657       _expectId(elementA, MatchKind.REFERENCE, 'ppp.Future'), |  | 
|  658       _expectId(elementB, MatchKind.REFERENCE, 'ppp.Stream') |  | 
|  659     ]; |  | 
|  660     await _verifyReferences(element, expected); |  | 
|  661   } |  | 
|  662  |  | 
|  663   test_searchReferences_PropertyAccessorElement_getter() async { |  | 
|  664     _indexTestUnit(''' |  | 
|  665 class A { |  | 
|  666   get ggg => null; |  | 
|  667   main() { |  | 
|  668     print(ggg); // ref-nq |  | 
|  669     print(this.ggg); // ref-q |  | 
|  670     ggg(); // inv-nq |  | 
|  671     this.ggg(); // inv-q |  | 
|  672   } |  | 
|  673 } |  | 
|  674 '''); |  | 
|  675     PropertyAccessorElement element = findElement('ggg', ElementKind.GETTER); |  | 
|  676     Element main = findElement('main'); |  | 
|  677     var expected = [ |  | 
|  678       _expectId(main, MatchKind.REFERENCE, 'ggg); // ref-nq'), |  | 
|  679       _expectIdQ(main, MatchKind.REFERENCE, 'ggg); // ref-q'), |  | 
|  680       _expectId(main, MatchKind.INVOCATION, 'ggg(); // inv-nq'), |  | 
|  681       _expectIdQ(main, MatchKind.INVOCATION, 'ggg(); // inv-q'), |  | 
|  682     ]; |  | 
|  683     await _verifyReferences(element, expected); |  | 
|  684   } |  | 
|  685  |  | 
|  686   test_searchReferences_PropertyAccessorElement_setter() async { |  | 
|  687     _indexTestUnit(''' |  | 
|  688 class A { |  | 
|  689   set s(x) {} |  | 
|  690   main() { |  | 
|  691     s = 1; |  | 
|  692     this.s = 2; |  | 
|  693   } |  | 
|  694 } |  | 
|  695 '''); |  | 
|  696     PropertyAccessorElement element = findElement('s='); |  | 
|  697     Element mainElement = findElement('main'); |  | 
|  698     var expected = [ |  | 
|  699       _expectId(mainElement, MatchKind.REFERENCE, 's = 1'), |  | 
|  700       _expectIdQ(mainElement, MatchKind.REFERENCE, 's = 2') |  | 
|  701     ]; |  | 
|  702     await _verifyReferences(element, expected); |  | 
|  703   } |  | 
|  704  |  | 
|  705   test_searchReferences_TopLevelVariableElement() async { |  | 
|  706     addSource( |  | 
|  707         '/lib.dart', |  | 
|  708         ''' |  | 
|  709 library lib; |  | 
|  710 var V; |  | 
|  711 '''); |  | 
|  712     _indexTestUnit(''' |  | 
|  713 import 'lib.dart' show V; // imp |  | 
|  714 import 'lib.dart' as pref; |  | 
|  715 main() { |  | 
|  716   pref.V = 1; // q |  | 
|  717   print(pref.V); // q |  | 
|  718   pref.V(); // q |  | 
|  719   V = 1; // nq |  | 
|  720   print(V); // nq |  | 
|  721   V(); // nq |  | 
|  722 } |  | 
|  723 '''); |  | 
|  724     ImportElement importElement = testLibraryElement.imports[0]; |  | 
|  725     CompilationUnitElement impUnit = |  | 
|  726         importElement.importedLibrary.definingCompilationUnit; |  | 
|  727     TopLevelVariableElement variable = impUnit.topLevelVariables[0]; |  | 
|  728     Element main = findElement('main'); |  | 
|  729     var expected = [ |  | 
|  730       _expectIdQ(testUnitElement, MatchKind.REFERENCE, 'V; // imp'), |  | 
|  731       _expectIdQ(main, MatchKind.WRITE, 'V = 1; // q'), |  | 
|  732       _expectIdQ(main, MatchKind.READ, 'V); // q'), |  | 
|  733       _expectIdQ(main, MatchKind.INVOCATION, 'V(); // q'), |  | 
|  734       _expectId(main, MatchKind.WRITE, 'V = 1; // nq'), |  | 
|  735       _expectId(main, MatchKind.READ, 'V); // nq'), |  | 
|  736       _expectId(main, MatchKind.INVOCATION, 'V(); // nq'), |  | 
|  737     ]; |  | 
|  738     await _verifyReferences(variable, expected); |  | 
|  739   } |  | 
|  740  |  | 
|  741   test_searchReferences_TypeParameterElement() async { |  | 
|  742     _indexTestUnit(''' |  | 
|  743 class A<T> { |  | 
|  744   main(T a, T b) {} |  | 
|  745 } |  | 
|  746 '''); |  | 
|  747     TypeParameterElement element = findElement('T'); |  | 
|  748     Element aElement = findElement('a'); |  | 
|  749     Element bElement = findElement('b'); |  | 
|  750     var expected = [ |  | 
|  751       _expectId(aElement, MatchKind.REFERENCE, 'T a'), |  | 
|  752       _expectId(bElement, MatchKind.REFERENCE, 'T b') |  | 
|  753     ]; |  | 
|  754     await _verifyReferences(element, expected); |  | 
|  755   } |  | 
|  756  |  | 
|  757   test_searchSubtypes() async { |  | 
|  758     _indexTestUnit(''' |  | 
|  759 class T {} |  | 
|  760 class A extends T {} // A |  | 
|  761 class B = Object with T; // B |  | 
|  762 class C implements T {} // C |  | 
|  763 '''); |  | 
|  764     ClassElement element = findElement('T'); |  | 
|  765     ClassElement elementA = findElement('A'); |  | 
|  766     ClassElement elementB = findElement('B'); |  | 
|  767     ClassElement elementC = findElement('C'); |  | 
|  768     var expected = [ |  | 
|  769       _expectId(elementA, MatchKind.REFERENCE, 'T {} // A'), |  | 
|  770       _expectId(elementB, MatchKind.REFERENCE, 'T; // B'), |  | 
|  771       _expectId(elementC, MatchKind.REFERENCE, 'T {} // C') |  | 
|  772     ]; |  | 
|  773     List<SearchMatch> matches = await searchEngine.searchSubtypes(element); |  | 
|  774     _assertMatches(matches, expected); |  | 
|  775   } |  | 
|  776  |  | 
|  777   test_searchTopLevelDeclarations() async { |  | 
|  778     _indexTestUnit(''' |  | 
|  779 class A {} // A |  | 
|  780 class B = Object with A; |  | 
|  781 typedef C(); |  | 
|  782 D() {} |  | 
|  783 var E = null; |  | 
|  784 class NoMatchABCDE {} |  | 
|  785 '''); |  | 
|  786     Element topA = findElement('A'); |  | 
|  787     Element topB = findElement('B'); |  | 
|  788     Element topC = findElement('C'); |  | 
|  789     Element topD = findElement('D'); |  | 
|  790     Element topE = findElement('E'); |  | 
|  791     var expected = [ |  | 
|  792       _expectId(topA, MatchKind.DECLARATION, 'A {} // A'), |  | 
|  793       _expectId(topB, MatchKind.DECLARATION, 'B ='), |  | 
|  794       _expectId(topC, MatchKind.DECLARATION, 'C()'), |  | 
|  795       _expectId(topD, MatchKind.DECLARATION, 'D() {}'), |  | 
|  796       _expectId(topE, MatchKind.DECLARATION, 'E = null') |  | 
|  797     ]; |  | 
|  798     List<SearchMatch> matches = |  | 
|  799         await searchEngine.searchTopLevelDeclarations(r'^[A-E]$'); |  | 
|  800     _assertMatches(matches, expected); |  | 
|  801   } |  | 
|  802  |  | 
|  803   ExpectedMatch _expectId(Element element, MatchKind kind, String search, |  | 
|  804       {int length, bool isResolved: true, bool isQualified: false}) { |  | 
|  805     int offset = findOffset(search); |  | 
|  806     if (length == null) { |  | 
|  807       length = getLeadingIdentifierLength(search); |  | 
|  808     } |  | 
|  809     return new ExpectedMatch(element, kind, offset, length, |  | 
|  810         isResolved: isResolved, isQualified: isQualified); |  | 
|  811   } |  | 
|  812  |  | 
|  813   /** |  | 
|  814    * Create [ExpectedMatch] for a qualified and resolved match. |  | 
|  815    */ |  | 
|  816   ExpectedMatch _expectIdQ(Element element, MatchKind kind, String search, |  | 
|  817       {int length, bool isResolved: true}) { |  | 
|  818     return _expectId(element, kind, search, isQualified: true, length: length); |  | 
|  819   } |  | 
|  820  |  | 
|  821   /** |  | 
|  822    * Create [ExpectedMatch] for a qualified and unresolved match. |  | 
|  823    */ |  | 
|  824   ExpectedMatch _expectIdQU(Element element, MatchKind kind, String search, |  | 
|  825       {int length}) { |  | 
|  826     return _expectId(element, kind, search, |  | 
|  827         isQualified: true, isResolved: false, length: length); |  | 
|  828   } |  | 
|  829  |  | 
|  830   /** |  | 
|  831    * Create [ExpectedMatch] for a unqualified and unresolved match. |  | 
|  832    */ |  | 
|  833   ExpectedMatch _expectIdU(Element element, MatchKind kind, String search, |  | 
|  834       {int length}) { |  | 
|  835     return _expectId(element, kind, search, |  | 
|  836         isQualified: false, isResolved: false, length: length); |  | 
|  837   } |  | 
|  838  |  | 
|  839   void _indexTestUnit(String code) { |  | 
|  840     resolveTestUnit(code); |  | 
|  841     index.indexUnit(testUnit); |  | 
|  842   } |  | 
|  843  |  | 
|  844   Future _verifyReferences( |  | 
|  845       Element element, List<ExpectedMatch> expectedMatches) async { |  | 
|  846     List<SearchMatch> matches = await searchEngine.searchReferences(element); |  | 
|  847     _assertMatches(matches, expectedMatches); |  | 
|  848     expect(matches, hasLength(expectedMatches.length)); |  | 
|  849   } |  | 
|  850  |  | 
|  851   static void _assertMatches( |  | 
|  852       List<SearchMatch> matches, List<ExpectedMatch> expectedMatches) { |  | 
|  853     expect(matches, unorderedEquals(expectedMatches)); |  | 
|  854   } |  | 
|  855 } |  | 
| OLD | NEW |