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 |