| 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/plugin/index/index_core.dart'; | 7 import 'package:analysis_server/plugin/index/index_core.dart'; |
| 8 import 'package:analysis_server/src/services/index/index.dart'; | 8 import 'package:analysis_server/src/services/index/index.dart'; |
| 9 import 'package:analysis_server/src/services/index/index_contributor.dart'; | 9 import 'package:analysis_server/src/services/index/index_contributor.dart'; |
| 10 import 'package:analysis_server/src/services/index/index_store.dart'; | 10 import 'package:analysis_server/src/services/index/index_store.dart'; |
| 11 import 'package:analysis_server/src/services/index/indexable_element.dart'; | 11 import 'package:analysis_server/src/services/index/indexable_element.dart'; |
| 12 import 'package:analysis_server/src/services/index/indexable_file.dart'; |
| 12 import 'package:analyzer/src/generated/ast.dart'; | 13 import 'package:analyzer/src/generated/ast.dart'; |
| 13 import 'package:analyzer/src/generated/element.dart'; | 14 import 'package:analyzer/src/generated/element.dart'; |
| 14 import 'package:analyzer/src/generated/engine.dart'; | 15 import 'package:analyzer/src/generated/engine.dart'; |
| 15 import 'package:analyzer/src/generated/source.dart'; | 16 import 'package:analyzer/src/generated/source.dart'; |
| 16 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 17 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 17 import 'package:typed_mock/typed_mock.dart'; | 18 import 'package:typed_mock/typed_mock.dart'; |
| 18 import 'package:unittest/unittest.dart'; | 19 import 'package:unittest/unittest.dart'; |
| 19 | 20 |
| 20 import '../../abstract_single_unit.dart'; | 21 import '../../abstract_single_unit.dart'; |
| 21 import '../../utils.dart'; | 22 import '../../utils.dart'; |
| 22 | 23 |
| 23 main() { | 24 main() { |
| 24 initializeTestEnvironment(); | 25 initializeTestEnvironment(); |
| 25 defineReflectiveTests(DartUnitContributorTest); | 26 defineReflectiveTests(DartUnitContributorTest); |
| 26 } | 27 } |
| 27 | 28 |
| 28 void indexDartUnit( | 29 void indexDartUnit( |
| 29 InternalIndexStore store, AnalysisContext context, CompilationUnit unit) { | 30 InternalIndexStore store, AnalysisContext context, CompilationUnit unit) { |
| 30 new DartIndexContributor().contributeTo(store, context, unit); | 31 new DartIndexContributor().contributeTo(store, context, unit); |
| 31 } | 32 } |
| 32 | 33 |
| 33 /** | 34 /** |
| 34 * Returns `true` if the [actual] location the same properties as [expected]. | 35 * Returns `true` if the [actual] location the same properties as [expected]. |
| 35 */ | 36 */ |
| 36 bool _equalsLocation(LocationImpl actual, ExpectedLocation expected) { | 37 bool _equalsLocation(LocationImpl actual, ExpectedLocation expected) { |
| 37 return _equalsLocationProperties(actual, expected.element, expected.offset, | 38 return _equalsLocationProperties(actual, expected.indexable, expected.offset, |
| 38 expected.length, expected.isQualified, expected.isResolved); | 39 expected.length, expected.isQualified, expected.isResolved); |
| 39 } | 40 } |
| 40 | 41 |
| 41 /** | 42 /** |
| 42 * Returns `true` if the [actual] location the expected properties. | 43 * Returns `true` if the [actual] location the expected properties. |
| 43 */ | 44 */ |
| 44 bool _equalsLocationProperties(LocationImpl actual, Element expectedElement, | 45 bool _equalsLocationProperties( |
| 45 int expectedOffset, int expectedLength, bool isQualified, bool isResolved) { | 46 LocationImpl actual, |
| 46 return (expectedElement == null || expectedElement == actual.element) && | 47 IndexableObject expectedIndexable, |
| 48 int expectedOffset, |
| 49 int expectedLength, |
| 50 bool isQualified, |
| 51 bool isResolved) { |
| 52 return (expectedIndexable == null || expectedIndexable == actual.indexable) && |
| 47 expectedOffset == actual.offset && | 53 expectedOffset == actual.offset && |
| 48 expectedLength == actual.length && | 54 expectedLength == actual.length && |
| 49 isQualified == actual.isQualified && | 55 isQualified == actual.isQualified && |
| 50 isResolved == actual.isResolved; | 56 isResolved == actual.isResolved; |
| 51 } | 57 } |
| 52 | 58 |
| 53 bool _equalsRecordedRelation( | 59 bool _equalsRecordedRelation( |
| 54 RecordedRelation recordedRelation, | 60 RecordedRelation recordedRelation, |
| 55 IndexableObject expectedIndexable, | 61 IndexableObject expectedIndexable, |
| 56 RelationshipImpl expectedRelationship, | 62 RelationshipImpl expectedRelationship, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 81 LocationImpl location) { | 87 LocationImpl location) { |
| 82 recordedRelations | 88 recordedRelations |
| 83 .add(new RecordedRelation(indexable, relationship, location)); | 89 .add(new RecordedRelation(indexable, relationship, location)); |
| 84 }); | 90 }); |
| 85 when(store.recordTopLevelDeclaration(anyObject)) | 91 when(store.recordTopLevelDeclaration(anyObject)) |
| 86 .thenInvoke((Element element) { | 92 .thenInvoke((Element element) { |
| 87 recordedTopElements.add(element); | 93 recordedTopElements.add(element); |
| 88 }); | 94 }); |
| 89 } | 95 } |
| 90 | 96 |
| 97 void test_isReferencedBy_PrefixElement() { |
| 98 _indexTestUnit(''' |
| 99 import 'dart:async' as ppp; |
| 100 main() { |
| 101 ppp.Future a; |
| 102 ppp.Stream b; |
| 103 } |
| 104 '''); |
| 105 // prepare elements |
| 106 PrefixElement element = findNodeElementAtString('ppp;'); |
| 107 Element elementA = findElement('a'); |
| 108 Element elementB = findElement('b'); |
| 109 IndexableElement indexable = new IndexableElement(element); |
| 110 // verify |
| 111 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, |
| 112 _expectedLocation(elementA, 'ppp.Future')); |
| 113 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, |
| 114 _expectedLocation(elementB, 'ppp.Stream')); |
| 115 _assertNoRecordedRelation(indexable, null, _expectedLocation(null, 'ppp;')); |
| 116 } |
| 117 |
| 91 void test_bad_unresolvedFieldFormalParameter() { | 118 void test_bad_unresolvedFieldFormalParameter() { |
| 92 verifyNoTestUnitErrors = false; | 119 verifyNoTestUnitErrors = false; |
| 93 _indexTestUnit(''' | 120 _indexTestUnit(''' |
| 94 class Test { | 121 class Test { |
| 95 final field; | 122 final field; |
| 96 Test(this.fie); | 123 Test(this.fie); |
| 97 }'''); | 124 }'''); |
| 98 } | 125 } |
| 99 | 126 |
| 100 void test_definesClass() { | 127 void test_definesClass() { |
| (...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 _assertRecordedRelation(indexableSetter, IndexConstants.IS_REFERENCED_BY, | 1051 _assertRecordedRelation(indexableSetter, IndexConstants.IS_REFERENCED_BY, |
| 1025 _expectedLocationQ(mainElement, 'field = 2; // q')); | 1052 _expectedLocationQ(mainElement, 'field = 2; // q')); |
| 1026 _assertRecordedRelation(indexableGetter, IndexConstants.IS_REFERENCED_BY, | 1053 _assertRecordedRelation(indexableGetter, IndexConstants.IS_REFERENCED_BY, |
| 1027 _expectedLocationQ(mainElement, 'field); // q')); | 1054 _expectedLocationQ(mainElement, 'field); // q')); |
| 1028 _assertRecordedRelationForElement( | 1055 _assertRecordedRelationForElement( |
| 1029 fieldElement, | 1056 fieldElement, |
| 1030 IndexConstants.IS_REFERENCED_BY, | 1057 IndexConstants.IS_REFERENCED_BY, |
| 1031 _expectedLocation(mainElement, 'field: 3')); | 1058 _expectedLocation(mainElement, 'field: 3')); |
| 1032 } | 1059 } |
| 1033 | 1060 |
| 1061 void test_isReferencedBy_fileOfLibrary_byImportingExportingFile() { |
| 1062 addSource('/lib.dart', ''); |
| 1063 _indexTestUnit(''' |
| 1064 import 'lib.dart'; // 1 |
| 1065 export 'lib.dart'; // 2 |
| 1066 '''); |
| 1067 // verify |
| 1068 IndexableFile libIndexableFile = new IndexableFile('/lib.dart'); |
| 1069 IndexableFile testIndexableFile = new IndexableFile(testFile); |
| 1070 _assertRecordedRelationForIndexable( |
| 1071 libIndexableFile, |
| 1072 IndexConstants.IS_REFERENCED_BY, |
| 1073 new ExpectedLocation( |
| 1074 testIndexableFile, |
| 1075 testCode.indexOf("'lib.dart'; // 1"), |
| 1076 "'lib.dart'".length, |
| 1077 false, |
| 1078 true)); |
| 1079 _assertRecordedRelationForIndexable( |
| 1080 libIndexableFile, |
| 1081 IndexConstants.IS_REFERENCED_BY, |
| 1082 new ExpectedLocation( |
| 1083 testIndexableFile, |
| 1084 testCode.indexOf("'lib.dart'; // 2"), |
| 1085 "'lib.dart'".length, |
| 1086 false, |
| 1087 true)); |
| 1088 } |
| 1089 |
| 1090 void test_isReferencedBy_fileOfPart_bySourcingFile() { |
| 1091 addSource('/part.dart', 'part of my.lib;'); |
| 1092 _indexTestUnit(''' |
| 1093 library my.lib; |
| 1094 part 'part.dart'; |
| 1095 '''); |
| 1096 // verify |
| 1097 IndexableFile partIndexableFile = new IndexableFile('/part.dart'); |
| 1098 IndexableFile testIndexableFile = new IndexableFile(testFile); |
| 1099 _assertRecordedRelationForIndexable( |
| 1100 partIndexableFile, |
| 1101 IndexConstants.IS_REFERENCED_BY, |
| 1102 new ExpectedLocation(testIndexableFile, testCode.indexOf("'part.dart'"), |
| 1103 "'part.dart'".length, false, true)); |
| 1104 } |
| 1105 |
| 1034 void test_isReferencedBy_FunctionElement() { | 1106 void test_isReferencedBy_FunctionElement() { |
| 1035 _indexTestUnit(''' | 1107 _indexTestUnit(''' |
| 1036 foo() {} | 1108 foo() {} |
| 1037 main() { | 1109 main() { |
| 1038 print(foo); | 1110 print(foo); |
| 1039 print(foo()); | 1111 print(foo()); |
| 1040 } | 1112 } |
| 1041 '''); | 1113 '''); |
| 1042 // prepare elements | 1114 // prepare elements |
| 1043 FunctionElement element = findElement("foo"); | 1115 FunctionElement element = findElement("foo"); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 } | 1361 } |
| 1290 '''); | 1362 '''); |
| 1291 // prepare elements | 1363 // prepare elements |
| 1292 Element mainElement = findElement('main'); | 1364 Element mainElement = findElement('main'); |
| 1293 Element element = findElement('L'); | 1365 Element element = findElement('L'); |
| 1294 // verify | 1366 // verify |
| 1295 _assertRecordedRelationForElement(element, IndexConstants.IS_REFERENCED_BY, | 1367 _assertRecordedRelationForElement(element, IndexConstants.IS_REFERENCED_BY, |
| 1296 _expectedLocation(mainElement, 'L;')); | 1368 _expectedLocation(mainElement, 'L;')); |
| 1297 } | 1369 } |
| 1298 | 1370 |
| 1299 void test_isReferencedBy_libraryName() { | 1371 void test_isReferencedBy_libraryName_byPartOf() { |
| 1300 Source libSource = addSource( | 1372 Source libSource = addSource( |
| 1301 '/lib.dart', | 1373 '/lib.dart', |
| 1302 ''' | 1374 ''' |
| 1303 library lib; | 1375 library lib; |
| 1304 part 'test.dart'; | 1376 part 'test.dart'; |
| 1305 '''); | 1377 '''); |
| 1306 testCode = 'part of lib;'; | 1378 testCode = 'part of lib;'; |
| 1307 testSource = addSource('/test.dart', testCode); | 1379 testSource = addSource('/test.dart', testCode); |
| 1308 testUnit = resolveDartUnit(testSource, libSource); | 1380 testUnit = resolveDartUnit(testSource, libSource); |
| 1309 testUnitElement = testUnit.element; | 1381 testUnitElement = testUnit.element; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 } | 1416 } |
| 1345 '''); | 1417 '''); |
| 1346 // prepare elements | 1418 // prepare elements |
| 1347 Element mainElement = findElement('main'); | 1419 Element mainElement = findElement('main'); |
| 1348 Element element = findElement('p'); | 1420 Element element = findElement('p'); |
| 1349 // verify | 1421 // verify |
| 1350 _assertRecordedRelationForElement(element, IndexConstants.IS_REFERENCED_BY, | 1422 _assertRecordedRelationForElement(element, IndexConstants.IS_REFERENCED_BY, |
| 1351 _expectedLocation(mainElement, 'p: 1')); | 1423 _expectedLocation(mainElement, 'p: 1')); |
| 1352 } | 1424 } |
| 1353 | 1425 |
| 1354 void test_isReferencedBy_PrefixElement() { | |
| 1355 _indexTestUnit(''' | |
| 1356 import 'dart:async' as ppp; | |
| 1357 main() { | |
| 1358 ppp.Future a; | |
| 1359 ppp.Stream b; | |
| 1360 } | |
| 1361 '''); | |
| 1362 // prepare elements | |
| 1363 PrefixElement element = findNodeElementAtString('ppp;'); | |
| 1364 Element elementA = findElement('a'); | |
| 1365 Element elementB = findElement('b'); | |
| 1366 IndexableElement indexable = new IndexableElement(element); | |
| 1367 // verify | |
| 1368 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
| 1369 _expectedLocation(elementA, 'ppp.Future')); | |
| 1370 _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY, | |
| 1371 _expectedLocation(elementB, 'ppp.Stream')); | |
| 1372 _assertNoRecordedRelation(indexable, null, _expectedLocation(null, 'ppp;')); | |
| 1373 } | |
| 1374 | |
| 1375 void test_isReferencedBy_TopLevelVariableElement() { | 1426 void test_isReferencedBy_TopLevelVariableElement() { |
| 1376 addSource( | 1427 addSource( |
| 1377 '/lib.dart', | 1428 '/lib.dart', |
| 1378 ''' | 1429 ''' |
| 1379 library lib; | 1430 library lib; |
| 1380 var V; | 1431 var V; |
| 1381 '''); | 1432 '''); |
| 1382 _indexTestUnit(''' | 1433 _indexTestUnit(''' |
| 1383 import 'lib.dart' show V; // imp | 1434 import 'lib.dart' show V; // imp |
| 1384 import 'lib.dart' as pref; | 1435 import 'lib.dart' as pref; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1589 indexDartUnit(store, context, null); | 1640 indexDartUnit(store, context, null); |
| 1590 } | 1641 } |
| 1591 | 1642 |
| 1592 void test_nullUnitElement() { | 1643 void test_nullUnitElement() { |
| 1593 CompilationUnit unit = new CompilationUnit(null, null, [], [], null); | 1644 CompilationUnit unit = new CompilationUnit(null, null, [], [], null); |
| 1594 indexDartUnit(store, context, unit); | 1645 indexDartUnit(store, context, unit); |
| 1595 } | 1646 } |
| 1596 | 1647 |
| 1597 void _assertDefinesTopLevelElement(Element element) { | 1648 void _assertDefinesTopLevelElement(Element element) { |
| 1598 ExpectedLocation location = new ExpectedLocation( | 1649 ExpectedLocation location = new ExpectedLocation( |
| 1599 element, element.nameOffset, element.nameLength, false, true); | 1650 new IndexableElement(element), |
| 1651 element.nameOffset, |
| 1652 element.nameLength, |
| 1653 false, |
| 1654 true); |
| 1600 _assertRecordedRelationForElement( | 1655 _assertRecordedRelationForElement( |
| 1601 testLibraryElement, IndexConstants.DEFINES, location); | 1656 testLibraryElement, IndexConstants.DEFINES, location); |
| 1602 expect(recordedTopElements, contains(element)); | 1657 expect(recordedTopElements, contains(element)); |
| 1603 } | 1658 } |
| 1604 | 1659 |
| 1605 /** | 1660 /** |
| 1606 * Asserts that [recordedRelations] has no item with the specified properties. | 1661 * Asserts that [recordedRelations] has no item with the specified properties. |
| 1607 */ | 1662 */ |
| 1608 void _assertNoRecordedRelation(IndexableObject expectedIndexable, | 1663 void _assertNoRecordedRelation(IndexableObject expectedIndexable, |
| 1609 RelationshipImpl relationship, ExpectedLocation location) { | 1664 RelationshipImpl relationship, ExpectedLocation location) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1678 return _assertRecordedRelationForIndexable(new IndexableName(expectedName), | 1733 return _assertRecordedRelationForIndexable(new IndexableName(expectedName), |
| 1679 expectedRelationship, expectedLocation); | 1734 expectedRelationship, expectedLocation); |
| 1680 } | 1735 } |
| 1681 | 1736 |
| 1682 ExpectedLocation _expectedLocation(Element element, String search, | 1737 ExpectedLocation _expectedLocation(Element element, String search, |
| 1683 {int length: -1, bool isQualified: false, bool isResolved: true}) { | 1738 {int length: -1, bool isQualified: false, bool isResolved: true}) { |
| 1684 int offset = findOffset(search); | 1739 int offset = findOffset(search); |
| 1685 if (length == -1) { | 1740 if (length == -1) { |
| 1686 length = getLeadingIdentifierLength(search); | 1741 length = getLeadingIdentifierLength(search); |
| 1687 } | 1742 } |
| 1743 IndexableObject indexable = |
| 1744 element != null ? new IndexableElement(element) : null; |
| 1688 return new ExpectedLocation( | 1745 return new ExpectedLocation( |
| 1689 element, offset, length, isQualified, isResolved); | 1746 indexable, offset, length, isQualified, isResolved); |
| 1690 } | 1747 } |
| 1691 | 1748 |
| 1692 ExpectedLocation _expectedLocationQ(Element element, String search, | 1749 ExpectedLocation _expectedLocationQ(Element element, String search, |
| 1693 {int length: -1}) { | 1750 {int length: -1}) { |
| 1694 return _expectedLocation(element, search, | 1751 return _expectedLocation(element, search, |
| 1695 length: length, isQualified: true); | 1752 length: length, isQualified: true); |
| 1696 } | 1753 } |
| 1697 | 1754 |
| 1698 ExpectedLocation _expectedLocationQU(Element element, String search, | 1755 ExpectedLocation _expectedLocationQU(Element element, String search, |
| 1699 {int length: -1}) { | 1756 {int length: -1}) { |
| 1700 return _expectedLocation(element, search, | 1757 return _expectedLocation(element, search, |
| 1701 length: length, isQualified: true, isResolved: false); | 1758 length: length, isQualified: true, isResolved: false); |
| 1702 } | 1759 } |
| 1703 | 1760 |
| 1704 void _indexTestUnit(String code) { | 1761 void _indexTestUnit(String code) { |
| 1705 resolveTestUnit(code); | 1762 resolveTestUnit(code); |
| 1706 indexDartUnit(store, context, testUnit); | 1763 indexDartUnit(store, context, testUnit); |
| 1707 } | 1764 } |
| 1708 } | 1765 } |
| 1709 | 1766 |
| 1710 class ExpectedLocation { | 1767 class ExpectedLocation { |
| 1711 Element element; | 1768 IndexableObject indexable; |
| 1712 int offset; | 1769 int offset; |
| 1713 int length; | 1770 int length; |
| 1714 bool isQualified; | 1771 bool isQualified; |
| 1715 bool isResolved; | 1772 bool isResolved; |
| 1716 | 1773 |
| 1717 ExpectedLocation(this.element, this.offset, this.length, this.isQualified, | 1774 ExpectedLocation(this.indexable, this.offset, this.length, this.isQualified, |
| 1718 this.isResolved); | 1775 this.isResolved); |
| 1719 | 1776 |
| 1720 @override | 1777 @override |
| 1721 String toString() { | 1778 String toString() { |
| 1722 return 'ExpectedLocation(element=$element; offset=$offset; length=$length;' | 1779 return 'ExpectedLocation(indexable=$indexable; offset=$offset; length=$lengt
h;' |
| 1723 ' isQualified=$isQualified isResolved=$isResolved)'; | 1780 ' isQualified=$isQualified isResolved=$isResolved)'; |
| 1724 } | 1781 } |
| 1725 } | 1782 } |
| 1726 | 1783 |
| 1727 class MockIndexStore extends TypedMock implements InternalIndexStore { | 1784 class MockIndexStore extends TypedMock implements InternalIndexStore { |
| 1728 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 1785 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 1729 } | 1786 } |
| 1730 | 1787 |
| 1731 /** | 1788 /** |
| 1732 * Information about a relation recorded into {@link IndexStore}. | 1789 * Information about a relation recorded into {@link IndexStore}. |
| 1733 */ | 1790 */ |
| 1734 class RecordedRelation { | 1791 class RecordedRelation { |
| 1735 final IndexableObject indexable; | 1792 final IndexableObject indexable; |
| 1736 final RelationshipImpl relationship; | 1793 final RelationshipImpl relationship; |
| 1737 final LocationImpl location; | 1794 final LocationImpl location; |
| 1738 | 1795 |
| 1739 RecordedRelation(this.indexable, this.relationship, this.location); | 1796 RecordedRelation(this.indexable, this.relationship, this.location); |
| 1740 | 1797 |
| 1741 @override | 1798 @override |
| 1742 String toString() { | 1799 String toString() { |
| 1743 return 'RecordedRelation(indexable=$indexable; relationship=$relationship; ' | 1800 return 'RecordedRelation(indexable=$indexable; relationship=$relationship; ' |
| 1744 'location=$location; flags=' | 1801 'location=$location; flags=' |
| 1745 '${location.isQualified ? "Q" : ""}' | 1802 '${location.isQualified ? "Q" : ""}' |
| 1746 '${location.isResolved ? "R" : ""})'; | 1803 '${location.isResolved ? "R" : ""})'; |
| 1747 } | 1804 } |
| 1748 } | 1805 } |
| OLD | NEW |