OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/element/element.dart'; | 8 import 'package:analyzer/dart/element/element.dart'; |
9 import 'package:analyzer/src/dart/analysis/driver.dart'; | 9 import 'package:analyzer/src/dart/analysis/driver.dart'; |
10 import 'package:analyzer/src/dart/analysis/search.dart'; | 10 import 'package:analyzer/src/dart/analysis/search.dart'; |
11 import 'package:analyzer/src/dart/ast/utilities.dart'; | 11 import 'package:analyzer/src/dart/ast/utilities.dart'; |
12 import 'package:analyzer/src/dart/element/member.dart'; | |
12 import 'package:test/test.dart'; | 13 import 'package:test/test.dart'; |
13 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 14 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
14 | 15 |
15 import 'base.dart'; | 16 import 'base.dart'; |
16 | 17 |
17 main() { | 18 main() { |
18 defineReflectiveSuite(() { | 19 defineReflectiveSuite(() { |
19 defineReflectiveTests(SearchTest); | 20 defineReflectiveTests(SearchTest); |
20 }); | 21 }); |
21 } | 22 } |
22 | 23 |
23 class ExpectedResult { | 24 class ExpectedResult { |
24 final List<String> enclosingComponents; | 25 final Element enclosingElement; |
25 final SearchResultKind kind; | 26 final SearchResultKind kind; |
26 final int offset; | 27 final int offset; |
27 final int length; | 28 final int length; |
28 final bool isResolved; | 29 final bool isResolved; |
29 final bool isQualified; | 30 final bool isQualified; |
30 | 31 |
31 ExpectedResult(this.enclosingComponents, this.kind, this.offset, this.length, | 32 ExpectedResult(this.enclosingElement, this.kind, this.offset, this.length, |
32 {this.isResolved: true, this.isQualified: false}); | 33 {this.isResolved: true, this.isQualified: false}); |
33 | 34 |
34 bool operator ==(Object result) { | 35 bool operator ==(Object result) { |
35 return result is SearchResult && | 36 return result is SearchResult && |
36 result.kind == this.kind && | 37 result.kind == this.kind && |
37 result.isResolved == this.isResolved && | 38 result.isResolved == this.isResolved && |
38 result.isQualified == this.isQualified && | 39 result.isQualified == this.isQualified && |
39 result.offset == this.offset && | 40 result.offset == this.offset && |
40 hasExpectedComponents(result.enclosingElement); | 41 result.enclosingElement == this.enclosingElement; |
41 } | |
42 | |
43 bool hasExpectedComponents(Element element) { | |
44 for (int i = enclosingComponents.length - 1; i >= 0; i--) { | |
45 if (element == null) { | |
46 return false; | |
47 } | |
48 if (element is CompilationUnitElement) { | |
49 if (element.source.uri.toString() != enclosingComponents[0]) { | |
50 return false; | |
51 } | |
52 } else if (element.name != enclosingComponents[i]) { | |
53 return false; | |
54 } | |
55 element = element.enclosingElement; | |
56 } | |
57 return true; | |
58 } | 42 } |
59 | 43 |
60 @override | 44 @override |
61 String toString() { | 45 String toString() { |
62 StringBuffer buffer = new StringBuffer(); | 46 StringBuffer buffer = new StringBuffer(); |
63 buffer.write("ExpectedResult(kind="); | 47 buffer.write("ExpectedResult(kind="); |
64 buffer.write(kind); | 48 buffer.write(kind); |
65 buffer.write(", enclosingComponents="); | 49 buffer.write(", enclosingElement="); |
66 buffer.write(enclosingComponents); | 50 buffer.write(enclosingElement); |
67 buffer.write(", offset="); | 51 buffer.write(", offset="); |
68 buffer.write(offset); | 52 buffer.write(offset); |
69 buffer.write(", length="); | 53 buffer.write(", length="); |
70 buffer.write(length); | 54 buffer.write(length); |
71 buffer.write(", isResolved="); | 55 buffer.write(", isResolved="); |
72 buffer.write(isResolved); | 56 buffer.write(isResolved); |
73 buffer.write(", isQualified="); | 57 buffer.write(", isQualified="); |
74 buffer.write(isQualified); | 58 buffer.write(isQualified); |
75 buffer.write(")"); | 59 buffer.write(")"); |
76 return buffer.toString(); | 60 return buffer.toString(); |
77 } | 61 } |
78 } | 62 } |
79 | 63 |
80 @reflectiveTest | 64 @reflectiveTest |
81 class SearchTest extends BaseAnalysisDriverTest { | 65 class SearchTest extends BaseAnalysisDriverTest { |
82 static const testUri = 'package:test/test.dart'; | 66 static const testUri = 'package:test/test.dart'; |
83 | 67 |
68 CompilationUnit testUnit; | |
69 CompilationUnitElement testUnitElement; | |
70 LibraryElement testLibraryElement; | |
71 | |
72 fail_test_searchReferences_CompilationUnitElement() async { | |
Brian Wilkerson
2016/11/28 18:52:08
Use @failingTest?
| |
73 provider.newFile( | |
74 _p('$testProject/my_part.dart'), | |
75 ''' | |
76 part of lib; | |
77 '''); | |
78 await _resolveTestUnit(''' | |
79 library lib; | |
80 part 'my_part.dart'; | |
81 '''); | |
82 CompilationUnitElement element = _findElementAtString('my_part'); | |
83 var expected = [ | |
84 _expectIdQ(element.library.definingCompilationUnit, | |
85 SearchResultKind.REFERENCE, "'my_part.dart'", | |
86 length: "'my_part.dart'".length) | |
87 ]; | |
88 await _verifyReferences(element, expected); | |
89 } | |
90 | |
91 test_searchReferences_ClassElement_definedInside() async { | |
92 await _resolveTestUnit(''' | |
93 class A {}; | |
94 main(A p) { | |
95 A v; | |
96 } | |
97 class B1 extends A {} // extends | |
98 class B2 implements A {} // implements | |
99 class B3 extends Object with A {} // with | |
100 List<A> v2 = null; | |
101 '''); | |
102 ClassElement element = _findElementAtString('A {}'); | |
103 Element p = _findElement('p'); | |
104 Element main = _findElement('main'); | |
105 Element b1 = _findElement('B1'); | |
106 Element b2 = _findElement('B2'); | |
107 Element b3 = _findElement('B3'); | |
108 Element v2 = _findElement('v2'); | |
109 var expected = [ | |
110 _expectId(p, SearchResultKind.REFERENCE, 'A p'), | |
111 _expectId(main, SearchResultKind.REFERENCE, 'A v'), | |
112 _expectId(b1, SearchResultKind.REFERENCE, 'A {} // extends'), | |
113 _expectId(b2, SearchResultKind.REFERENCE, 'A {} // implements'), | |
114 _expectId(b3, SearchResultKind.REFERENCE, 'A {} // with'), | |
115 _expectId(v2, SearchResultKind.REFERENCE, 'A> v2'), | |
116 ]; | |
117 await _verifyReferences(element, expected); | |
118 } | |
119 | |
120 test_searchReferences_ClassElement_definedOutside() async { | |
121 provider.newFile( | |
122 _p('$testProject/lib.dart'), | |
123 r''' | |
124 class A {}; | |
125 '''); | |
126 await _resolveTestUnit(''' | |
127 import 'lib.dart'; | |
128 main(A p) { | |
129 A v; | |
130 } | |
131 '''); | |
132 ClassElement element = _findElementAtString('A p'); | |
133 Element p = _findElement('p'); | |
134 Element main = _findElement('main'); | |
135 var expected = [ | |
136 _expectId(p, SearchResultKind.REFERENCE, 'A p'), | |
137 _expectId(main, SearchResultKind.REFERENCE, 'A v') | |
138 ]; | |
139 await _verifyReferences(element, expected); | |
140 } | |
141 | |
142 test_searchReferences_ConstructorElement() async { | |
143 await _resolveTestUnit(''' | |
144 class A { | |
145 A.named() {} | |
146 } | |
147 main() { | |
148 new A.named(); | |
149 } | |
150 '''); | |
151 ConstructorElement element = _findElement('named'); | |
152 Element mainElement = _findElement('main'); | |
153 var expected = [ | |
154 _expectIdQ(mainElement, SearchResultKind.REFERENCE, '.named();', | |
155 length: 6) | |
156 ]; | |
157 await _verifyReferences(element, expected); | |
158 } | |
159 | |
160 test_searchReferences_ConstructorElement_synthetic() async { | |
161 await _resolveTestUnit(''' | |
162 class A { | |
163 } | |
164 main() { | |
165 new A(); | |
166 } | |
167 '''); | |
168 ClassElement classElement = _findElement('A'); | |
169 ConstructorElement element = classElement.unnamedConstructor; | |
170 Element mainElement = _findElement('main'); | |
171 var expected = [ | |
172 _expectIdQ(mainElement, SearchResultKind.REFERENCE, '();', length: 0) | |
173 ]; | |
174 await _verifyReferences(element, expected); | |
175 } | |
176 | |
177 test_searchReferences_FieldElement() async { | |
178 await _resolveTestUnit(''' | |
179 class A { | |
180 var field; | |
181 A({this.field}); | |
182 main() { | |
183 new A(field: 1); | |
184 // getter | |
185 print(field); // ref-nq | |
186 print(this.field); // ref-q | |
187 field(); // inv-nq | |
188 this.field(); // inv-q | |
189 // setter | |
190 field = 2; // ref-nq; | |
191 this.field = 3; // ref-q; | |
192 } | |
193 } | |
194 '''); | |
195 FieldElement element = _findElement('field', ElementKind.FIELD); | |
196 Element main = _findElement('main'); | |
197 Element fieldParameter = _findElement('field', ElementKind.PARAMETER); | |
198 var expected = [ | |
199 _expectIdQ(fieldParameter, SearchResultKind.WRITE, 'field}'), | |
200 _expectIdQ(main, SearchResultKind.REFERENCE, 'field: 1'), | |
201 _expectId(main, SearchResultKind.READ, 'field); // ref-nq'), | |
202 _expectIdQ(main, SearchResultKind.READ, 'field); // ref-q'), | |
203 _expectId(main, SearchResultKind.INVOCATION, 'field(); // inv-nq'), | |
204 _expectIdQ(main, SearchResultKind.INVOCATION, 'field(); // inv-q'), | |
205 _expectId(main, SearchResultKind.WRITE, 'field = 2; // ref-nq'), | |
206 _expectIdQ(main, SearchResultKind.WRITE, 'field = 3; // ref-q'), | |
207 ]; | |
208 await _verifyReferences(element, expected); | |
209 } | |
210 | |
211 test_searchReferences_FieldElement_ofEnum() async { | |
212 await _resolveTestUnit(''' | |
213 enum MyEnum { | |
214 A, B, C | |
215 } | |
216 main() { | |
217 print(MyEnum.A.index); | |
218 print(MyEnum.values); | |
219 print(MyEnum.A); | |
220 print(MyEnum.B); | |
221 } | |
222 '''); | |
223 ClassElement enumElement = _findElement('MyEnum'); | |
224 Element mainElement = _findElement('main'); | |
225 await _verifyReferences(enumElement.getField('index'), | |
226 [_expectIdQ(mainElement, SearchResultKind.READ, 'index);')]); | |
227 await _verifyReferences(enumElement.getField('values'), | |
228 [_expectIdQ(mainElement, SearchResultKind.READ, 'values);')]); | |
229 await _verifyReferences(enumElement.getField('A'), [ | |
230 _expectIdQ(mainElement, SearchResultKind.READ, 'A.index);'), | |
231 _expectIdQ(mainElement, SearchResultKind.READ, 'A);') | |
232 ]); | |
233 await _verifyReferences(enumElement.getField('B'), | |
234 [_expectIdQ(mainElement, SearchResultKind.READ, 'B);')]); | |
235 } | |
236 | |
237 test_searchReferences_FieldElement_synthetic() async { | |
238 await _resolveTestUnit(''' | |
239 class A { | |
240 get field => null; | |
241 set field(x) {} | |
242 main() { | |
243 // getter | |
244 print(field); // ref-nq | |
245 print(this.field); // ref-q | |
246 field(); // inv-nq | |
247 this.field(); // inv-q | |
248 // setter | |
249 field = 2; // ref-nq; | |
250 this.field = 3; // ref-q; | |
251 } | |
252 } | |
253 '''); | |
254 FieldElement element = _findElement('field', ElementKind.FIELD); | |
255 Element main = _findElement('main'); | |
256 var expected = [ | |
257 _expectId(main, SearchResultKind.READ, 'field); // ref-nq'), | |
258 _expectIdQ(main, SearchResultKind.READ, 'field); // ref-q'), | |
259 _expectId(main, SearchResultKind.INVOCATION, 'field(); // inv-nq'), | |
260 _expectIdQ(main, SearchResultKind.INVOCATION, 'field(); // inv-q'), | |
261 _expectId(main, SearchResultKind.WRITE, 'field = 2; // ref-nq'), | |
262 _expectIdQ(main, SearchResultKind.WRITE, 'field = 3; // ref-q'), | |
263 ]; | |
264 await _verifyReferences(element, expected); | |
265 } | |
266 | |
267 test_searchReferences_FunctionElement() async { | |
268 await _resolveTestUnit(''' | |
269 test() {} | |
270 main() { | |
271 test(); | |
272 print(test); | |
273 } | |
274 '''); | |
275 FunctionElement element = _findElement('test'); | |
276 Element mainElement = _findElement('main'); | |
277 var expected = [ | |
278 _expectId(mainElement, SearchResultKind.INVOCATION, 'test();'), | |
279 _expectId(mainElement, SearchResultKind.REFERENCE, 'test);') | |
280 ]; | |
281 await _verifyReferences(element, expected); | |
282 } | |
283 | |
84 test_searchReferences_FunctionElement_local() async { | 284 test_searchReferences_FunctionElement_local() async { |
85 addTestFile(''' | 285 await _resolveTestUnit(''' |
86 main() { | 286 main() { |
87 test() {} | 287 test() {} |
88 test(); | 288 test(); |
89 print(test); | 289 print(test); |
90 } | 290 } |
91 '''); | 291 '''); |
92 FunctionElement element = await _findElement('test'); | 292 FunctionElement element = _findElement('test'); |
93 List<String> main = [testUri, 'main']; | 293 Element main = _findElement('main'); |
94 var expected = [ | 294 var expected = [ |
95 _expectId(main, SearchResultKind.INVOCATION, 'test();'), | 295 _expectId(main, SearchResultKind.INVOCATION, 'test();'), |
96 _expectId(main, SearchResultKind.REFERENCE, 'test);') | 296 _expectId(main, SearchResultKind.REFERENCE, 'test);') |
97 ]; | 297 ]; |
98 await _verifyReferences(element, expected); | 298 await _verifyReferences(element, expected); |
99 } | 299 } |
100 | 300 |
101 test_searchReferences_LabelElement() async { | 301 test_searchReferences_LabelElement() async { |
102 addTestFile(''' | 302 await _resolveTestUnit(''' |
103 main() { | 303 main() { |
104 label: | 304 label: |
105 while (true) { | 305 while (true) { |
106 if (true) { | 306 if (true) { |
107 break label; // 1 | 307 break label; // 1 |
108 } | 308 } |
109 break label; // 2 | 309 break label; // 2 |
110 } | 310 } |
111 } | 311 } |
112 '''); | 312 '''); |
113 Element element = await _findElement('label'); | 313 Element element = _findElement('label'); |
114 List<String> main = [testUri, 'main']; | 314 Element main = _findElement('main'); |
115 var expected = [ | 315 var expected = [ |
116 _expectId(main, SearchResultKind.REFERENCE, 'label; // 1'), | 316 _expectId(main, SearchResultKind.REFERENCE, 'label; // 1'), |
117 _expectId(main, SearchResultKind.REFERENCE, 'label; // 2') | 317 _expectId(main, SearchResultKind.REFERENCE, 'label; // 2') |
118 ]; | 318 ]; |
119 await _verifyReferences(element, expected); | 319 await _verifyReferences(element, expected); |
120 } | 320 } |
121 | 321 |
122 test_searchReferences_LocalVariableElement() async { | 322 test_searchReferences_LocalVariableElement() async { |
123 addTestFile(r''' | 323 await _resolveTestUnit(r''' |
124 main() { | 324 main() { |
125 var v; | 325 var v; |
126 v = 1; | 326 v = 1; |
127 v += 2; | 327 v += 2; |
128 print(v); | 328 print(v); |
129 v(); | 329 v(); |
130 } | 330 } |
131 '''); | 331 '''); |
132 Element element = await _findElement('v'); | 332 Element element = _findElement('v'); |
133 List<String> main = [testUri, 'main']; | 333 Element main = _findElement('main'); |
134 var expected = [ | 334 var expected = [ |
135 _expectId(main, SearchResultKind.WRITE, 'v = 1;'), | 335 _expectId(main, SearchResultKind.WRITE, 'v = 1;'), |
136 _expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'), | 336 _expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'), |
137 _expectId(main, SearchResultKind.READ, 'v);'), | 337 _expectId(main, SearchResultKind.READ, 'v);'), |
138 _expectId(main, SearchResultKind.INVOCATION, 'v();') | 338 _expectId(main, SearchResultKind.INVOCATION, 'v();') |
139 ]; | 339 ]; |
140 await _verifyReferences(element, expected); | 340 await _verifyReferences(element, expected); |
141 } | 341 } |
142 | 342 |
143 test_searchReferences_localVariableElement_inForEachLoop() async { | 343 test_searchReferences_localVariableElement_inForEachLoop() async { |
144 addTestFile(''' | 344 await _resolveTestUnit(''' |
145 main() { | 345 main() { |
146 for (var v in []) { | 346 for (var v in []) { |
147 v = 1; | 347 v = 1; |
148 v += 2; | 348 v += 2; |
149 print(v); | 349 print(v); |
150 v(); | 350 v(); |
151 } | 351 } |
152 } | 352 } |
153 '''); | 353 '''); |
154 Element element = await _findElementAtString('v in []'); | 354 Element element = _findElementAtString('v in []'); |
155 List<String> main = [testUri, 'main']; | 355 Element main = _findElement('main'); |
156 var expected = [ | 356 var expected = [ |
157 _expectId(main, SearchResultKind.WRITE, 'v = 1;'), | 357 _expectId(main, SearchResultKind.WRITE, 'v = 1;'), |
158 _expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'), | 358 _expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'), |
159 _expectId(main, SearchResultKind.READ, 'v);'), | 359 _expectId(main, SearchResultKind.READ, 'v);'), |
160 _expectId(main, SearchResultKind.INVOCATION, 'v();') | 360 _expectId(main, SearchResultKind.INVOCATION, 'v();') |
161 ]; | 361 ]; |
162 await _verifyReferences(element, expected); | 362 await _verifyReferences(element, expected); |
163 } | 363 } |
164 | 364 |
365 test_searchReferences_MethodElement() async { | |
366 await _resolveTestUnit(''' | |
367 class A { | |
368 m() {} | |
369 main() { | |
370 m(); // 1 | |
371 this.m(); // 2 | |
372 print(m); // 3 | |
373 print(this.m); // 4 | |
374 } | |
375 } | |
376 '''); | |
377 MethodElement method = _findElement('m'); | |
378 Element mainElement = _findElement('main'); | |
379 var expected = [ | |
380 _expectId(mainElement, SearchResultKind.INVOCATION, 'm(); // 1'), | |
381 _expectIdQ(mainElement, SearchResultKind.INVOCATION, 'm(); // 2'), | |
382 _expectId(mainElement, SearchResultKind.REFERENCE, 'm); // 3'), | |
383 _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'm); // 4') | |
384 ]; | |
385 await _verifyReferences(method, expected); | |
386 } | |
387 | |
388 test_searchReferences_MethodMember() async { | |
389 await _resolveTestUnit(''' | |
390 class A<T> { | |
391 T m() => null; | |
392 } | |
393 main(A<int> a) { | |
394 a.m(); // ref | |
395 } | |
396 '''); | |
397 MethodMember method = _findElementAtString('m(); // ref'); | |
398 Element mainElement = _findElement('main'); | |
399 var expected = [ | |
400 _expectIdQ(mainElement, SearchResultKind.INVOCATION, 'm(); // ref') | |
401 ]; | |
402 await _verifyReferences(method, expected); | |
403 } | |
404 | |
405 test_searchReferences_ParameterElement_ofConstructor() async { | |
406 await _resolveTestUnit(''' | |
407 class C { | |
408 var f; | |
409 C({p}) : f = p + 1 { | |
410 p = 2; | |
411 p += 3; | |
412 print(p); | |
413 p(); | |
414 } | |
415 } | |
416 main() { | |
417 new C(p: 42); | |
418 } | |
419 '''); | |
420 ParameterElement element = _findElement('p'); | |
421 ClassElement classC = _findElement('C'); | |
422 ConstructorElement constructorA = classC.unnamedConstructor; | |
423 Element mainElement = _findElement('main'); | |
424 var expected = [ | |
425 _expectId(constructorA, SearchResultKind.READ, 'p + 1 {'), | |
426 _expectId(constructorA, SearchResultKind.WRITE, 'p = 2;'), | |
427 _expectId(constructorA, SearchResultKind.READ_WRITE, 'p += 3;'), | |
428 _expectId(constructorA, SearchResultKind.READ, 'p);'), | |
429 _expectId(constructorA, SearchResultKind.INVOCATION, 'p();'), | |
430 _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'p: 42') | |
431 ]; | |
432 await _verifyReferences(element, expected); | |
433 } | |
434 | |
435 test_searchReferences_ParameterElement_ofLocalFunction() async { | |
436 await _resolveTestUnit(''' | |
437 main() { | |
438 foo({p}) { | |
439 p = 1; | |
440 p += 2; | |
441 print(p); | |
442 p(); | |
443 } | |
444 foo(p: 42); | |
445 } | |
446 '''); | |
447 ParameterElement element = _findElement('p'); | |
448 Element fooElement = _findElement('foo'); | |
449 Element mainElement = _findElement('main'); | |
450 var expected = [ | |
451 _expectId(fooElement, SearchResultKind.WRITE, 'p = 1;'), | |
452 _expectId(fooElement, SearchResultKind.READ_WRITE, 'p += 2;'), | |
453 _expectId(fooElement, SearchResultKind.READ, 'p);'), | |
454 _expectId(fooElement, SearchResultKind.INVOCATION, 'p();'), | |
455 _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'p: 42') | |
456 ]; | |
457 await _verifyReferences(element, expected); | |
458 } | |
459 | |
460 test_searchReferences_ParameterElement_ofMethod() async { | |
461 await _resolveTestUnit(''' | |
462 class C { | |
463 foo({p}) { | |
464 p = 1; | |
465 p += 2; | |
466 print(p); | |
467 p(); | |
468 } | |
469 } | |
470 main(C c) { | |
471 c.foo(p: 42); | |
472 } | |
473 '''); | |
474 ParameterElement element = _findElement('p'); | |
475 Element fooElement = _findElement('foo'); | |
476 Element mainElement = _findElement('main'); | |
477 var expected = [ | |
478 _expectId(fooElement, SearchResultKind.WRITE, 'p = 1;'), | |
479 _expectId(fooElement, SearchResultKind.READ_WRITE, 'p += 2;'), | |
480 _expectId(fooElement, SearchResultKind.READ, 'p);'), | |
481 _expectId(fooElement, SearchResultKind.INVOCATION, 'p();'), | |
482 _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'p: 42') | |
483 ]; | |
484 await _verifyReferences(element, expected); | |
485 } | |
486 | |
487 test_searchReferences_ParameterElement_ofTopLevelFunction() async { | |
488 await _resolveTestUnit(''' | |
489 foo({p}) { | |
490 p = 1; | |
491 p += 2; | |
492 print(p); | |
493 p(); | |
494 } | |
495 main() { | |
496 foo(p: 42); | |
497 } | |
498 '''); | |
499 ParameterElement element = _findElement('p'); | |
500 Element fooElement = _findElement('foo'); | |
501 Element mainElement = _findElement('main'); | |
502 var expected = [ | |
503 _expectId(fooElement, SearchResultKind.WRITE, 'p = 1;'), | |
504 _expectId(fooElement, SearchResultKind.READ_WRITE, 'p += 2;'), | |
505 _expectId(fooElement, SearchResultKind.READ, 'p);'), | |
506 _expectId(fooElement, SearchResultKind.INVOCATION, 'p();'), | |
507 _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'p: 42') | |
508 ]; | |
509 await _verifyReferences(element, expected); | |
510 } | |
511 | |
512 test_searchReferences_PropertyAccessorElement_getter() async { | |
513 await _resolveTestUnit(''' | |
514 class A { | |
515 get ggg => null; | |
516 main() { | |
517 print(ggg); // ref-nq | |
518 print(this.ggg); // ref-q | |
519 ggg(); // inv-nq | |
520 this.ggg(); // inv-q | |
521 } | |
522 } | |
523 '''); | |
524 PropertyAccessorElement element = _findElement('ggg', ElementKind.GETTER); | |
525 Element main = _findElement('main'); | |
526 var expected = [ | |
527 _expectId(main, SearchResultKind.REFERENCE, 'ggg); // ref-nq'), | |
528 _expectIdQ(main, SearchResultKind.REFERENCE, 'ggg); // ref-q'), | |
529 _expectId(main, SearchResultKind.INVOCATION, 'ggg(); // inv-nq'), | |
530 _expectIdQ(main, SearchResultKind.INVOCATION, 'ggg(); // inv-q'), | |
531 ]; | |
532 await _verifyReferences(element, expected); | |
533 } | |
534 | |
535 test_searchReferences_PropertyAccessorElement_setter() async { | |
536 await _resolveTestUnit(''' | |
537 class A { | |
538 set s(x) {} | |
539 main() { | |
540 s = 1; | |
541 this.s = 2; | |
542 } | |
543 } | |
544 '''); | |
545 PropertyAccessorElement element = _findElement('s='); | |
546 Element mainElement = _findElement('main'); | |
547 var expected = [ | |
548 _expectId(mainElement, SearchResultKind.REFERENCE, 's = 1'), | |
549 _expectIdQ(mainElement, SearchResultKind.REFERENCE, 's = 2') | |
550 ]; | |
551 await _verifyReferences(element, expected); | |
552 } | |
553 | |
554 test_searchReferences_TopLevelVariableElement() async { | |
555 provider.newFile( | |
556 _p('$testProject/lib.dart'), | |
557 ''' | |
558 library lib; | |
559 var V; | |
560 '''); | |
561 await _resolveTestUnit(''' | |
562 import 'lib.dart' show V; // imp | |
563 import 'lib.dart' as pref; | |
564 main() { | |
565 pref.V = 1; // q | |
566 print(pref.V); // q | |
567 pref.V(); // q | |
568 V = 1; // nq | |
569 print(V); // nq | |
570 V(); // nq | |
571 } | |
572 '''); | |
573 ImportElement importElement = testLibraryElement.imports[0]; | |
574 CompilationUnitElement impUnit = | |
575 importElement.importedLibrary.definingCompilationUnit; | |
576 TopLevelVariableElement variable = impUnit.topLevelVariables[0]; | |
577 Element main = _findElement('main'); | |
578 var expected = [ | |
579 _expectIdQ(testUnitElement, SearchResultKind.REFERENCE, 'V; // imp'), | |
580 _expectIdQ(main, SearchResultKind.WRITE, 'V = 1; // q'), | |
581 _expectIdQ(main, SearchResultKind.READ, 'V); // q'), | |
582 _expectIdQ(main, SearchResultKind.INVOCATION, 'V(); // q'), | |
583 _expectId(main, SearchResultKind.WRITE, 'V = 1; // nq'), | |
584 _expectId(main, SearchResultKind.READ, 'V); // nq'), | |
585 _expectId(main, SearchResultKind.INVOCATION, 'V(); // nq'), | |
586 ]; | |
587 await _verifyReferences(variable, expected); | |
588 } | |
589 | |
165 test_searchReferences_TypeParameterElement_ofClass() async { | 590 test_searchReferences_TypeParameterElement_ofClass() async { |
166 addTestFile(''' | 591 await _resolveTestUnit(''' |
167 class A<T> { | 592 class A<T> { |
168 foo(T a) {} | 593 foo(T a) {} |
169 bar(T b) {} | 594 bar(T b) {} |
170 } | 595 } |
171 '''); | 596 '''); |
172 TypeParameterElement element = await _findElement('T'); | 597 TypeParameterElement element = _findElement('T'); |
173 var expected = [ | 598 Element a = _findElement('a'); |
174 _expectId([testUri, 'A', 'foo', 'a'], SearchResultKind.REFERENCE, 'T a'), | 599 Element b = _findElement('b'); |
175 _expectId([testUri, 'A', 'bar', 'b'], SearchResultKind.REFERENCE, 'T b'), | 600 var expected = [ |
601 _expectId(a, SearchResultKind.REFERENCE, 'T a'), | |
602 _expectId(b, SearchResultKind.REFERENCE, 'T b'), | |
176 ]; | 603 ]; |
177 await _verifyReferences(element, expected); | 604 await _verifyReferences(element, expected); |
178 } | 605 } |
179 | 606 |
180 test_searchReferences_TypeParameterElement_ofLocalFunction() async { | 607 test_searchReferences_TypeParameterElement_ofLocalFunction() async { |
181 addTestFile(''' | 608 await _resolveTestUnit(''' |
182 main() { | 609 main() { |
183 void foo<T>(T a) { | 610 void foo<T>(T a) { |
184 void bar(T b) {} | 611 void bar(T b) {} |
185 } | 612 } |
186 } | 613 } |
187 '''); | 614 '''); |
188 TypeParameterElement element = await _findElement('T'); | 615 TypeParameterElement element = _findElement('T'); |
189 var expected = [ | 616 Element a = _findElement('a'); |
190 _expectId( | 617 Element b = _findElement('b'); |
191 [testUri, 'main', 'foo', 'a'], SearchResultKind.REFERENCE, 'T a'), | 618 var expected = [ |
192 _expectId([testUri, 'main', 'foo', 'bar', 'b'], | 619 _expectId(a, SearchResultKind.REFERENCE, 'T a'), |
193 SearchResultKind.REFERENCE, 'T b'), | 620 _expectId(b, SearchResultKind.REFERENCE, 'T b'), |
194 ]; | 621 ]; |
195 await _verifyReferences(element, expected); | 622 await _verifyReferences(element, expected); |
196 } | 623 } |
197 | 624 |
198 test_searchReferences_TypeParameterElement_ofMethod() async { | 625 test_searchReferences_TypeParameterElement_ofMethod() async { |
199 addTestFile(''' | 626 await _resolveTestUnit(''' |
200 class A { | 627 class A { |
201 foo<T>(T p) {} | 628 foo<T>(T p) {} |
202 } | 629 } |
203 '''); | 630 '''); |
204 TypeParameterElement element = await _findElement('T'); | 631 TypeParameterElement element = _findElement('T'); |
205 var expected = [ | 632 Element p = _findElement('p'); |
206 _expectId([testUri, 'A', 'foo', 'p'], SearchResultKind.REFERENCE, 'T p'), | 633 var expected = [ |
634 _expectId(p, SearchResultKind.REFERENCE, 'T p'), | |
207 ]; | 635 ]; |
208 await _verifyReferences(element, expected); | 636 await _verifyReferences(element, expected); |
209 } | 637 } |
210 | 638 |
211 test_searchReferences_TypeParameterElement_ofTopLevelFunction() async { | 639 test_searchReferences_TypeParameterElement_ofTopLevelFunction() async { |
212 addTestFile(''' | 640 await _resolveTestUnit(''' |
213 foo<T>(T a) { | 641 foo<T>(T a) { |
214 bar(T b) {} | 642 bar(T b) {} |
215 } | 643 } |
216 '''); | 644 '''); |
217 TypeParameterElement element = await _findElement('T'); | 645 TypeParameterElement element = _findElement('T'); |
218 var expected = [ | 646 Element a = _findElement('a'); |
219 _expectId([testUri, 'foo', 'a'], SearchResultKind.REFERENCE, 'T a'), | 647 Element b = _findElement('b'); |
220 _expectId( | 648 var expected = [ |
221 [testUri, 'foo', 'bar', 'b'], SearchResultKind.REFERENCE, 'T b'), | 649 _expectId(a, SearchResultKind.REFERENCE, 'T a'), |
650 _expectId(b, SearchResultKind.REFERENCE, 'T b'), | |
222 ]; | 651 ]; |
223 await _verifyReferences(element, expected); | 652 await _verifyReferences(element, expected); |
224 } | 653 } |
225 | 654 |
226 ExpectedResult _expectId( | 655 ExpectedResult _expectId( |
227 List<String> enclosingComponents, SearchResultKind kind, String search, | 656 Element enclosingElement, SearchResultKind kind, String search, |
228 {int length, bool isResolved: true, bool isQualified: false}) { | 657 {int length, bool isResolved: true, bool isQualified: false}) { |
229 int offset = findOffset(search); | 658 int offset = findOffset(search); |
230 if (length == null) { | 659 if (length == null) { |
231 length = getLeadingIdentifierLength(search); | 660 length = getLeadingIdentifierLength(search); |
232 } | 661 } |
233 return new ExpectedResult(enclosingComponents, kind, offset, length, | 662 return new ExpectedResult(enclosingElement, kind, offset, length, |
234 isResolved: isResolved, isQualified: isQualified); | 663 isResolved: isResolved, isQualified: isQualified); |
235 } | 664 } |
236 | 665 |
237 Future<Element> _findElement(String name) async { | 666 /** |
238 AnalysisResult result = await driver.getResult(testFile); | 667 * Create [ExpectedResult] for a qualified and resolved match. |
239 return findChildElement(result.unit.element, name); | 668 */ |
240 } | 669 ExpectedResult _expectIdQ( |
241 | 670 Element element, SearchResultKind kind, String search, |
242 Future<Element> _findElementAtString(String search) async { | 671 {int length, bool isResolved: true}) { |
243 AnalysisResult result = await driver.getResult(testFile); | 672 return _expectId(element, kind, search, isQualified: true, length: length); |
673 } | |
674 | |
675 Element _findElement(String name, [ElementKind kind]) { | |
676 return findChildElement(testUnit.element, name, kind); | |
677 } | |
678 | |
679 Element _findElementAtString(String search) { | |
244 int offset = findOffset(search); | 680 int offset = findOffset(search); |
245 AstNode node = new NodeLocator(offset).searchWithin(result.unit); | 681 AstNode node = new NodeLocator(offset).searchWithin(testUnit); |
246 return ElementLocator.locate(node); | 682 return ElementLocator.locate(node); |
247 } | 683 } |
248 | 684 |
685 String _p(String path) => provider.convertPath(path); | |
686 | |
687 Future<Null> _resolveTestUnit(String code) async { | |
688 addTestFile(code); | |
689 if (testUnit == null) { | |
690 AnalysisResult result = await driver.getResult(testFile); | |
691 testUnit = result.unit; | |
692 testUnitElement = testUnit.element; | |
693 testLibraryElement = testUnitElement.library; | |
694 } | |
695 } | |
696 | |
249 Future _verifyReferences( | 697 Future _verifyReferences( |
250 Element element, List<ExpectedResult> expectedMatches) async { | 698 Element element, List<ExpectedResult> expectedMatches) async { |
251 List<SearchResult> results = await driver.search.references(element); | 699 List<SearchResult> results = await driver.search.references(element); |
252 _assertResults(results, expectedMatches); | 700 _assertResults(results, expectedMatches); |
253 expect(results, hasLength(expectedMatches.length)); | 701 expect(results, hasLength(expectedMatches.length)); |
254 } | 702 } |
255 | 703 |
256 static void _assertResults( | 704 static void _assertResults( |
257 List<SearchResult> matches, List<ExpectedResult> expectedMatches) { | 705 List<SearchResult> matches, List<ExpectedResult> expectedMatches) { |
258 expect(matches, unorderedEquals(expectedMatches)); | 706 expect(matches, unorderedEquals(expectedMatches)); |
259 } | 707 } |
260 } | 708 } |
OLD | NEW |