| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import 'dart:convert'; |
| 6 |
| 7 import 'package:analyzer/dart/element/element.dart'; |
| 8 import 'package:analyzer/src/summary/format.dart'; |
| 9 import 'package:analyzer/src/summary/idl.dart'; |
| 10 import 'package:analyzer/src/summary/index_unit.dart'; |
| 11 import 'package:unittest/unittest.dart'; |
| 12 |
| 13 import '../../reflective_tests.dart'; |
| 14 import '../abstract_single_unit.dart'; |
| 15 |
| 16 main() { |
| 17 groupSep = ' | '; |
| 18 runReflectiveTests(PackageIndexAssemblerTest); |
| 19 } |
| 20 |
| 21 class ExpectedLocation { |
| 22 final CompilationUnitElement unitElement; |
| 23 final int offset; |
| 24 final int length; |
| 25 final bool isQualified; |
| 26 final bool isResolved; |
| 27 |
| 28 ExpectedLocation(this.unitElement, this.offset, this.length, this.isQualified, |
| 29 this.isResolved); |
| 30 |
| 31 @override |
| 32 String toString() { |
| 33 return '(unit=$unitElement; offset=$offset; length=$length;' |
| 34 ' isQualified=$isQualified isResolved=$isResolved)'; |
| 35 } |
| 36 } |
| 37 |
| 38 @reflectiveTest |
| 39 class PackageIndexAssemblerTest extends AbstractSingleUnitTest { |
| 40 PackageIndex packageIndex; |
| 41 UnitIndex unitIndex; |
| 42 |
| 43 void test_isExtendedBy_ClassDeclaration() { |
| 44 _indexTestUnit(''' |
| 45 class A {} // 1 |
| 46 class B extends A {} // 2 |
| 47 '''); |
| 48 ClassElement classElementA = findElement('A'); |
| 49 // verify |
| 50 _assertHasRelation(classElementA, IndexRelationKind.IS_EXTENDED_BY, |
| 51 _expectedLocation('A {} // 2')); |
| 52 } |
| 53 |
| 54 void test_isReferencedBy_ClassElement() { |
| 55 _indexTestUnit(''' |
| 56 class A { |
| 57 static var field; |
| 58 } |
| 59 main(A p) { |
| 60 A v; |
| 61 new A(); // 2 |
| 62 A.field = 1; |
| 63 print(A.field); // 3 |
| 64 } |
| 65 '''); |
| 66 ClassElement element = findElement("A"); |
| 67 // verify |
| 68 _assertHasRelation(element, IndexRelationKind.IS_REFERENCED_BY, |
| 69 _expectedLocation('A p) {')); |
| 70 _assertHasRelation( |
| 71 element, IndexRelationKind.IS_REFERENCED_BY, _expectedLocation('A v;')); |
| 72 _assertHasRelation(element, IndexRelationKind.IS_REFERENCED_BY, |
| 73 _expectedLocation('A(); // 2')); |
| 74 _assertHasRelation(element, IndexRelationKind.IS_REFERENCED_BY, |
| 75 _expectedLocation('A.field = 1;')); |
| 76 _assertHasRelation(element, IndexRelationKind.IS_REFERENCED_BY, |
| 77 _expectedLocation('A.field); // 3')); |
| 78 } |
| 79 |
| 80 /** |
| 81 * Asserts that [unitIndex] has an item with the expected properties. |
| 82 */ |
| 83 void _assertHasRelation( |
| 84 Element element, |
| 85 IndexRelationKind expectedRelationship, |
| 86 ExpectedLocation expectedLocation) { |
| 87 int elementId = _findElementId(element); |
| 88 for (int i = 0; i < unitIndex.locationOffsets.length; i++) { |
| 89 if (unitIndex.elements[i] == elementId && |
| 90 unitIndex.locationOffsets[i] == expectedLocation.offset && |
| 91 unitIndex.locationLengths[i] == expectedLocation.length) { |
| 92 return; |
| 93 } |
| 94 } |
| 95 _failWithIndexDump( |
| 96 'not found\n$element $expectedRelationship at $expectedLocation'); |
| 97 } |
| 98 |
| 99 ExpectedLocation _expectedLocation(String search, |
| 100 {int length: -1, bool isQualified: false, bool isResolved: true}) { |
| 101 int offset = findOffset(search); |
| 102 if (length == -1) { |
| 103 length = getLeadingIdentifierLength(search); |
| 104 } |
| 105 return new ExpectedLocation( |
| 106 testUnitElement, offset, length, isQualified, isResolved); |
| 107 } |
| 108 |
| 109 void _failWithIndexDump(String msg) { |
| 110 String packageIndexJsonString = |
| 111 new JsonEncoder.withIndent(' ').convert(packageIndex.toJson()); |
| 112 fail('$msg in\n' + packageIndexJsonString); |
| 113 } |
| 114 |
| 115 /** |
| 116 * Return the [element] identifier in [packageIndex] or fail. |
| 117 */ |
| 118 int _findElementId(Element element) { |
| 119 int elementUnitId = _getElementUnitId(element); |
| 120 for (int elementId = 0; |
| 121 elementId < packageIndex.elementUnits.length; |
| 122 elementId++) { |
| 123 if (packageIndex.elementUnits[elementId] == elementUnitId && |
| 124 packageIndex.elementOffsets[elementId] == element.nameOffset) { |
| 125 return elementId; |
| 126 } |
| 127 } |
| 128 _failWithIndexDump('Element $element is not referenced'); |
| 129 return 0; |
| 130 } |
| 131 |
| 132 int _getElementUnitId(Element element) { |
| 133 CompilationUnitElement unitElement = |
| 134 PackageIndexAssembler.getUnitElement(element); |
| 135 int libraryUriId = _getUriId(unitElement.library.source.uri); |
| 136 int unitUriId = _getUriId(unitElement.library.source.uri); |
| 137 for (int i = 0; i < packageIndex.elementLibraryUris.length; i++) { |
| 138 if (packageIndex.elementLibraryUris[i] == libraryUriId && |
| 139 packageIndex.elementUnitUris[i] == unitUriId) { |
| 140 return i; |
| 141 } |
| 142 } |
| 143 fail('Unit $unitElement of $element is not referenced in the index.'); |
| 144 return -1; |
| 145 } |
| 146 |
| 147 int _getUriId(Uri uri) { |
| 148 String str = uri.toString(); |
| 149 int id = packageIndex.uris.indexOf(str); |
| 150 expect(id, isNonNegative); |
| 151 return id; |
| 152 } |
| 153 |
| 154 void _indexTestUnit(String code) { |
| 155 resolveTestUnit(code); |
| 156 PackageIndexAssembler assembler = new PackageIndexAssembler(); |
| 157 assembler.index(testUnit); |
| 158 // assemble, write and read |
| 159 PackageIndexBuilder indexBuilder = assembler.assemble(); |
| 160 List<int> indexBytes = indexBuilder.toBuffer(); |
| 161 packageIndex = new PackageIndex.fromBuffer(indexBytes); |
| 162 // prepare the only unit index |
| 163 expect(packageIndex.units, hasLength(1)); |
| 164 unitIndex = packageIndex.units[0]; |
| 165 } |
| 166 } |
| OLD | NEW |