Chromium Code Reviews| 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 |