Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1039)

Side by Side Diff: pkg/analysis_server/lib/src/services/index2/index2.dart

Issue 1755263002: Initial new index implementation. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/index2/index2.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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:async';
6
7 import 'package:analyzer/dart/ast/ast.dart';
8 import 'package:analyzer/dart/element/element.dart';
9 import 'package:analyzer/src/generated/source.dart';
10 import 'package:analyzer/src/summary/format.dart';
11 import 'package:analyzer/src/summary/idl.dart';
12 import 'package:analyzer/src/summary/index_unit.dart';
13 import 'package:collection/collection.dart';
14
15 /**
16 * Interface for storing and requesting relations.
17 */
18 class Index2 {
19 final PackageIndexStore _store;
20
21 Index2(this._store);
22
23 /**
24 * Complete with a list of locations where the given [element] has relation
25 * of the given [kind].
26 */
27 Future<List<Location>> getRelations(
28 Element element, IndexRelationKind kind) async {
29 List<Location> locations = <Location>[];
30 Iterable<PackageIndexId> ids = await _store.getIds();
31 for (PackageIndexId id in ids) {
32 PackageIndex index = await _store.getIndex(id);
33 _PackageIndexRequester requester = new _PackageIndexRequester(index);
34 List<Location> packageLocations = requester.getRelations(element, kind);
35 locations.addAll(packageLocations);
36 }
37 return locations;
38 }
39
40 /**
41 * Index the given fully resolved [unit].
42 */
43 void indexUnit(CompilationUnit unit) {
44 PackageIndexAssembler assembler = new PackageIndexAssembler();
45 assembler.index(unit);
46 PackageIndexBuilder indexBuilder = assembler.assemble();
47 String unitLibraryUri = unit.element.library.source.uri.toString();
48 String unitUnitUri = unit.element.source.uri.toString();
49 _store.putIndex(unitLibraryUri, unitUnitUri, indexBuilder);
50 }
51 }
52
53 /**
54 * Information about location of a single relation in the index.
55 *
56 * The location is expressed as a library specific unit containing the index
57 * relation, offset within this [Source] and length.
58 *
59 * Clients may not extend, implement or mix-in this class.
60 */
61 class Location {
62 /**
63 * The URI of the source of the library containing this location.
64 */
65 final String libraryUri;
66
67 /**
68 * The URI of the source of the unit containing this location.
69 */
70 final String unitUri;
71
72 /**
73 * The offset of this location within the [unitUri].
74 */
75 final int offset;
76
77 /**
78 * The length of this location.
79 */
80 final int length;
81
82 /**
83 * Is `true` if this location is qualified.
84 */
85 final bool isQualified;
86
87 Location(this.libraryUri, this.unitUri, this.offset, this.length,
88 this.isQualified);
89
90 @override
91 String toString() => 'Location{librarySourceUri: $libraryUri, '
92 'unitSourceUri: $unitUri, offset: $offset, length: $length, '
93 'isQualified: $isQualified}';
94 }
95
96 /**
97 * Opaque identifier of a [PackageIndex].
98 */
99 abstract class PackageIndexId {}
100
101 /**
102 * Storage of [PackageIndex] objects.
103 */
104 abstract class PackageIndexStore {
105 /**
106 * Complete with identifiers of all [PackageIndex] objects.
107 */
108 Future<Iterable<PackageIndexId>> getIds();
109
110 /**
111 * Complete with the [PackageIndex] with the given [id].
112 */
113 Future<PackageIndex> getIndex(PackageIndexId id);
114
115 /**
116 * Put the given [indexBuilder] into the store.
117 */
118 void putIndex(String unitLibraryUri, String unitUnitUri,
119 PackageIndexBuilder indexBuilder);
120 }
121
122 /**
123 * Helper for requesting information from a single [PackageIndex].
124 */
125 class _PackageIndexRequester {
126 final PackageIndex index;
127
128 _PackageIndexRequester(this.index);
129
130 /**
131 * Return the [element]'s identifier in the [index] or `null` if the
132 * [element] is not referenced in the [index].
133 */
134 int findElementId(Element element) {
135 int unitId = getUnitId(element);
136 int offset = element.nameOffset;
137 if (element is LibraryElement || element is CompilationUnitElement) {
138 offset = 0;
139 }
140 IndexSyntheticElementKind kind =
141 PackageIndexAssembler.getIndexElementKind(element);
142 for (int elementId = 0;
143 elementId < index.elementUnits.length;
144 elementId++) {
145 if (index.elementUnits[elementId] == unitId &&
146 index.elementOffsets[elementId] == offset &&
147 index.elementKinds[elementId] == kind) {
148 return elementId;
149 }
150 }
151 return null;
152 }
153
154 /**
155 * Complete with a list of locations where the given [element] has relation
156 * of the given [kind].
157 */
158 List<Location> getRelations(Element element, IndexRelationKind kind) {
159 int elementId = findElementId(element);
160 if (elementId == null) {
161 return const <Location>[];
162 }
163 List<Location> locations = <Location>[];
164 for (UnitIndex unitIndex in index.units) {
165 _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex);
166 List<Location> unitLocations = requester.getRelations(elementId, kind);
167 locations.addAll(unitLocations);
168 }
169 return locations;
170 }
171
172 /**
173 * Return the identifier of [str] in the [index] or `-1` if [str] is not used
174 * in the [index].
175 */
176 int getStringId(String str) {
177 return index.strings.indexOf(str);
178 }
179
180 /**
181 * Return the identifier of the [CompilationUnitElement] containing the
182 * [element] in the [index] or `-1` if not found.
183 */
184 int getUnitId(Element element) {
185 CompilationUnitElement unitElement =
186 PackageIndexAssembler.getUnitElement(element);
187 int libraryUriId = getUriId(unitElement.library.source.uri);
188 int unitUriId = getUriId(unitElement.source.uri);
189 for (int i = 0; i < index.unitLibraryUris.length; i++) {
190 if (index.unitLibraryUris[i] == libraryUriId &&
191 index.unitUnitUris[i] == unitUriId) {
192 return i;
193 }
194 }
195 return -1;
196 }
197
198 /**
199 * Return the URI of the library source of the library specific [unit].
200 */
201 String getUnitLibraryUri(int unit) {
202 int id = index.unitLibraryUris[unit];
203 return index.strings[id];
204 }
205
206 /**
207 * Return the URI of the unit source of the library specific [unit].
208 */
209 String getUnitUnitUri(int unit) {
210 int id = index.unitUnitUris[unit];
211 return index.strings[id];
212 }
213
214 /**
215 * Return the identifier of the [uri] in the [index] or `-1` if the [uri] is
216 * not used in the [index].
217 */
218 int getUriId(Uri uri) {
219 String str = uri.toString();
220 return getStringId(str);
221 }
222 }
223
224 /**
225 * Helper for requesting information from a single [UnitIndex].
226 */
227 class _UnitIndexRequester {
228 final _PackageIndexRequester packageRequester;
229 final UnitIndex unitIndex;
230
231 _UnitIndexRequester(this.packageRequester, this.unitIndex);
232
233 /**
234 * Return a list of locations where an element with the given [elementId] has
235 * relation of the given [kind].
236 */
237 List<Location> getRelations(int elementId, IndexRelationKind kind) {
238 // Find a usage of the element.
239 int i = binarySearch(unitIndex.usedElements, elementId);
240 if (i == -1) {
241 return const <Location>[];
242 }
243 // Find the first usage of the element.
244 while (i > 0 && unitIndex.usedElements[i - 1] == elementId) {
245 i--;
246 }
247 // Create locations for every usage of the element.
248 List<Location> locations = <Location>[];
249 String unitLibraryUri = null;
250 String unitUnitUri = null;
251 for (;
252 i < unitIndex.usedElements.length &&
253 unitIndex.usedElements[i] == elementId;
254 i++) {
255 if (unitIndex.usedElementKinds[i] == kind) {
256 unitLibraryUri ??= packageRequester.getUnitLibraryUri(unitIndex.unit);
257 unitUnitUri ??= packageRequester.getUnitUnitUri(unitIndex.unit);
258 locations.add(new Location(
259 unitLibraryUri,
260 unitUnitUri,
261 unitIndex.usedElementOffsets[i],
262 unitIndex.usedElementLengths[i],
263 unitIndex.usedElementIsQualifiedFlags[i]));
264 }
265 }
266 return locations;
267 }
268 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/index2/index2.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698