| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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 library test.services.src.index.dart_index_contributor; | 5 library test.services.src.index.dart_index_contributor; |
| 6 | 6 |
| 7 import 'package:analysis_server/src/services/index/index.dart'; | 7 import 'package:analysis_server/src/services/index/index.dart'; |
| 8 import 'package:analysis_server/src/services/index/index_contributor.dart'; | 8 import 'package:analysis_server/src/services/index/index_contributor.dart'; |
| 9 import 'package:analysis_server/src/services/index/index_store.dart'; | 9 import 'package:analysis_server/src/services/index/index_store.dart'; |
| 10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 ExpectedLocation expectedLocation) { | 46 ExpectedLocation expectedLocation) { |
| 47 return expectedElement == recordedRelation.element && | 47 return expectedElement == recordedRelation.element && |
| 48 (expectedRelationship == null || | 48 (expectedRelationship == null || |
| 49 expectedRelationship == recordedRelation.relationship) && | 49 expectedRelationship == recordedRelation.relationship) && |
| 50 (expectedLocation == null || | 50 (expectedLocation == null || |
| 51 _equalsLocation(recordedRelation.location, expectedLocation)); | 51 _equalsLocation(recordedRelation.location, expectedLocation)); |
| 52 } | 52 } |
| 53 | 53 |
| 54 @reflectiveTest | 54 @reflectiveTest |
| 55 class DartUnitContributorTest extends AbstractSingleUnitTest { | 55 class DartUnitContributorTest extends AbstractSingleUnitTest { |
| 56 IndexStore store = new MockIndexStore(); | 56 InternalIndexStore store = new MockIndexStore(); |
| 57 List<RecordedRelation> recordedRelations = <RecordedRelation>[]; | 57 List<RecordedRelation> recordedRelations = <RecordedRelation>[]; |
| 58 List<Element> recordedTopElements = <Element>[]; | 58 List<Element> recordedTopElements = <Element>[]; |
| 59 | 59 |
| 60 CompilationUnitElement importedUnit({int index: 0}) { | 60 CompilationUnitElement importedUnit({int index: 0}) { |
| 61 List<ImportElement> imports = testLibraryElement.imports; | 61 List<ImportElement> imports = testLibraryElement.imports; |
| 62 return imports[index].importedLibrary.definingCompilationUnit; | 62 return imports[index].importedLibrary.definingCompilationUnit; |
| 63 } | 63 } |
| 64 | 64 |
| 65 void setUp() { | 65 void setUp() { |
| 66 super.setUp(); | 66 super.setUp(); |
| 67 when(store.aboutToIndexDart(context, anyObject)).thenReturn(true); | 67 when(store.aboutToIndexDart(context, anyObject)).thenReturn(true); |
| 68 when(store.recordRelationship(anyObject, anyObject, anyObject)).thenInvoke( | 68 when(store.recordRelationship(anyObject, anyObject, anyObject)).thenInvoke( |
| 69 (Element element, Relationship relationship, Location location) { | 69 (Element element, Relationship relationship, Location location) { |
| 70 recordedRelations | 70 recordedRelations |
| 71 .add(new RecordedRelation(element, relationship, location)); | 71 .add(new RecordedRelation(element, relationship, location)); |
| 72 }); | 72 }); |
| 73 when(store.recordTopLevelDeclaration(anyObject)).thenInvoke((Element element
) { | 73 when(store.recordTopLevelDeclaration(anyObject)) |
| 74 .thenInvoke((Element element) { |
| 74 recordedTopElements.add(element); | 75 recordedTopElements.add(element); |
| 75 }); | 76 }); |
| 76 } | 77 } |
| 77 | 78 |
| 78 void test_definesClass() { | 79 void test_definesClass() { |
| 79 _indexTestUnit('class A {}'); | 80 _indexTestUnit('class A {}'); |
| 80 // prepare elements | 81 // prepare elements |
| 81 ClassElement classElement = findElement("A"); | 82 ClassElement classElement = findElement("A"); |
| 82 // verify | 83 // verify |
| 83 _assertDefinesTopLevelElement(classElement); | 84 _assertDefinesTopLevelElement(classElement); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 void test_forIn() { | 129 void test_forIn() { |
| 129 _indexTestUnit(''' | 130 _indexTestUnit(''' |
| 130 main() { | 131 main() { |
| 131 for (var v in []) { | 132 for (var v in []) { |
| 132 } | 133 } |
| 133 }'''); | 134 }'''); |
| 134 // prepare elements | 135 // prepare elements |
| 135 Element mainElement = findElement("main"); | 136 Element mainElement = findElement("main"); |
| 136 VariableElement variableElement = findElement("v"); | 137 VariableElement variableElement = findElement("v"); |
| 137 // verify | 138 // verify |
| 138 _assertNoRecordedRelation(variableElement, | 139 _assertNoRecordedRelation(variableElement, IndexConstants.IS_READ_BY, |
| 139 IndexConstants.IS_READ_BY, _expectedLocation(mainElement, 'v in []')); | 140 _expectedLocation(mainElement, 'v in []')); |
| 140 } | 141 } |
| 141 | 142 |
| 142 void test_isDefinedBy_NameElement_method() { | 143 void test_isDefinedBy_NameElement_method() { |
| 143 _indexTestUnit(''' | 144 _indexTestUnit(''' |
| 144 class A { | 145 class A { |
| 145 m() {} | 146 m() {} |
| 146 }'''); | 147 }'''); |
| 147 // prepare elements | 148 // prepare elements |
| 148 Element methodElement = findElement("m"); | 149 Element methodElement = findElement("m"); |
| 149 Element nameElement = new NameElement("m"); | 150 Element nameElement = new NameElement("m"); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 void test_isInvokedBy_LocalVariableElement() { | 277 void test_isInvokedBy_LocalVariableElement() { |
| 277 _indexTestUnit(''' | 278 _indexTestUnit(''' |
| 278 main() { | 279 main() { |
| 279 var v; | 280 var v; |
| 280 v(); | 281 v(); |
| 281 }'''); | 282 }'''); |
| 282 // prepare elements | 283 // prepare elements |
| 283 Element mainElement = findElement("main"); | 284 Element mainElement = findElement("main"); |
| 284 Element element = findElement("v"); | 285 Element element = findElement("v"); |
| 285 // verify | 286 // verify |
| 286 _assertRecordedRelation(element, | 287 _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY, |
| 287 IndexConstants.IS_INVOKED_BY, _expectedLocation(mainElement, 'v();')); | 288 _expectedLocation(mainElement, 'v();')); |
| 288 } | 289 } |
| 289 | 290 |
| 290 void test_isInvokedBy_MethodElement() { | 291 void test_isInvokedBy_MethodElement() { |
| 291 _indexTestUnit(''' | 292 _indexTestUnit(''' |
| 292 class A { | 293 class A { |
| 293 foo() {} | 294 foo() {} |
| 294 main() { | 295 main() { |
| 295 this.foo(); // q | 296 this.foo(); // q |
| 296 foo(); // nq | 297 foo(); // nq |
| 297 } | 298 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 | 392 |
| 392 void test_isInvokedBy_ParameterElement() { | 393 void test_isInvokedBy_ParameterElement() { |
| 393 _indexTestUnit(''' | 394 _indexTestUnit(''' |
| 394 main(p()) { | 395 main(p()) { |
| 395 p(); | 396 p(); |
| 396 }'''); | 397 }'''); |
| 397 // prepare elements | 398 // prepare elements |
| 398 Element mainElement = findElement("main"); | 399 Element mainElement = findElement("main"); |
| 399 Element element = findElement("p"); | 400 Element element = findElement("p"); |
| 400 // verify | 401 // verify |
| 401 _assertRecordedRelation(element, | 402 _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY, |
| 402 IndexConstants.IS_INVOKED_BY, _expectedLocation(mainElement, 'p();')); | 403 _expectedLocation(mainElement, 'p();')); |
| 403 } | 404 } |
| 404 | 405 |
| 405 void test_isMixedInBy_ClassDeclaration() { | 406 void test_isMixedInBy_ClassDeclaration() { |
| 406 _indexTestUnit(''' | 407 _indexTestUnit(''' |
| 407 class A {} // 1 | 408 class A {} // 1 |
| 408 class B extends Object with A {} // 2 | 409 class B extends Object with A {} // 2 |
| 409 '''); | 410 '''); |
| 410 // prepare elements | 411 // prepare elements |
| 411 ClassElement classElementA = findElement("A"); | 412 ClassElement classElementA = findElement("A"); |
| 412 ClassElement classElementB = findElement("B"); | 413 ClassElement classElementB = findElement("B"); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 431 void test_isReadBy_ParameterElement() { | 432 void test_isReadBy_ParameterElement() { |
| 432 _indexTestUnit(''' | 433 _indexTestUnit(''' |
| 433 main(var p) { | 434 main(var p) { |
| 434 print(p); | 435 print(p); |
| 435 } | 436 } |
| 436 '''); | 437 '''); |
| 437 // prepare elements | 438 // prepare elements |
| 438 Element mainElement = findElement("main"); | 439 Element mainElement = findElement("main"); |
| 439 Element parameterElement = findElement("p"); | 440 Element parameterElement = findElement("p"); |
| 440 // verify | 441 // verify |
| 441 _assertRecordedRelation(parameterElement, | 442 _assertRecordedRelation(parameterElement, IndexConstants.IS_READ_BY, |
| 442 IndexConstants.IS_READ_BY, _expectedLocation(mainElement, 'p);')); | 443 _expectedLocation(mainElement, 'p);')); |
| 443 } | 444 } |
| 444 | 445 |
| 445 void test_isReadBy_VariableElement() { | 446 void test_isReadBy_VariableElement() { |
| 446 _indexTestUnit(''' | 447 _indexTestUnit(''' |
| 447 main() { | 448 main() { |
| 448 var v = 0; | 449 var v = 0; |
| 449 print(v); | 450 print(v); |
| 450 } | 451 } |
| 451 '''); | 452 '''); |
| 452 // prepare elements | 453 // prepare elements |
| 453 Element mainElement = findElement("main"); | 454 Element mainElement = findElement("main"); |
| 454 Element variableElement = findElement("v"); | 455 Element variableElement = findElement("v"); |
| 455 // verify | 456 // verify |
| 456 _assertRecordedRelation(variableElement, | 457 _assertRecordedRelation(variableElement, IndexConstants.IS_READ_BY, |
| 457 IndexConstants.IS_READ_BY, _expectedLocation(mainElement, 'v);')); | 458 _expectedLocation(mainElement, 'v);')); |
| 458 } | 459 } |
| 459 | 460 |
| 460 void test_isReadWrittenBy_ParameterElement() { | 461 void test_isReadWrittenBy_ParameterElement() { |
| 461 _indexTestUnit(''' | 462 _indexTestUnit(''' |
| 462 main(int p) { | 463 main(int p) { |
| 463 p += 1; | 464 p += 1; |
| 464 } | 465 } |
| 465 '''); | 466 '''); |
| 466 // prepare elements | 467 // prepare elements |
| 467 Element mainElement = findElement("main"); | 468 Element mainElement = findElement("main"); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 497 A.field = 1; | 498 A.field = 1; |
| 498 print(A.field); // 3 | 499 print(A.field); // 3 |
| 499 } | 500 } |
| 500 '''); | 501 '''); |
| 501 // prepare elements | 502 // prepare elements |
| 502 ClassElement aElement = findElement("A"); | 503 ClassElement aElement = findElement("A"); |
| 503 Element mainElement = findElement("main"); | 504 Element mainElement = findElement("main"); |
| 504 ParameterElement pElement = findElement("p"); | 505 ParameterElement pElement = findElement("p"); |
| 505 VariableElement vElement = findElement("v"); | 506 VariableElement vElement = findElement("v"); |
| 506 // verify | 507 // verify |
| 507 _assertRecordedRelation(aElement, | 508 _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY, |
| 508 IndexConstants.IS_REFERENCED_BY, _expectedLocation(pElement, 'A p) {')); | 509 _expectedLocation(pElement, 'A p) {')); |
| 509 _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY, | 510 _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY, |
| 510 _expectedLocation(vElement, 'A v;')); | 511 _expectedLocation(vElement, 'A v;')); |
| 511 _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY, | 512 _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY, |
| 512 _expectedLocation(mainElement, 'A(); // 2')); | 513 _expectedLocation(mainElement, 'A(); // 2')); |
| 513 _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY, | 514 _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY, |
| 514 _expectedLocation(mainElement, 'A.field = 1;')); | 515 _expectedLocation(mainElement, 'A.field = 1;')); |
| 515 _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY, | 516 _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY, |
| 516 _expectedLocation(mainElement, 'A.field); // 3')); | 517 _expectedLocation(mainElement, 'A.field); // 3')); |
| 517 } | 518 } |
| 518 | 519 |
| 519 void test_isReferencedBy_ClassTypeAlias() { | 520 void test_isReferencedBy_ClassTypeAlias() { |
| 520 _indexTestUnit(''' | 521 _indexTestUnit(''' |
| 521 class A {} | 522 class A {} |
| 522 class B = Object with A; | 523 class B = Object with A; |
| 523 main(B p) { | 524 main(B p) { |
| 524 B v; | 525 B v; |
| 525 } | 526 } |
| 526 '''); | 527 '''); |
| 527 // prepare elements | 528 // prepare elements |
| 528 ClassElement bElement = findElement("B"); | 529 ClassElement bElement = findElement("B"); |
| 529 ParameterElement pElement = findElement("p"); | 530 ParameterElement pElement = findElement("p"); |
| 530 VariableElement vElement = findElement("v"); | 531 VariableElement vElement = findElement("v"); |
| 531 // verify | 532 // verify |
| 532 _assertRecordedRelation(bElement, | 533 _assertRecordedRelation(bElement, IndexConstants.IS_REFERENCED_BY, |
| 533 IndexConstants.IS_REFERENCED_BY, _expectedLocation(pElement, 'B p) {')); | 534 _expectedLocation(pElement, 'B p) {')); |
| 534 _assertRecordedRelation(bElement, IndexConstants.IS_REFERENCED_BY, | 535 _assertRecordedRelation(bElement, IndexConstants.IS_REFERENCED_BY, |
| 535 _expectedLocation(vElement, 'B v;')); | 536 _expectedLocation(vElement, 'B v;')); |
| 536 } | 537 } |
| 537 | 538 |
| 538 void test_isReferencedBy_CompilationUnitElement_export() { | 539 void test_isReferencedBy_CompilationUnitElement_export() { |
| 539 addSource('/lib.dart', ''' | 540 addSource('/lib.dart', ''' |
| 540 library lib; | 541 library lib; |
| 541 '''); | 542 '''); |
| 542 _indexTestUnit(''' | 543 _indexTestUnit(''' |
| 543 export 'lib.dart'; | 544 export 'lib.dart'; |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 void test_isReferencedBy_FunctionTypeAliasElement() { | 733 void test_isReferencedBy_FunctionTypeAliasElement() { |
| 733 _indexTestUnit(''' | 734 _indexTestUnit(''' |
| 734 typedef A(); | 735 typedef A(); |
| 735 main(A p) { | 736 main(A p) { |
| 736 } | 737 } |
| 737 '''); | 738 '''); |
| 738 // prepare elements | 739 // prepare elements |
| 739 Element aElement = findElement('A'); | 740 Element aElement = findElement('A'); |
| 740 Element pElement = findElement('p'); | 741 Element pElement = findElement('p'); |
| 741 // verify | 742 // verify |
| 742 _assertRecordedRelation(aElement, | 743 _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY, |
| 743 IndexConstants.IS_REFERENCED_BY, _expectedLocation(pElement, 'A p) {')); | 744 _expectedLocation(pElement, 'A p) {')); |
| 744 } | 745 } |
| 745 | 746 |
| 746 /** | 747 /** |
| 747 * There was a bug in the AST structure, when single [Comment] was cloned and | 748 * There was a bug in the AST structure, when single [Comment] was cloned and |
| 748 * assigned to both [FieldDeclaration] and [VariableDeclaration]. | 749 * assigned to both [FieldDeclaration] and [VariableDeclaration]. |
| 749 * | 750 * |
| 750 * This caused duplicate indexing. | 751 * This caused duplicate indexing. |
| 751 * Here we test that the problem is fixed one way or another. | 752 * Here we test that the problem is fixed one way or another. |
| 752 */ | 753 */ |
| 753 void test_isReferencedBy_identifierInComment() { | 754 void test_isReferencedBy_identifierInComment() { |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 main() { | 932 main() { |
| 932 L: while (true) { | 933 L: while (true) { |
| 933 break L; | 934 break L; |
| 934 } | 935 } |
| 935 } | 936 } |
| 936 '''); | 937 '''); |
| 937 // prepare elements | 938 // prepare elements |
| 938 Element mainElement = findElement('main'); | 939 Element mainElement = findElement('main'); |
| 939 Element element = findElement('L'); | 940 Element element = findElement('L'); |
| 940 // verify | 941 // verify |
| 941 _assertRecordedRelation(element, | 942 _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY, |
| 942 IndexConstants.IS_REFERENCED_BY, _expectedLocation(mainElement, 'L;')); | 943 _expectedLocation(mainElement, 'L;')); |
| 943 } | 944 } |
| 944 | 945 |
| 945 void test_isReferencedBy_libraryName() { | 946 void test_isReferencedBy_libraryName() { |
| 946 Source libSource = addSource('/lib.dart', ''' | 947 Source libSource = addSource('/lib.dart', ''' |
| 947 library lib; | 948 library lib; |
| 948 part 'test.dart'; | 949 part 'test.dart'; |
| 949 '''); | 950 '''); |
| 950 testCode = 'part of lib;'; | 951 testCode = 'part of lib;'; |
| 951 testSource = addSource('/test.dart', testCode); | 952 testSource = addSource('/test.dart', testCode); |
| 952 testUnit = resolveDartUnit(testSource, libSource); | 953 testUnit = resolveDartUnit(testSource, libSource); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1114 | 1115 |
| 1115 void test_isWrittenBy_ParameterElement() { | 1116 void test_isWrittenBy_ParameterElement() { |
| 1116 _indexTestUnit(''' | 1117 _indexTestUnit(''' |
| 1117 main(var p) { | 1118 main(var p) { |
| 1118 p = 1; | 1119 p = 1; |
| 1119 }'''); | 1120 }'''); |
| 1120 // prepare elements | 1121 // prepare elements |
| 1121 Element mainElement = findElement("main"); | 1122 Element mainElement = findElement("main"); |
| 1122 ParameterElement pElement = findElement("p"); | 1123 ParameterElement pElement = findElement("p"); |
| 1123 // verify | 1124 // verify |
| 1124 _assertRecordedRelation(pElement, | 1125 _assertRecordedRelation(pElement, IndexConstants.IS_WRITTEN_BY, |
| 1125 IndexConstants.IS_WRITTEN_BY, _expectedLocation(mainElement, 'p = 1')); | 1126 _expectedLocation(mainElement, 'p = 1')); |
| 1126 } | 1127 } |
| 1127 | 1128 |
| 1128 void test_isWrittenBy_VariableElement() { | 1129 void test_isWrittenBy_VariableElement() { |
| 1129 _indexTestUnit(''' | 1130 _indexTestUnit(''' |
| 1130 main() { | 1131 main() { |
| 1131 var v = 0; | 1132 var v = 0; |
| 1132 v = 1; | 1133 v = 1; |
| 1133 }'''); | 1134 }'''); |
| 1134 // prepare elements | 1135 // prepare elements |
| 1135 Element mainElement = findElement("main"); | 1136 Element mainElement = findElement("main"); |
| 1136 LocalVariableElement vElement = findElement("v"); | 1137 LocalVariableElement vElement = findElement("v"); |
| 1137 // verify | 1138 // verify |
| 1138 _assertRecordedRelation(vElement, | 1139 _assertRecordedRelation(vElement, IndexConstants.IS_WRITTEN_BY, |
| 1139 IndexConstants.IS_WRITTEN_BY, _expectedLocation(mainElement, 'v = 1')); | 1140 _expectedLocation(mainElement, 'v = 1')); |
| 1140 } | 1141 } |
| 1141 | 1142 |
| 1142 void test_NameElement_field() { | 1143 void test_NameElement_field() { |
| 1143 _indexTestUnit(''' | 1144 _indexTestUnit(''' |
| 1144 class A { | 1145 class A { |
| 1145 int field; | 1146 int field; |
| 1146 } | 1147 } |
| 1147 main(A a, p) { | 1148 main(A a, p) { |
| 1148 print(a.field); // r | 1149 print(a.field); // r |
| 1149 print(p.field); // ur | 1150 print(p.field); // ur |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 ExpectedLocation(this.element, this.offset, this.length, this.isQualified, | 1457 ExpectedLocation(this.element, this.offset, this.length, this.isQualified, |
| 1457 this.isResolved); | 1458 this.isResolved); |
| 1458 | 1459 |
| 1459 @override | 1460 @override |
| 1460 String toString() { | 1461 String toString() { |
| 1461 return 'ExpectedLocation(element=$element; offset=$offset; length=$length;' | 1462 return 'ExpectedLocation(element=$element; offset=$offset; length=$length;' |
| 1462 ' isQualified=$isQualified isResolved=$isResolved)'; | 1463 ' isQualified=$isQualified isResolved=$isResolved)'; |
| 1463 } | 1464 } |
| 1464 } | 1465 } |
| 1465 | 1466 |
| 1466 class MockIndexStore extends TypedMock implements IndexStore { | 1467 class MockIndexStore extends TypedMock implements InternalIndexStore { |
| 1467 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 1468 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 1468 } | 1469 } |
| 1469 | 1470 |
| 1470 /** | 1471 /** |
| 1471 * Information about a relation recorded into {@link IndexStore}. | 1472 * Information about a relation recorded into {@link IndexStore}. |
| 1472 */ | 1473 */ |
| 1473 class RecordedRelation { | 1474 class RecordedRelation { |
| 1474 final Element element; | 1475 final Element element; |
| 1475 final Relationship relationship; | 1476 final Relationship relationship; |
| 1476 final Location location; | 1477 final Location location; |
| 1477 | 1478 |
| 1478 RecordedRelation(this.element, this.relationship, this.location); | 1479 RecordedRelation(this.element, this.relationship, this.location); |
| 1479 | 1480 |
| 1480 @override | 1481 @override |
| 1481 String toString() { | 1482 String toString() { |
| 1482 return 'RecordedRelation(element=$element; relationship=$relationship; ' | 1483 return 'RecordedRelation(element=$element; relationship=$relationship; ' |
| 1483 'location=$location; flags=' '${location.isQualified ? "Q" : ""}' | 1484 'location=$location; flags=' '${location.isQualified ? "Q" : ""}' |
| 1484 '${location.isResolved ? "R" : ""})'; | 1485 '${location.isResolved ? "R" : ""})'; |
| 1485 } | 1486 } |
| 1486 } | 1487 } |
| OLD | NEW |