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.index.dart_index_contributor; | |
6 | |
7 import 'package:analysis_server/src/provisional/index/index_core.dart'; | |
8 import 'package:analysis_server/src/services/index/index.dart'; | |
9 import 'package:analysis_server/src/services/index/index_contributor.dart'; | |
10 import 'package:analysis_server/src/services/index/index_store.dart'; | |
11 import 'package:analysis_server/src/services/index/indexable_element.dart'; | |
12 import 'package:analysis_server/src/services/index/indexable_file.dart'; | |
13 import 'package:analyzer/dart/ast/ast.dart'; | |
14 import 'package:analyzer/dart/element/element.dart'; | |
15 import 'package:analyzer/src/generated/engine.dart'; | |
16 import 'package:analyzer/src/generated/source.dart'; | |
17 import 'package:test_reflective_loader/test_reflective_loader.dart'; | |
18 import 'package:typed_mock/typed_mock.dart'; | |
19 import 'package:unittest/unittest.dart'; | |
20 | |
21 import '../../abstract_single_unit.dart'; | |
22 import '../../utils.dart'; | |
23 | |
24 main() { | |
25 initializeTestEnvironment(); | |
26 defineReflectiveTests(DartUnitContributorTest); | |
27 } | |
28 | |
29 void indexDartUnit( | |
30 InternalIndexStore store, AnalysisContext context, CompilationUnit unit) { | |
31 new DartIndexContributor().contributeTo(store, context, unit); | |
32 } | |
33 | |
34 /** | |
35 * Returns `true` if the [actual] location the same properties as [expected]. | |
36 */ | |
37 bool _equalsLocation(LocationImpl actual, ExpectedLocation expected) { | |
38 return _equalsLocationProperties(actual, expected.indexable, expected.offset, | |
39 expected.length, expected.isQualified, expected.isResolved); | |
40 } | |
41 | |
42 /** | |
43 * Returns `true` if the [actual] location the expected properties. | |
44 */ | |
45 bool _equalsLocationProperties( | |
46 LocationImpl actual, | |
47 IndexableObject expectedIndexable, | |
48 int expectedOffset, | |
49 int expectedLength, | |
50 bool isQualified, | |
51 bool isResolved) { | |
52 return (expectedIndexable == null || expectedIndexable == actual.indexable) && | |
53 expectedOffset == actual.offset && | |
54 expectedLength == actual.length && | |
55 isQualified == actual.isQualified && | |
56 isResolved == actual.isResolved; | |
57 } | |
58 | |
59 bool _equalsRecordedRelation( | |
60 RecordedRelation recordedRelation, | |
61 IndexableObject expectedIndexable, | |
62 RelationshipImpl expectedRelationship, | |
63 ExpectedLocation expectedLocation) { | |
64 return expectedIndexable == recordedRelation.indexable && | |
65 (expectedRelationship == null || | |
66 expectedRelationship == recordedRelation.relationship) && | |
67 (expectedLocation == null || | |
68 _equalsLocation(recordedRelation.location, expectedLocation)); | |
69 } | |
70 | |
71 @reflectiveTest | |
72 class DartUnitContributorTest extends AbstractSingleUnitTest { | |
73 InternalIndexStore store = new MockIndexStore(); | |
74 List<RecordedRelation> recordedRelations = <RecordedRelation>[]; | |
75 List<Element> recordedTopElements = <Element>[]; | |
76 | |
77 CompilationUnitElement importedUnit({int index: 0}) { | |
78 List<ImportElement> imports = testLibraryElement.imports; | |
79 return imports[index].importedLibrary.definingCompilationUnit; | |
80 } | |
81 | |
82 void setUp() { | |
83 super.setUp(); | |
84 when(store.aboutToIndex(context, anyObject)).thenReturn(true); | |
85 when(store.recordRelationship(anyObject, anyObject, anyObject)).thenInvoke( | |
86 (IndexableObject indexable, RelationshipImpl relationship, | |
87 LocationImpl location) { | |
88 recordedRelations | |
89 .add(new RecordedRelation(indexable, relationship, location)); | |
90 }); | |
91 when(store.recordTopLevelDeclaration(anyObject)) | |
92 .thenInvoke((Element element) { | |
93 recordedTopElements.add(element); | |
94 }); | |
95 } | |
96 | |
97 void test_bad_unresolvedFieldFormalParameter() { | |
98 verifyNoTestUnitErrors = false; | |
99 _indexTestUnit(''' | |
100 class Test { | |
101 final field; | |
102 Test(this.fie); | |
103 }'''); | |
104 } | |
105 | |
106 void test_definesClass() { | |
107 _indexTestUnit('class A {}'); | |
108 // prepare elements | |
109 ClassElement classElement = findElement("A"); | |
110 // verify | |
111 _assertDefinesTopLevelElement(classElement); | |
112 } | |
113 | |
114 void test_definesClassAlias() { | |
115 _indexTestUnit(''' | |
116 class Mix {} | |
117 class MyClass = Object with Mix;'''); | |
118 // prepare elements | |
119 Element classElement = findElement("MyClass"); | |
120 // verify | |
121 _assertDefinesTopLevelElement(classElement); | |
122 } | |
123 | |
124 void test_definesClassEnum() { | |
125 _indexTestUnit('enum MyEnum {A, B, c}'); | |
126 // prepare elements | |
127 ClassElement classElement = findElement("MyEnum"); | |
128 // verify | |
129 _assertDefinesTopLevelElement(classElement); | |
130 } | |
131 | |
132 void test_definesFunction() { | |
133 _indexTestUnit('myFunction() {}'); | |
134 // prepare elements | |
135 FunctionElement functionElement = findElement("myFunction"); | |
136 // verify | |
137 _assertDefinesTopLevelElement(functionElement); | |
138 } | |
139 | |
140 void test_definesFunctionType() { | |
141 _indexTestUnit('typedef MyFunction(int p);'); | |
142 // prepare elements | |
143 FunctionTypeAliasElement typeAliasElement = findElement("MyFunction"); | |
144 // verify | |
145 _assertDefinesTopLevelElement(typeAliasElement); | |
146 } | |
147 | |
148 void test_definesVariable() { | |
149 _indexTestUnit('var myVar = 42;'); | |
150 // prepare elements | |
151 VariableElement varElement = findElement("myVar"); | |
152 // verify | |
153 _assertDefinesTopLevelElement(varElement); | |
154 } | |
155 | |
156 void test_forIn() { | |
157 _indexTestUnit(''' | |
158 main() { | |
159 for (var v in []) { | |
160 } | |
161 }'''); | |
162 // prepare elements | |
163 Element mainElement = findElement("main"); | |
164 VariableElement variableElement = findElement("v"); | |
165 // verify | |
166 _assertNoRecordedRelationForElement(variableElement, | |
167 IndexConstants.IS_READ_BY, _expectedLocation(mainElement, 'v in []')); | |
168 } | |
169 | |
170 void test_hasAncestor_ClassDeclaration() { | |
171 _indexTestUnit(''' | |
172 class A {} | |
173 class B1 extends A {} | |
174 class B2 implements A {} | |
175 class C1 extends B1 {} | |
176 class C2 extends B2 {} | |
177 class C3 implements B1 {} | |
178 class C4 implements B2 {} | |
179 class M extends Object with A {} | |
180 '''); | |
181 // prepare elements | |
182 ClassElement classElementA = findElement("A"); | |
183 ClassElement classElementB1 = findElement("B1"); | |
184 ClassElement classElementB2 = findElement("B2"); | |
185 ClassElement classElementC1 = findElement("C1"); | |
186 ClassElement classElementC2 = findElement("C2"); | |
187 ClassElement classElementC3 = findElement("C3"); | |
188 ClassElement classElementC4 = findElement("C4"); | |
189 ClassElement classElementM = findElement("M"); | |
190 // verify | |
191 _assertRecordedRelationForElement( | |
192 classElementA, | |
193 IndexConstants.HAS_ANCESTOR, | |
194 _expectedLocation(classElementB1, 'B1 extends A')); | |
195 _assertRecordedRelationForElement( | |
196 classElementA, | |
197 IndexConstants.HAS_ANCESTOR, | |
198 _expectedLocation(classElementB2, 'B2 implements A')); | |
199 _assertRecordedRelationForElement( | |
200 classElementA, | |
201 IndexConstants.HAS_ANCESTOR, | |
202 _expectedLocation(classElementC1, 'C1 extends B1')); | |
203 _assertRecordedRelationForElement( | |
204 classElementA, | |
205 IndexConstants.HAS_ANCESTOR, | |
206 _expectedLocation(classElementC2, 'C2 extends B2')); | |
207 _assertRecordedRelationForElement( | |
208 classElementA, | |
209 IndexConstants.HAS_ANCESTOR, | |
210 _expectedLocation(classElementC3, 'C3 implements B1')); | |
211 _assertRecordedRelationForElement( | |
212 classElementA, | |
213 IndexConstants.HAS_ANCESTOR, | |
214 _expectedLocation(classElementC4, 'C4 implements B2')); | |
215 _assertRecordedRelationForElement( | |
216 classElementA, | |
217 IndexConstants.HAS_ANCESTOR, | |
218 _expectedLocation(classElementM, 'M extends Object with A')); | |
219 } | |
220 | |
221 void test_hasAncestor_ClassTypeAlias() { | |
222 _indexTestUnit(''' | |
223 class A {} | |
224 class B extends A {} | |
225 class C1 = Object with A; | |
226 class C2 = Object with B; | |
227 '''); | |
228 // prepare elements | |
229 ClassElement classElementA = findElement("A"); | |
230 ClassElement classElementB = findElement("B"); | |
231 ClassElement classElementC1 = findElement("C1"); | |
232 ClassElement classElementC2 = findElement("C2"); | |
233 // verify | |
234 _assertRecordedRelationForElement( | |
235 classElementA, | |
236 IndexConstants.HAS_ANCESTOR, | |
237 _expectedLocation(classElementC1, 'C1 = Object with A')); | |
238 _assertRecordedRelationForElement( | |
239 classElementA, | |
240 IndexConstants.HAS_ANCESTOR, | |
241 _expectedLocation(classElementC2, 'C2 = Object with B')); | |
242 _assertRecordedRelationForElement( | |
243 classElementB, | |
244 IndexConstants.HAS_ANCESTOR, | |
245 _expectedLocation(classElementC2, 'C2 = Object with B')); | |
246 } | |
247 | |
248 void test_IndexableName_field() { | |
249 _indexTestUnit(''' | |
250 class A { | |
251 int field; | |
252 } | |
253 main(A a, p) { | |
254 print(a.field); // r | |
255 print(p.field); // ur | |
256 { | |
257 var field = 42; | |
258 print(field); // not a member | |
259 } | |
260 } | |
261 '''); | |
262 // prepare elements | |
263 Element mainElement = findElement('main'); | |
264 FieldElement fieldElement = findElement('field'); | |
265 IndexableName indexable = new IndexableName('field'); | |
266 // verify | |
267 _assertRecordedRelation(indexable, IndexConstants.NAME_IS_DEFINED_BY, | |
268 _expectedLocation(fieldElement, 'field;')); | |
269 _assertRecordedRelation(indexable, IndexConstants.IS_READ_BY, | |
270 _expectedLocationQ(mainElement, 'field); // r')); | |
271 _assertRecordedRelation(indexable, IndexConstants.IS_READ_BY, | |
272 _expectedLocationQU(mainElement, 'field); // ur')); | |
273 _assertNoRecordedRelation(indexable, IndexConstants.IS_READ_BY, | |
274 _expectedLocation(mainElement, 'field); // not a member')); | |
275 } | |
276 | |
277 void test_IndexableName_isDefinedBy_localVariable_inForEach() { | |
278 _indexTestUnit(''' | |
279 class A { | |
280 main() { | |
281 for (int test in []) { | |
282 } | |
283 } | |
284 } | |
285 '''); | |
286 // prepare elements | |
287 LocalVariableElement testElement = findElement('test'); | |
288 IndexableName indexable = new IndexableName('test'); | |
289 // verify | |
290 _assertRecordedRelation(indexable, IndexConstants.NAME_IS_DEFINED_BY, | |
291 _expectedLocation(testElement, 'test in []')); | |
292 } | |
293 | |
294 void test_IndexableName_method() { | |
295 _indexTestUnit(''' | |
296 class A { | |
297 method() {} | |
298 } | |
299 main(A a, p) { | |
300 a.method(); // r | |
301 p.method(); // ur | |
302 } | |
303 '''); | |
304 // prepare elements | |
305 Element mainElement = findElement('main'); | |
306 MethodElement methodElement = findElement('method'); | |
307 IndexableName indexable = new IndexableName('method'); | |
308 // verify | |
309 _assertRecordedRelation(indexable, IndexConstants.NAME_IS_DEFINED_BY, | |
310 _expectedLocation(methodElement, 'method() {}')); | |
311 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
312 _expectedLocationQ(mainElement, 'method(); // r')); | |
313 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
314 _expectedLocationQU(mainElement, 'method(); // ur')); | |
315 } | |
316 | |
317 void test_IndexableName_operator_resolved() { | |
318 _indexTestUnit(''' | |
319 class A { | |
320 operator +(o) {} | |
321 operator -(o) {} | |
322 operator ~() {} | |
323 operator ==(o) {} | |
324 } | |
325 main(A a) { | |
326 a + 5; | |
327 a += 5; | |
328 a == 5; | |
329 ++a; | |
330 --a; | |
331 ~a; | |
332 a++; | |
333 a--; | |
334 } | |
335 '''); | |
336 // prepare elements | |
337 Element mainElement = findElement('main'); | |
338 // binary | |
339 _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY, | |
340 _expectedLocationQ(mainElement, '+ 5', length: 1)); | |
341 _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY, | |
342 _expectedLocationQ(mainElement, '+= 5', length: 2)); | |
343 _assertRecordedRelationForName('==', IndexConstants.IS_INVOKED_BY, | |
344 _expectedLocationQ(mainElement, '== 5', length: 2)); | |
345 // prefix | |
346 _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY, | |
347 _expectedLocationQ(mainElement, '++a', length: 2)); | |
348 _assertRecordedRelationForName('-', IndexConstants.IS_INVOKED_BY, | |
349 _expectedLocationQ(mainElement, '--a', length: 2)); | |
350 _assertRecordedRelationForName('~', IndexConstants.IS_INVOKED_BY, | |
351 _expectedLocationQ(mainElement, '~a', length: 1)); | |
352 // postfix | |
353 _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY, | |
354 _expectedLocationQ(mainElement, '++;', length: 2)); | |
355 _assertRecordedRelationForName('-', IndexConstants.IS_INVOKED_BY, | |
356 _expectedLocationQ(mainElement, '--;', length: 2)); | |
357 } | |
358 | |
359 void test_IndexableName_operator_unresolved() { | |
360 _indexTestUnit(''' | |
361 class A { | |
362 operator +(o) {} | |
363 operator -(o) {} | |
364 operator ~() {} | |
365 operator ==(o) {} | |
366 } | |
367 main(a) { | |
368 a + 5; | |
369 a += 5; | |
370 a == 5; | |
371 ++a; | |
372 --a; | |
373 ~a; | |
374 a++; | |
375 a--; | |
376 } | |
377 '''); | |
378 // prepare elements | |
379 Element mainElement = findElement('main'); | |
380 // binary | |
381 _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY, | |
382 _expectedLocationQU(mainElement, '+ 5', length: 1)); | |
383 _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY, | |
384 _expectedLocationQU(mainElement, '+= 5', length: 2)); | |
385 _assertRecordedRelationForName('==', IndexConstants.IS_INVOKED_BY, | |
386 _expectedLocationQU(mainElement, '== 5', length: 2)); | |
387 // prefix | |
388 _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY, | |
389 _expectedLocationQU(mainElement, '++a', length: 2)); | |
390 _assertRecordedRelationForName('-', IndexConstants.IS_INVOKED_BY, | |
391 _expectedLocationQU(mainElement, '--a', length: 2)); | |
392 _assertRecordedRelationForName('~', IndexConstants.IS_INVOKED_BY, | |
393 _expectedLocationQU(mainElement, '~a', length: 1)); | |
394 // postfix | |
395 _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY, | |
396 _expectedLocationQU(mainElement, '++;', length: 2)); | |
397 _assertRecordedRelationForName('-', IndexConstants.IS_INVOKED_BY, | |
398 _expectedLocationQU(mainElement, '--;', length: 2)); | |
399 } | |
400 | |
401 void test_isDefinedBy_IndexableName_method() { | |
402 _indexTestUnit(''' | |
403 class A { | |
404 m() {} | |
405 }'''); | |
406 // prepare elements | |
407 Element methodElement = findElement("m"); | |
408 IndexableName nameIndexable = new IndexableName("m"); | |
409 // verify | |
410 _assertRecordedRelationForIndexable( | |
411 nameIndexable, | |
412 IndexConstants.NAME_IS_DEFINED_BY, | |
413 _expectedLocation(methodElement, 'm() {}')); | |
414 } | |
415 | |
416 void test_isDefinedBy_IndexableName_operator() { | |
417 _indexTestUnit(''' | |
418 class A { | |
419 operator +(o) {} | |
420 }'''); | |
421 // prepare elements | |
422 Element methodElement = findElement("+"); | |
423 IndexableName nameIndexable = new IndexableName("+"); | |
424 // verify | |
425 _assertRecordedRelationForIndexable( | |
426 nameIndexable, | |
427 IndexConstants.NAME_IS_DEFINED_BY, | |
428 _expectedLocation(methodElement, '+(o) {}', length: 1)); | |
429 } | |
430 | |
431 void test_isExtendedBy_ClassDeclaration() { | |
432 _indexTestUnit(''' | |
433 class A {} // 1 | |
434 class B extends A {} // 2 | |
435 '''); | |
436 // prepare elements | |
437 ClassElement classElementA = findElement("A"); | |
438 ClassElement classElementB = findElement("B"); | |
439 // verify | |
440 _assertRecordedRelationForElement( | |
441 classElementA, | |
442 IndexConstants.IS_EXTENDED_BY, | |
443 _expectedLocation(classElementB, 'A {} // 2')); | |
444 } | |
445 | |
446 void test_isExtendedBy_ClassDeclaration_Object() { | |
447 _indexTestUnit(''' | |
448 class A {} // 1 | |
449 '''); | |
450 // prepare elements | |
451 ClassElement classElementA = findElement("A"); | |
452 ClassElement classElementObject = classElementA.supertype.element; | |
453 // verify | |
454 _assertRecordedRelationForElement( | |
455 classElementObject, | |
456 IndexConstants.IS_EXTENDED_BY, | |
457 _expectedLocation(classElementA, 'A {}', length: 0)); | |
458 } | |
459 | |
460 void test_isExtendedBy_ClassTypeAlias() { | |
461 _indexTestUnit(''' | |
462 class A {} // 1 | |
463 class B {} // 2 | |
464 class C = A with B; // 3 | |
465 '''); | |
466 // prepare elements | |
467 ClassElement classElementA = findElement("A"); | |
468 ClassElement classElementC = findElement("C"); | |
469 // verify | |
470 _assertRecordedRelationForElement( | |
471 classElementA, | |
472 IndexConstants.IS_EXTENDED_BY, | |
473 _expectedLocation(classElementC, 'A with')); | |
474 } | |
475 | |
476 void test_isImplementedBy_ClassDeclaration() { | |
477 _indexTestUnit(''' | |
478 class A {} // 1 | |
479 class B implements A {} // 2 | |
480 '''); | |
481 // prepare elements | |
482 ClassElement classElementA = findElement("A"); | |
483 ClassElement classElementB = findElement("B"); | |
484 // verify | |
485 _assertRecordedRelationForElement( | |
486 classElementA, | |
487 IndexConstants.IS_IMPLEMENTED_BY, | |
488 _expectedLocation(classElementB, 'A {} // 2')); | |
489 } | |
490 | |
491 void test_isImplementedBy_ClassTypeAlias() { | |
492 _indexTestUnit(''' | |
493 class A {} // 1 | |
494 class B {} // 2 | |
495 class C = Object with A implements B; // 3 | |
496 '''); | |
497 // prepare elements | |
498 ClassElement classElementB = findElement("B"); | |
499 ClassElement classElementC = findElement("C"); | |
500 // verify | |
501 _assertRecordedRelationForElement( | |
502 classElementB, | |
503 IndexConstants.IS_IMPLEMENTED_BY, | |
504 _expectedLocation(classElementC, 'B; // 3')); | |
505 } | |
506 | |
507 void test_isInvokedBy_FieldElement() { | |
508 _indexTestUnit(''' | |
509 class A { | |
510 var field; | |
511 main() { | |
512 this.field(); // q | |
513 field(); // nq | |
514 } | |
515 }'''); | |
516 // prepare elements | |
517 Element mainElement = findElement("main"); | |
518 FieldElement fieldElement = findElement("field"); | |
519 PropertyAccessorElement getterElement = fieldElement.getter; | |
520 IndexableElement indexable = new IndexableElement(getterElement); | |
521 // verify | |
522 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
523 _expectedLocationQ(mainElement, 'field(); // q')); | |
524 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
525 _expectedLocation(mainElement, 'field(); // nq')); | |
526 } | |
527 | |
528 void test_isInvokedBy_FunctionElement() { | |
529 addSource( | |
530 '/lib.dart', | |
531 ''' | |
532 library lib; | |
533 foo() {} | |
534 '''); | |
535 _indexTestUnit(''' | |
536 import 'lib.dart'; | |
537 import 'lib.dart' as pref; | |
538 main() { | |
539 pref.foo(); // q | |
540 foo(); // nq | |
541 }'''); | |
542 // prepare elements | |
543 Element mainElement = findElement("main"); | |
544 FunctionElement functionElement = importedUnit().functions[0]; | |
545 IndexableElement indexable = new IndexableElement(functionElement); | |
546 // verify | |
547 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
548 _expectedLocation(mainElement, 'foo(); // q')); | |
549 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
550 _expectedLocation(mainElement, 'foo(); // nq')); | |
551 } | |
552 | |
553 void test_isInvokedBy_LocalVariableElement() { | |
554 _indexTestUnit(''' | |
555 main() { | |
556 var v; | |
557 v(); | |
558 }'''); | |
559 // prepare elements | |
560 Element mainElement = findElement("main"); | |
561 Element element = findElement("v"); | |
562 // verify | |
563 _assertRecordedRelationForElement(element, IndexConstants.IS_INVOKED_BY, | |
564 _expectedLocation(mainElement, 'v();')); | |
565 } | |
566 | |
567 void test_isInvokedBy_MethodElement() { | |
568 _indexTestUnit(''' | |
569 class A { | |
570 foo() {} | |
571 main() { | |
572 this.foo(); // q | |
573 foo(); // nq | |
574 } | |
575 }'''); | |
576 // prepare elements | |
577 Element mainElement = findElement("main"); | |
578 Element methodElement = findElement("foo"); | |
579 IndexableElement indexable = new IndexableElement(methodElement); | |
580 // verify | |
581 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
582 _expectedLocationQ(mainElement, 'foo(); // q')); | |
583 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
584 _expectedLocation(mainElement, 'foo(); // nq')); | |
585 } | |
586 | |
587 void test_isInvokedBy_MethodElement_propagatedType() { | |
588 _indexTestUnit(''' | |
589 class A { | |
590 foo() {} | |
591 } | |
592 main() { | |
593 var a = new A(); | |
594 a.foo(); | |
595 } | |
596 '''); | |
597 // prepare elements | |
598 Element mainElement = findElement("main"); | |
599 Element methodElement = findElement("foo"); | |
600 // verify | |
601 _assertRecordedRelationForElement( | |
602 methodElement, | |
603 IndexConstants.IS_INVOKED_BY, | |
604 _expectedLocationQ(mainElement, 'foo();')); | |
605 } | |
606 | |
607 void test_isInvokedBy_operator_binary() { | |
608 _indexTestUnit(''' | |
609 class A { | |
610 operator +(other) => this; | |
611 } | |
612 main(A a) { | |
613 print(a + 1); | |
614 a += 2; | |
615 ++a; | |
616 a++; | |
617 } | |
618 '''); | |
619 // prepare elements | |
620 MethodElement element = findElement('+'); | |
621 Element mainElement = findElement('main'); | |
622 IndexableElement indexable = new IndexableElement(element); | |
623 // verify | |
624 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
625 _expectedLocationQ(mainElement, '+ 1', length: 1)); | |
626 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
627 _expectedLocationQ(mainElement, '+= 2', length: 2)); | |
628 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
629 _expectedLocationQ(mainElement, '++a;', length: 2)); | |
630 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
631 _expectedLocationQ(mainElement, '++;', length: 2)); | |
632 } | |
633 | |
634 void test_isInvokedBy_operator_index() { | |
635 _indexTestUnit(''' | |
636 class A { | |
637 operator [](i) => null; | |
638 operator []=(i, v) {} | |
639 } | |
640 main(A a) { | |
641 print(a[0]); | |
642 a[1] = 42; | |
643 } | |
644 '''); | |
645 // prepare elements | |
646 MethodElement readElement = findElement("[]"); | |
647 MethodElement writeElement = findElement("[]="); | |
648 Element mainElement = findElement('main'); | |
649 // verify | |
650 _assertRecordedRelationForElement(readElement, IndexConstants.IS_INVOKED_BY, | |
651 _expectedLocationQ(mainElement, '[0]', length: 1)); | |
652 _assertRecordedRelationForElement( | |
653 writeElement, | |
654 IndexConstants.IS_INVOKED_BY, | |
655 _expectedLocationQ(mainElement, '[1] =', length: 1)); | |
656 } | |
657 | |
658 void test_isInvokedBy_operator_prefix() { | |
659 _indexTestUnit(''' | |
660 class A { | |
661 A operator ~() => this; | |
662 } | |
663 main(A a) { | |
664 print(~a); | |
665 } | |
666 '''); | |
667 // prepare elements | |
668 MethodElement element = findElement("~"); | |
669 Element mainElement = findElement('main'); | |
670 // verify | |
671 _assertRecordedRelationForElement(element, IndexConstants.IS_INVOKED_BY, | |
672 _expectedLocationQ(mainElement, '~a', length: 1)); | |
673 } | |
674 | |
675 void test_isInvokedBy_ParameterElement() { | |
676 _indexTestUnit(''' | |
677 main(p()) { | |
678 p(); | |
679 }'''); | |
680 // prepare elements | |
681 Element mainElement = findElement("main"); | |
682 Element element = findElement("p"); | |
683 // verify | |
684 _assertRecordedRelationForElement(element, IndexConstants.IS_INVOKED_BY, | |
685 _expectedLocation(mainElement, 'p();')); | |
686 } | |
687 | |
688 void test_isMixedInBy_ClassDeclaration() { | |
689 _indexTestUnit(''' | |
690 class A {} // 1 | |
691 class B extends Object with A {} // 2 | |
692 '''); | |
693 // prepare elements | |
694 ClassElement classElementA = findElement("A"); | |
695 ClassElement classElementB = findElement("B"); | |
696 // verify | |
697 _assertRecordedRelationForElement( | |
698 classElementA, | |
699 IndexConstants.IS_MIXED_IN_BY, | |
700 _expectedLocation(classElementB, 'A {} // 2')); | |
701 } | |
702 | |
703 void test_isMixedInBy_ClassTypeAlias() { | |
704 _indexTestUnit(''' | |
705 class A {} // 1 | |
706 class B = Object with A; // 2 | |
707 '''); | |
708 // prepare elements | |
709 ClassElement classElementA = findElement("A"); | |
710 ClassElement classElementB = findElement("B"); | |
711 // verify | |
712 _assertRecordedRelationForElement( | |
713 classElementA, | |
714 IndexConstants.IS_MIXED_IN_BY, | |
715 _expectedLocation(classElementB, 'A; // 2')); | |
716 } | |
717 | |
718 void test_isReadBy_ParameterElement() { | |
719 _indexTestUnit(''' | |
720 main(var p) { | |
721 print(p); | |
722 } | |
723 '''); | |
724 // prepare elements | |
725 Element mainElement = findElement("main"); | |
726 Element parameterElement = findElement("p"); | |
727 // verify | |
728 _assertRecordedRelationForElement(parameterElement, | |
729 IndexConstants.IS_READ_BY, _expectedLocation(mainElement, 'p);')); | |
730 } | |
731 | |
732 void test_isReadBy_VariableElement() { | |
733 _indexTestUnit(''' | |
734 main() { | |
735 var v = 0; | |
736 print(v); | |
737 } | |
738 '''); | |
739 // prepare elements | |
740 Element mainElement = findElement("main"); | |
741 Element variableElement = findElement("v"); | |
742 // verify | |
743 _assertRecordedRelationForElement(variableElement, | |
744 IndexConstants.IS_READ_BY, _expectedLocation(mainElement, 'v);')); | |
745 } | |
746 | |
747 void test_isReadWrittenBy_ParameterElement() { | |
748 _indexTestUnit(''' | |
749 main(int p) { | |
750 p += 1; | |
751 } | |
752 '''); | |
753 // prepare elements | |
754 Element mainElement = findElement("main"); | |
755 Element parameterElement = findElement("p"); | |
756 // verify | |
757 _assertRecordedRelationForElement( | |
758 parameterElement, | |
759 IndexConstants.IS_READ_WRITTEN_BY, | |
760 _expectedLocation(mainElement, 'p += 1')); | |
761 } | |
762 | |
763 void test_isReadWrittenBy_VariableElement() { | |
764 _indexTestUnit(''' | |
765 main() { | |
766 var v = 0; | |
767 v += 1; | |
768 } | |
769 '''); | |
770 // prepare elements | |
771 Element mainElement = findElement("main"); | |
772 Element variableElement = findElement("v"); | |
773 // verify | |
774 _assertRecordedRelationForElement( | |
775 variableElement, | |
776 IndexConstants.IS_READ_WRITTEN_BY, | |
777 _expectedLocation(mainElement, 'v += 1')); | |
778 } | |
779 | |
780 void test_isReferencedBy_ClassElement() { | |
781 _indexTestUnit(''' | |
782 class A { | |
783 static var field; | |
784 } | |
785 main(A p) { | |
786 A v; | |
787 new A(); // 2 | |
788 A.field = 1; | |
789 print(A.field); // 3 | |
790 } | |
791 '''); | |
792 // prepare elements | |
793 ClassElement aElement = findElement("A"); | |
794 Element mainElement = findElement("main"); | |
795 ParameterElement pElement = findElement("p"); | |
796 VariableElement vElement = findElement("v"); | |
797 IndexableElement indexable = new IndexableElement(aElement); | |
798 // verify | |
799 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
800 _expectedLocation(pElement, 'A p) {')); | |
801 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
802 _expectedLocation(vElement, 'A v;')); | |
803 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
804 _expectedLocation(mainElement, 'A(); // 2')); | |
805 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
806 _expectedLocation(mainElement, 'A.field = 1;')); | |
807 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
808 _expectedLocation(mainElement, 'A.field); // 3')); | |
809 } | |
810 | |
811 void test_isReferencedBy_ClassElement_invocation() { | |
812 verifyNoTestUnitErrors = false; | |
813 _indexTestUnit(''' | |
814 class A {} | |
815 main() { | |
816 A(); // invalid code, but still a reference | |
817 }'''); | |
818 // prepare elements | |
819 Element mainElement = findElement('main'); | |
820 Element classElement = findElement('A'); | |
821 IndexableElement indexable = new IndexableElement(classElement); | |
822 // verify | |
823 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
824 _expectedLocation(mainElement, 'A();')); | |
825 } | |
826 | |
827 void test_isReferencedBy_ClassTypeAlias() { | |
828 _indexTestUnit(''' | |
829 class A {} | |
830 class B = Object with A; | |
831 main(B p) { | |
832 B v; | |
833 } | |
834 '''); | |
835 // prepare elements | |
836 ClassElement bElement = findElement("B"); | |
837 ParameterElement pElement = findElement("p"); | |
838 VariableElement vElement = findElement("v"); | |
839 IndexableElement indexable = new IndexableElement(bElement); | |
840 // verify | |
841 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
842 _expectedLocation(pElement, 'B p) {')); | |
843 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
844 _expectedLocation(vElement, 'B v;')); | |
845 } | |
846 | |
847 void test_isReferencedBy_CompilationUnitElement_export() { | |
848 addSource( | |
849 '/lib.dart', | |
850 ''' | |
851 library lib; | |
852 '''); | |
853 _indexTestUnit(''' | |
854 export 'lib.dart'; | |
855 '''); | |
856 // prepare elements | |
857 LibraryElement libElement = testLibraryElement.exportedLibraries[0]; | |
858 CompilationUnitElement libUnitElement = libElement.definingCompilationUnit; | |
859 // verify | |
860 _assertRecordedRelationForElement( | |
861 libUnitElement, | |
862 IndexConstants.IS_REFERENCED_BY, | |
863 _expectedLocation(testUnitElement, "'lib.dart'", length: 10)); | |
864 } | |
865 | |
866 void test_isReferencedBy_CompilationUnitElement_import() { | |
867 addSource( | |
868 '/lib.dart', | |
869 ''' | |
870 library lib; | |
871 '''); | |
872 _indexTestUnit(''' | |
873 import 'lib.dart'; | |
874 '''); | |
875 // prepare elements | |
876 LibraryElement libElement = testLibraryElement.imports[0].importedLibrary; | |
877 CompilationUnitElement libUnitElement = libElement.definingCompilationUnit; | |
878 // verify | |
879 _assertRecordedRelationForElement( | |
880 libUnitElement, | |
881 IndexConstants.IS_REFERENCED_BY, | |
882 _expectedLocation(testUnitElement, "'lib.dart'", length: 10)); | |
883 } | |
884 | |
885 void test_isReferencedBy_CompilationUnitElement_part() { | |
886 addSource('/my_unit.dart', 'part of my_lib;'); | |
887 _indexTestUnit(''' | |
888 library my_lib; | |
889 part 'my_unit.dart'; | |
890 '''); | |
891 // prepare elements | |
892 CompilationUnitElement myUnitElement = testLibraryElement.parts[0]; | |
893 // verify | |
894 _assertRecordedRelationForElement( | |
895 myUnitElement, | |
896 IndexConstants.IS_REFERENCED_BY, | |
897 _expectedLocation(testUnitElement, "'my_unit.dart';", length: 14)); | |
898 } | |
899 | |
900 void test_isReferencedBy_ConstructorElement() { | |
901 _indexTestUnit(''' | |
902 class A implements B { | |
903 A() {} | |
904 A.foo() {} | |
905 } | |
906 class B extends A { | |
907 B() : super(); // marker-1 | |
908 B.foo() : super.foo(); // marker-2 | |
909 factory B.bar() = A.foo; // marker-3 | |
910 } | |
911 main() { | |
912 new A(); // marker-main-1 | |
913 new A.foo(); // marker-main-2 | |
914 } | |
915 '''); | |
916 // prepare elements | |
917 Element mainElement = findElement('main'); | |
918 var isConstructor = (node) => node is ConstructorDeclaration; | |
919 ConstructorElement consA = findNodeElementAtString("A()", isConstructor); | |
920 ConstructorElement consA_foo = | |
921 findNodeElementAtString("A.foo()", isConstructor); | |
922 ConstructorElement consB = findNodeElementAtString("B()", isConstructor); | |
923 ConstructorElement consB_foo = | |
924 findNodeElementAtString("B.foo()", isConstructor); | |
925 ConstructorElement consB_bar = | |
926 findNodeElementAtString("B.bar()", isConstructor); | |
927 IndexableElement indexableA = new IndexableElement(consA); | |
928 IndexableElement indexableA_foo = new IndexableElement(consA_foo); | |
929 // A() | |
930 _assertRecordedRelation(indexableA, IndexConstants.IS_REFERENCED_BY, | |
931 _expectedLocation(consB, '(); // marker-1', length: 0)); | |
932 _assertRecordedRelation(indexableA, IndexConstants.IS_REFERENCED_BY, | |
933 _expectedLocation(mainElement, '(); // marker-main-1', length: 0)); | |
934 // A.foo() | |
935 _assertRecordedRelation(indexableA_foo, IndexConstants.IS_REFERENCED_BY, | |
936 _expectedLocation(consB_foo, '.foo(); // marker-2', length: 4)); | |
937 _assertRecordedRelation(indexableA_foo, IndexConstants.IS_REFERENCED_BY, | |
938 _expectedLocation(consB_bar, '.foo; // marker-3', length: 4)); | |
939 _assertRecordedRelation(indexableA_foo, IndexConstants.IS_REFERENCED_BY, | |
940 _expectedLocation(mainElement, '.foo(); // marker-main-2', length: 4)); | |
941 } | |
942 | |
943 void test_isReferencedBy_ConstructorElement_classTypeAlias() { | |
944 _indexTestUnit(''' | |
945 class M {} | |
946 class A implements B { | |
947 A() {} | |
948 A.named() {} | |
949 } | |
950 class B = A with M; | |
951 main() { | |
952 new B(); // marker-main-1 | |
953 new B.named(); // marker-main-2 | |
954 } | |
955 '''); | |
956 // prepare elements | |
957 Element mainElement = findElement('main'); | |
958 var isConstructor = (node) => node is ConstructorDeclaration; | |
959 ConstructorElement consA = findNodeElementAtString("A()", isConstructor); | |
960 ConstructorElement consA_named = | |
961 findNodeElementAtString("A.named()", isConstructor); | |
962 // verify | |
963 _assertRecordedRelationForElement(consA, IndexConstants.IS_REFERENCED_BY, | |
964 _expectedLocation(mainElement, '(); // marker-main-1', length: 0)); | |
965 _assertRecordedRelationForElement( | |
966 consA_named, | |
967 IndexConstants.IS_REFERENCED_BY, | |
968 _expectedLocation(mainElement, '.named(); // marker-main-2', | |
969 length: 6)); | |
970 } | |
971 | |
972 void test_isReferencedBy_ConstructorElement_redirection() { | |
973 _indexTestUnit(''' | |
974 class A { | |
975 A() : this.bar(); | |
976 A.foo() : this(); // marker | |
977 A.bar(); | |
978 } | |
979 '''); | |
980 // prepare elements | |
981 var isConstructor = (node) => node is ConstructorDeclaration; | |
982 ConstructorElement constructorA = | |
983 findNodeElementAtString("A()", isConstructor); | |
984 ConstructorElement constructorA_foo = | |
985 findNodeElementAtString("A.foo()", isConstructor); | |
986 ConstructorElement constructorA_bar = | |
987 findNodeElementAtString("A.bar()", isConstructor); | |
988 // A() | |
989 _assertRecordedRelationForElement( | |
990 constructorA, | |
991 IndexConstants.IS_REFERENCED_BY, | |
992 _expectedLocation(constructorA_foo, '(); // marker', length: 0)); | |
993 // A.foo() | |
994 _assertRecordedRelationForElement( | |
995 constructorA_bar, | |
996 IndexConstants.IS_REFERENCED_BY, | |
997 _expectedLocation(constructorA, '.bar();', length: 4)); | |
998 } | |
999 | |
1000 void test_isReferencedBy_FieldElement() { | |
1001 _indexTestUnit(''' | |
1002 class A { | |
1003 var field; | |
1004 A({this.field}); | |
1005 m() { | |
1006 field = 1; // nq | |
1007 print(field); // nq | |
1008 } | |
1009 } | |
1010 main(A a) { | |
1011 a.field = 2; // q | |
1012 print(a.field); // q | |
1013 new A(field: 3); | |
1014 } | |
1015 '''); | |
1016 // prepare elements | |
1017 Element mElement = findElement("m"); | |
1018 Element mainElement = findElement("main"); | |
1019 FieldElement fieldElement = findElement("field"); | |
1020 PropertyAccessorElement getter = fieldElement.getter; | |
1021 PropertyAccessorElement setter = fieldElement.setter; | |
1022 IndexableElement indexableGetter = new IndexableElement(getter); | |
1023 IndexableElement indexableSetter = new IndexableElement(setter); | |
1024 // m() | |
1025 _assertRecordedRelation(indexableSetter, IndexConstants.IS_REFERENCED_BY, | |
1026 _expectedLocation(mElement, 'field = 1; // nq')); | |
1027 _assertRecordedRelation(indexableGetter, IndexConstants.IS_REFERENCED_BY, | |
1028 _expectedLocation(mElement, 'field); // nq')); | |
1029 // main() | |
1030 _assertRecordedRelation(indexableSetter, IndexConstants.IS_REFERENCED_BY, | |
1031 _expectedLocationQ(mainElement, 'field = 2; // q')); | |
1032 _assertRecordedRelation(indexableGetter, IndexConstants.IS_REFERENCED_BY, | |
1033 _expectedLocationQ(mainElement, 'field); // q')); | |
1034 _assertRecordedRelationForElement( | |
1035 fieldElement, | |
1036 IndexConstants.IS_REFERENCED_BY, | |
1037 _expectedLocation(mainElement, 'field: 3')); | |
1038 } | |
1039 | |
1040 void test_isReferencedBy_fileOfLibrary_byImportingExportingFile() { | |
1041 addSource('/lib.dart', ''); | |
1042 _indexTestUnit(''' | |
1043 import 'lib.dart'; // 1 | |
1044 export 'lib.dart'; // 2 | |
1045 '''); | |
1046 // verify | |
1047 IndexableFile libIndexableFile = new IndexableFile('/lib.dart'); | |
1048 IndexableFile testIndexableFile = new IndexableFile(testFile); | |
1049 _assertRecordedRelationForIndexable( | |
1050 libIndexableFile, | |
1051 IndexConstants.IS_REFERENCED_BY, | |
1052 new ExpectedLocation( | |
1053 testIndexableFile, | |
1054 testCode.indexOf("'lib.dart'; // 1"), | |
1055 "'lib.dart'".length, | |
1056 false, | |
1057 true)); | |
1058 _assertRecordedRelationForIndexable( | |
1059 libIndexableFile, | |
1060 IndexConstants.IS_REFERENCED_BY, | |
1061 new ExpectedLocation( | |
1062 testIndexableFile, | |
1063 testCode.indexOf("'lib.dart'; // 2"), | |
1064 "'lib.dart'".length, | |
1065 false, | |
1066 true)); | |
1067 } | |
1068 | |
1069 void test_isReferencedBy_fileOfPart_bySourcingFile() { | |
1070 addSource('/part.dart', 'part of my.lib;'); | |
1071 _indexTestUnit(''' | |
1072 library my.lib; | |
1073 part 'part.dart'; | |
1074 '''); | |
1075 // verify | |
1076 IndexableFile partIndexableFile = new IndexableFile('/part.dart'); | |
1077 IndexableFile testIndexableFile = new IndexableFile(testFile); | |
1078 _assertRecordedRelationForIndexable( | |
1079 partIndexableFile, | |
1080 IndexConstants.IS_REFERENCED_BY, | |
1081 new ExpectedLocation(testIndexableFile, testCode.indexOf("'part.dart'"), | |
1082 "'part.dart'".length, false, true)); | |
1083 } | |
1084 | |
1085 void test_isReferencedBy_FunctionElement() { | |
1086 _indexTestUnit(''' | |
1087 foo() {} | |
1088 main() { | |
1089 print(foo); | |
1090 print(foo()); | |
1091 } | |
1092 '''); | |
1093 // prepare elements | |
1094 FunctionElement element = findElement("foo"); | |
1095 Element mainElement = findElement("main"); | |
1096 IndexableElement indexable = new IndexableElement(element); | |
1097 // "referenced" here | |
1098 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1099 _expectedLocation(mainElement, 'foo);')); | |
1100 // only "invoked", but not "referenced" | |
1101 { | |
1102 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
1103 _expectedLocation(mainElement, 'foo());')); | |
1104 _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1105 _expectedLocation(mainElement, 'foo());')); | |
1106 } | |
1107 } | |
1108 | |
1109 void test_isReferencedBy_FunctionTypeAliasElement() { | |
1110 _indexTestUnit(''' | |
1111 typedef A(); | |
1112 main(A p) { | |
1113 } | |
1114 '''); | |
1115 // prepare elements | |
1116 Element aElement = findElement('A'); | |
1117 Element pElement = findElement('p'); | |
1118 // verify | |
1119 _assertRecordedRelationForElement(aElement, IndexConstants.IS_REFERENCED_BY, | |
1120 _expectedLocation(pElement, 'A p) {')); | |
1121 } | |
1122 | |
1123 /** | |
1124 * There was a bug in the AST structure, when single [Comment] was cloned and | |
1125 * assigned to both [FieldDeclaration] and [VariableDeclaration]. | |
1126 * | |
1127 * This caused duplicate indexing. | |
1128 * Here we test that the problem is fixed one way or another. | |
1129 */ | |
1130 void test_isReferencedBy_identifierInComment() { | |
1131 _indexTestUnit(''' | |
1132 class A {} | |
1133 /// [A] text | |
1134 var myVariable = null; | |
1135 '''); | |
1136 // prepare elements | |
1137 Element aElement = findElement('A'); | |
1138 Element variableElement = findElement('myVariable'); | |
1139 IndexableElement indexable = new IndexableElement(aElement); | |
1140 // verify | |
1141 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1142 _expectedLocation(testUnitElement, 'A] text')); | |
1143 _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1144 _expectedLocation(variableElement, 'A] text')); | |
1145 } | |
1146 | |
1147 void test_isReferencedBy_ImportElement_noPrefix() { | |
1148 addSource( | |
1149 '/lib.dart', | |
1150 ''' | |
1151 library lib; | |
1152 var myVar; | |
1153 myFunction() {} | |
1154 myToHide() {} | |
1155 '''); | |
1156 _indexTestUnit(''' | |
1157 import 'lib.dart' show myVar, myFunction hide myToHide; | |
1158 main() { | |
1159 myVar = 1; | |
1160 myFunction(); | |
1161 print(0); | |
1162 } | |
1163 '''); | |
1164 // prepare elements | |
1165 ImportElement importElement = testLibraryElement.imports[0]; | |
1166 Element mainElement = findElement('main'); | |
1167 IndexableElement indexable = new IndexableElement(importElement); | |
1168 // verify | |
1169 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1170 _expectedLocation(mainElement, 'myVar = 1;', length: 0)); | |
1171 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1172 _expectedLocation(mainElement, 'myFunction();', length: 0)); | |
1173 _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1174 _expectedLocation(mainElement, 'print(0);', length: 0)); | |
1175 // no references from import combinators | |
1176 _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1177 _expectedLocation(testUnitElement, 'myVar, ', length: 0)); | |
1178 _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1179 _expectedLocation(testUnitElement, 'myFunction hide', length: 0)); | |
1180 _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1181 _expectedLocation(testUnitElement, 'myToHide;', length: 0)); | |
1182 } | |
1183 | |
1184 void test_isReferencedBy_ImportElement_withPrefix() { | |
1185 addSource( | |
1186 '/libA.dart', | |
1187 ''' | |
1188 library libA; | |
1189 var myVar; | |
1190 '''); | |
1191 addSource( | |
1192 '/libB.dart', | |
1193 ''' | |
1194 library libB; | |
1195 class MyClass {} | |
1196 '''); | |
1197 _indexTestUnit(''' | |
1198 import 'libA.dart' as pref; | |
1199 import 'libB.dart' as pref; | |
1200 main() { | |
1201 pref.myVar = 1; | |
1202 new pref.MyClass(); | |
1203 } | |
1204 '''); | |
1205 // prepare elements | |
1206 ImportElement importElementA = testLibraryElement.imports[0]; | |
1207 ImportElement importElementB = testLibraryElement.imports[1]; | |
1208 Element mainElement = findElement('main'); | |
1209 // verify | |
1210 _assertRecordedRelationForElement( | |
1211 importElementA, | |
1212 IndexConstants.IS_REFERENCED_BY, | |
1213 _expectedLocation(mainElement, 'pref.myVar = 1;', length: 5)); | |
1214 _assertRecordedRelationForElement( | |
1215 importElementB, | |
1216 IndexConstants.IS_REFERENCED_BY, | |
1217 _expectedLocation(mainElement, 'pref.MyClass();', length: 5)); | |
1218 } | |
1219 | |
1220 void test_isReferencedBy_ImportElement_withPrefix_combinators() { | |
1221 addSource( | |
1222 '/lib.dart', | |
1223 ''' | |
1224 library lib; | |
1225 class A {} | |
1226 class B {} | |
1227 '''); | |
1228 _indexTestUnit(''' | |
1229 import 'lib.dart' as pref show A; | |
1230 import 'lib.dart' as pref show B; | |
1231 import 'lib.dart'; | |
1232 import 'lib.dart' as otherPrefix; | |
1233 main() { | |
1234 new pref.A(); | |
1235 new pref.B(); | |
1236 } | |
1237 '''); | |
1238 // prepare elements | |
1239 ImportElement importElementA = testLibraryElement.imports[0]; | |
1240 ImportElement importElementB = testLibraryElement.imports[1]; | |
1241 Element mainElement = findElement('main'); | |
1242 // verify | |
1243 _assertRecordedRelationForElement( | |
1244 importElementA, | |
1245 IndexConstants.IS_REFERENCED_BY, | |
1246 _expectedLocation(mainElement, 'pref.A();', length: 5)); | |
1247 _assertRecordedRelationForElement( | |
1248 importElementB, | |
1249 IndexConstants.IS_REFERENCED_BY, | |
1250 _expectedLocation(mainElement, 'pref.B();', length: 5)); | |
1251 } | |
1252 | |
1253 void test_isReferencedBy_ImportElement_withPrefix_invocation() { | |
1254 addSource( | |
1255 '/lib.dart', | |
1256 ''' | |
1257 library lib; | |
1258 myFunc() {} | |
1259 '''); | |
1260 _indexTestUnit(''' | |
1261 import 'lib.dart' as pref; | |
1262 main() { | |
1263 pref.myFunc(); | |
1264 } | |
1265 '''); | |
1266 // prepare elements | |
1267 ImportElement importElement = testLibraryElement.imports[0]; | |
1268 Element mainElement = findElement('main'); | |
1269 // verify | |
1270 _assertRecordedRelationForElement( | |
1271 importElement, | |
1272 IndexConstants.IS_REFERENCED_BY, | |
1273 _expectedLocation(mainElement, 'pref.myFunc();', length: 5)); | |
1274 } | |
1275 | |
1276 void test_isReferencedBy_ImportElement_withPrefix_oneCandidate() { | |
1277 addSource( | |
1278 '/lib.dart', | |
1279 ''' | |
1280 library lib; | |
1281 class A {} | |
1282 class B {} | |
1283 '''); | |
1284 _indexTestUnit(''' | |
1285 import 'lib.dart' as pref show A; | |
1286 main() { | |
1287 new pref.A(); | |
1288 } | |
1289 '''); | |
1290 // prepare elements | |
1291 ImportElement importElement = testLibraryElement.imports[0]; | |
1292 Element mainElement = findElement('main'); | |
1293 // verify | |
1294 _assertRecordedRelationForElement( | |
1295 importElement, | |
1296 IndexConstants.IS_REFERENCED_BY, | |
1297 _expectedLocation(mainElement, 'pref.A();', length: 5)); | |
1298 } | |
1299 | |
1300 void test_isReferencedBy_ImportElement_withPrefix_unresolvedElement() { | |
1301 verifyNoTestUnitErrors = false; | |
1302 addSource( | |
1303 '/lib.dart', | |
1304 ''' | |
1305 library lib; | |
1306 '''); | |
1307 _indexTestUnit(''' | |
1308 import 'lib.dart' as pref; | |
1309 main() { | |
1310 pref.myVar = 1; | |
1311 } | |
1312 '''); | |
1313 } | |
1314 | |
1315 void test_isReferencedBy_ImportElement_withPrefix_wrongInvocation() { | |
1316 verifyNoTestUnitErrors = false; | |
1317 _indexTestUnit(''' | |
1318 import 'dart:math' as m; | |
1319 main() { | |
1320 m(); | |
1321 }'''); | |
1322 } | |
1323 | |
1324 void test_isReferencedBy_ImportElement_withPrefix_wrongPrefixedIdentifier() { | |
1325 verifyNoTestUnitErrors = false; | |
1326 _indexTestUnit(''' | |
1327 import 'dart:math' as m; | |
1328 main() { | |
1329 x.m; | |
1330 } | |
1331 '''); | |
1332 } | |
1333 | |
1334 void test_isReferencedBy_LabelElement() { | |
1335 _indexTestUnit(''' | |
1336 main() { | |
1337 L: while (true) { | |
1338 break L; | |
1339 } | |
1340 } | |
1341 '''); | |
1342 // prepare elements | |
1343 Element mainElement = findElement('main'); | |
1344 Element element = findElement('L'); | |
1345 // verify | |
1346 _assertRecordedRelationForElement(element, IndexConstants.IS_REFERENCED_BY, | |
1347 _expectedLocation(mainElement, 'L;')); | |
1348 } | |
1349 | |
1350 void test_isReferencedBy_libraryName_byPartOf() { | |
1351 Source libSource = addSource( | |
1352 '/lib.dart', | |
1353 ''' | |
1354 library lib; | |
1355 part 'test.dart'; | |
1356 '''); | |
1357 testCode = 'part of lib;'; | |
1358 testSource = addSource('/test.dart', testCode); | |
1359 testUnit = resolveDartUnit(testSource, libSource); | |
1360 testUnitElement = testUnit.element; | |
1361 testLibraryElement = testUnitElement.library; | |
1362 indexDartUnit(store, context, testUnit); | |
1363 // verify | |
1364 _assertRecordedRelationForElement( | |
1365 testLibraryElement, | |
1366 IndexConstants.IS_REFERENCED_BY, | |
1367 _expectedLocation(testUnitElement, "lib;")); | |
1368 } | |
1369 | |
1370 void test_isReferencedBy_MethodElement() { | |
1371 _indexTestUnit(''' | |
1372 class A { | |
1373 method() {} | |
1374 main() { | |
1375 print(this.method); // q | |
1376 print(method); // nq | |
1377 } | |
1378 }'''); | |
1379 // prepare elements | |
1380 Element mainElement = findElement("main"); | |
1381 MethodElement methodElement = findElement("method"); | |
1382 IndexableElement indexable = new IndexableElement(methodElement); | |
1383 // verify | |
1384 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1385 _expectedLocationQ(mainElement, 'method); // q')); | |
1386 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1387 _expectedLocation(mainElement, 'method); // nq')); | |
1388 } | |
1389 | |
1390 void test_isReferencedBy_ParameterElement() { | |
1391 _indexTestUnit(''' | |
1392 foo({var p}) {} | |
1393 main() { | |
1394 foo(p: 1); | |
1395 } | |
1396 '''); | |
1397 // prepare elements | |
1398 Element mainElement = findElement('main'); | |
1399 Element element = findElement('p'); | |
1400 // verify | |
1401 _assertRecordedRelationForElement(element, IndexConstants.IS_REFERENCED_BY, | |
1402 _expectedLocation(mainElement, 'p: 1')); | |
1403 } | |
1404 | |
1405 void test_isReferencedBy_PrefixElement() { | |
1406 _indexTestUnit(''' | |
1407 import 'dart:async' as ppp; | |
1408 main() { | |
1409 ppp.Future a; | |
1410 ppp.Stream b; | |
1411 } | |
1412 '''); | |
1413 // prepare elements | |
1414 PrefixElement element = findNodeElementAtString('ppp;'); | |
1415 Element elementA = findElement('a'); | |
1416 Element elementB = findElement('b'); | |
1417 IndexableElement indexable = new IndexableElement(element); | |
1418 // verify | |
1419 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1420 _expectedLocation(elementA, 'ppp.Future')); | |
1421 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1422 _expectedLocation(elementB, 'ppp.Stream')); | |
1423 _assertNoRecordedRelation(indexable, null, _expectedLocation(null, 'ppp;')); | |
1424 } | |
1425 | |
1426 void test_isReferencedBy_TopLevelVariableElement() { | |
1427 addSource( | |
1428 '/lib.dart', | |
1429 ''' | |
1430 library lib; | |
1431 var V; | |
1432 '''); | |
1433 _indexTestUnit(''' | |
1434 import 'lib.dart' show V; // imp | |
1435 import 'lib.dart' as pref; | |
1436 main() { | |
1437 pref.V = 5; // q | |
1438 print(pref.V); // q | |
1439 V = 5; // nq | |
1440 print(V); // nq | |
1441 }'''); | |
1442 // prepare elements | |
1443 TopLevelVariableElement variable = importedUnit().topLevelVariables[0]; | |
1444 Element mainElement = findElement("main"); | |
1445 IndexableElement indexableGetter = new IndexableElement(variable.getter); | |
1446 IndexableElement indexableSetter = new IndexableElement(variable.setter); | |
1447 // verify | |
1448 _assertRecordedRelationForElement(variable, IndexConstants.IS_REFERENCED_BY, | |
1449 _expectedLocation(testUnitElement, 'V; // imp')); | |
1450 _assertRecordedRelation(indexableSetter, IndexConstants.IS_REFERENCED_BY, | |
1451 _expectedLocation(mainElement, 'V = 5; // q')); | |
1452 _assertRecordedRelation(indexableGetter, IndexConstants.IS_REFERENCED_BY, | |
1453 _expectedLocation(mainElement, 'V); // q')); | |
1454 _assertRecordedRelation(indexableSetter, IndexConstants.IS_REFERENCED_BY, | |
1455 _expectedLocation(mainElement, 'V = 5; // nq')); | |
1456 _assertRecordedRelation(indexableGetter, IndexConstants.IS_REFERENCED_BY, | |
1457 _expectedLocation(mainElement, 'V); // nq')); | |
1458 } | |
1459 | |
1460 void test_isReferencedBy_typeInVariableList() { | |
1461 _indexTestUnit(''' | |
1462 class A {} | |
1463 A myVariable = null; | |
1464 '''); | |
1465 // prepare elements | |
1466 Element classElementA = findElement('A'); | |
1467 Element variableElement = findElement('myVariable'); | |
1468 // verify | |
1469 _assertRecordedRelationForElement( | |
1470 classElementA, | |
1471 IndexConstants.IS_REFERENCED_BY, | |
1472 _expectedLocation(variableElement, 'A myVariable')); | |
1473 } | |
1474 | |
1475 void test_isReferencedBy_TypeParameterElement() { | |
1476 _indexTestUnit(''' | |
1477 class A<T> { | |
1478 T f; | |
1479 foo(T p) { | |
1480 T v; | |
1481 } | |
1482 } | |
1483 '''); | |
1484 // prepare elements | |
1485 Element typeParameterElement = findElement('T'); | |
1486 Element fieldElement = findElement('f'); | |
1487 Element parameterElement = findElement('p'); | |
1488 Element variableElement = findElement('v'); | |
1489 IndexableElement indexable = new IndexableElement(typeParameterElement); | |
1490 // verify | |
1491 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1492 _expectedLocation(fieldElement, 'T f')); | |
1493 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1494 _expectedLocation(parameterElement, 'T p')); | |
1495 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
1496 _expectedLocation(variableElement, 'T v')); | |
1497 } | |
1498 | |
1499 void test_isWrittenBy_ConstructorFieldInitializer() { | |
1500 _indexTestUnit(''' | |
1501 class A { | |
1502 int field; | |
1503 A() : field = 5; | |
1504 } | |
1505 '''); | |
1506 // prepare elements | |
1507 ClassElement classElement = findElement('A'); | |
1508 ConstructorElement constructorElement = classElement.constructors[0]; | |
1509 FieldElement fieldElement = findElement("field"); | |
1510 // verify | |
1511 _assertRecordedRelationForElement( | |
1512 fieldElement, | |
1513 IndexConstants.IS_WRITTEN_BY, | |
1514 _expectedLocation(constructorElement, 'field = 5')); | |
1515 } | |
1516 | |
1517 void test_isWrittenBy_FieldElement_fieldFormalParameter() { | |
1518 _indexTestUnit(''' | |
1519 class A { | |
1520 int field; | |
1521 A(this.field); | |
1522 } | |
1523 '''); | |
1524 // prepare elements | |
1525 FieldElement fieldElement = findElement("field"); | |
1526 Element fieldParameterElement = findNodeElementAtString("field);"); | |
1527 // verify | |
1528 _assertRecordedRelationForElement( | |
1529 fieldElement, | |
1530 IndexConstants.IS_WRITTEN_BY, | |
1531 _expectedLocation(fieldParameterElement, 'field);')); | |
1532 } | |
1533 | |
1534 void test_isWrittenBy_ParameterElement() { | |
1535 _indexTestUnit(''' | |
1536 main(var p) { | |
1537 p = 1; | |
1538 }'''); | |
1539 // prepare elements | |
1540 Element mainElement = findElement("main"); | |
1541 ParameterElement pElement = findElement("p"); | |
1542 // verify | |
1543 _assertRecordedRelationForElement(pElement, IndexConstants.IS_WRITTEN_BY, | |
1544 _expectedLocation(mainElement, 'p = 1')); | |
1545 } | |
1546 | |
1547 void test_isWrittenBy_VariableElement() { | |
1548 _indexTestUnit(''' | |
1549 main() { | |
1550 var v = 0; | |
1551 v = 1; | |
1552 }'''); | |
1553 // prepare elements | |
1554 Element mainElement = findElement("main"); | |
1555 LocalVariableElement vElement = findElement("v"); | |
1556 // verify | |
1557 _assertRecordedRelationForElement(vElement, IndexConstants.IS_WRITTEN_BY, | |
1558 _expectedLocation(mainElement, 'v = 1')); | |
1559 } | |
1560 | |
1561 void test_nameIsInvokedBy() { | |
1562 _indexTestUnit(''' | |
1563 class A { | |
1564 test(x) {} | |
1565 } | |
1566 main(A a, p) { | |
1567 a.test(1); | |
1568 p.test(2); | |
1569 }'''); | |
1570 // prepare elements | |
1571 Element mainElement = findElement("main"); | |
1572 IndexableName indexable = new IndexableName('test'); | |
1573 // verify | |
1574 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
1575 _expectedLocationQ(mainElement, 'test(1)')); | |
1576 _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY, | |
1577 _expectedLocationQU(mainElement, 'test(2)')); | |
1578 _assertNoRecordedRelation(indexable, IndexConstants.IS_READ_BY, | |
1579 _expectedLocationQU(mainElement, 'test(2)')); | |
1580 } | |
1581 | |
1582 void test_nameIsReadBy() { | |
1583 _indexTestUnit(''' | |
1584 class A { | |
1585 var test; | |
1586 } | |
1587 main(A a, p) { | |
1588 print(a.test); // a | |
1589 print(p.test); // p | |
1590 }'''); | |
1591 // prepare elements | |
1592 Element mainElement = findElement("main"); | |
1593 IndexableName indexable = new IndexableName('test'); | |
1594 // verify | |
1595 _assertRecordedRelation(indexable, IndexConstants.IS_READ_BY, | |
1596 _expectedLocationQ(mainElement, 'test); // a')); | |
1597 _assertRecordedRelation(indexable, IndexConstants.IS_READ_BY, | |
1598 _expectedLocationQU(mainElement, 'test); // p')); | |
1599 } | |
1600 | |
1601 void test_nameIsReadWrittenBy() { | |
1602 _indexTestUnit(''' | |
1603 class A { | |
1604 var test; | |
1605 } | |
1606 main(A a, p) { | |
1607 a.test += 1; | |
1608 p.test += 2; | |
1609 }'''); | |
1610 // prepare elements | |
1611 Element mainElement = findElement("main"); | |
1612 IndexableName indexable = new IndexableName('test'); | |
1613 // verify | |
1614 _assertRecordedRelation(indexable, IndexConstants.IS_READ_WRITTEN_BY, | |
1615 _expectedLocationQ(mainElement, 'test += 1')); | |
1616 _assertRecordedRelation(indexable, IndexConstants.IS_READ_WRITTEN_BY, | |
1617 _expectedLocationQU(mainElement, 'test += 2')); | |
1618 } | |
1619 | |
1620 void test_nameIsWrittenBy() { | |
1621 _indexTestUnit(''' | |
1622 class A { | |
1623 var test; | |
1624 } | |
1625 main(A a, p) { | |
1626 a.test = 1; | |
1627 p.test = 2; | |
1628 }'''); | |
1629 // prepare elements | |
1630 Element mainElement = findElement("main"); | |
1631 IndexableName indexable = new IndexableName('test'); | |
1632 // verify | |
1633 _assertRecordedRelation(indexable, IndexConstants.IS_WRITTEN_BY, | |
1634 _expectedLocationQ(mainElement, 'test = 1')); | |
1635 _assertRecordedRelation(indexable, IndexConstants.IS_WRITTEN_BY, | |
1636 _expectedLocationQU(mainElement, 'test = 2')); | |
1637 } | |
1638 | |
1639 void test_nullUnit() { | |
1640 indexDartUnit(store, context, null); | |
1641 } | |
1642 | |
1643 void test_nullUnitElement() { | |
1644 CompilationUnit unit = new CompilationUnit(null, null, [], [], null); | |
1645 indexDartUnit(store, context, unit); | |
1646 } | |
1647 | |
1648 void _assertDefinesTopLevelElement(Element element) { | |
1649 ExpectedLocation location = new ExpectedLocation( | |
1650 new IndexableElement(element), | |
1651 element.nameOffset, | |
1652 element.nameLength, | |
1653 false, | |
1654 true); | |
1655 _assertRecordedRelationForElement( | |
1656 testLibraryElement, IndexConstants.DEFINES, location); | |
1657 expect(recordedTopElements, contains(element)); | |
1658 } | |
1659 | |
1660 /** | |
1661 * Asserts that [recordedRelations] has no item with the specified properties. | |
1662 */ | |
1663 void _assertNoRecordedRelation(IndexableObject expectedIndexable, | |
1664 RelationshipImpl relationship, ExpectedLocation location) { | |
1665 for (RecordedRelation recordedRelation in recordedRelations) { | |
1666 if (_equalsRecordedRelation( | |
1667 recordedRelation, expectedIndexable, relationship, location)) { | |
1668 fail('not expected: $recordedRelation in\n' + | |
1669 recordedRelations.join('\n')); | |
1670 } | |
1671 } | |
1672 } | |
1673 | |
1674 /** | |
1675 * Asserts that [recordedRelations] has no item with the specified properties. | |
1676 */ | |
1677 void _assertNoRecordedRelationForElement(Element expectedElement, | |
1678 RelationshipImpl relationship, ExpectedLocation location) { | |
1679 _assertNoRecordedRelation( | |
1680 new IndexableElement(expectedElement), relationship, location); | |
1681 } | |
1682 | |
1683 /** | |
1684 * Asserts that [recordedRelations] has an item with the expected properties. | |
1685 */ | |
1686 LocationImpl _assertRecordedRelation( | |
1687 IndexableObject expectedIndexable, | |
1688 RelationshipImpl expectedRelationship, | |
1689 ExpectedLocation expectedLocation) { | |
1690 for (RecordedRelation recordedRelation in recordedRelations) { | |
1691 if (_equalsRecordedRelation(recordedRelation, expectedIndexable, | |
1692 expectedRelationship, expectedLocation)) { | |
1693 return recordedRelation.location; | |
1694 } | |
1695 } | |
1696 fail("not found\n$expectedIndexable $expectedRelationship " | |
1697 "in $expectedLocation in\n" + | |
1698 recordedRelations.join('\n')); | |
1699 return null; | |
1700 } | |
1701 | |
1702 /** | |
1703 * Asserts that [recordedRelations] has an item with the expected properties. | |
1704 */ | |
1705 LocationImpl _assertRecordedRelationForElement( | |
1706 Element expectedElement, | |
1707 RelationshipImpl expectedRelationship, | |
1708 ExpectedLocation expectedLocation) { | |
1709 return _assertRecordedRelationForIndexable( | |
1710 new IndexableElement(expectedElement), | |
1711 expectedRelationship, | |
1712 expectedLocation); | |
1713 } | |
1714 | |
1715 /** | |
1716 * Asserts that [recordedRelations] has an item with the expected properties. | |
1717 */ | |
1718 LocationImpl _assertRecordedRelationForIndexable( | |
1719 IndexableObject expectedIndexable, | |
1720 RelationshipImpl expectedRelationship, | |
1721 ExpectedLocation expectedLocation) { | |
1722 return _assertRecordedRelation( | |
1723 expectedIndexable, expectedRelationship, expectedLocation); | |
1724 } | |
1725 | |
1726 /** | |
1727 * Asserts that [recordedRelations] has an item with the expected properties. | |
1728 */ | |
1729 LocationImpl _assertRecordedRelationForName( | |
1730 String expectedName, | |
1731 RelationshipImpl expectedRelationship, | |
1732 ExpectedLocation expectedLocation) { | |
1733 return _assertRecordedRelationForIndexable(new IndexableName(expectedName), | |
1734 expectedRelationship, expectedLocation); | |
1735 } | |
1736 | |
1737 ExpectedLocation _expectedLocation(Element element, String search, | |
1738 {int length: -1, bool isQualified: false, bool isResolved: true}) { | |
1739 int offset = findOffset(search); | |
1740 if (length == -1) { | |
1741 length = getLeadingIdentifierLength(search); | |
1742 } | |
1743 IndexableObject indexable = | |
1744 element != null ? new IndexableElement(element) : null; | |
1745 return new ExpectedLocation( | |
1746 indexable, offset, length, isQualified, isResolved); | |
1747 } | |
1748 | |
1749 ExpectedLocation _expectedLocationQ(Element element, String search, | |
1750 {int length: -1}) { | |
1751 return _expectedLocation(element, search, | |
1752 length: length, isQualified: true); | |
1753 } | |
1754 | |
1755 ExpectedLocation _expectedLocationQU(Element element, String search, | |
1756 {int length: -1}) { | |
1757 return _expectedLocation(element, search, | |
1758 length: length, isQualified: true, isResolved: false); | |
1759 } | |
1760 | |
1761 void _indexTestUnit(String code) { | |
1762 resolveTestUnit(code); | |
1763 indexDartUnit(store, context, testUnit); | |
1764 } | |
1765 } | |
1766 | |
1767 class ExpectedLocation { | |
1768 IndexableObject indexable; | |
1769 int offset; | |
1770 int length; | |
1771 bool isQualified; | |
1772 bool isResolved; | |
1773 | |
1774 ExpectedLocation(this.indexable, this.offset, this.length, this.isQualified, | |
1775 this.isResolved); | |
1776 | |
1777 @override | |
1778 String toString() { | |
1779 return 'ExpectedLocation(indexable=$indexable; offset=$offset; length=$lengt
h;' | |
1780 ' isQualified=$isQualified isResolved=$isResolved)'; | |
1781 } | |
1782 } | |
1783 | |
1784 class MockIndexStore extends TypedMock implements InternalIndexStore {} | |
1785 | |
1786 /** | |
1787 * Information about a relation recorded into {@link IndexStore}. | |
1788 */ | |
1789 class RecordedRelation { | |
1790 final IndexableObject indexable; | |
1791 final RelationshipImpl relationship; | |
1792 final LocationImpl location; | |
1793 | |
1794 RecordedRelation(this.indexable, this.relationship, this.location); | |
1795 | |
1796 @override | |
1797 String toString() { | |
1798 return 'RecordedRelation(indexable=$indexable; relationship=$relationship; ' | |
1799 'location=$location; flags=' | |
1800 '${location.isQualified ? "Q" : ""}' | |
1801 '${location.isResolved ? "R" : ""})'; | |
1802 } | |
1803 } | |
OLD | NEW |