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

Side by Side Diff: pkg/analyzer/lib/src/generated/index.dart

Issue 257773008: New analyzer snapshot, based on r35422. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update pubspec.yaml Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
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 // This code was auto-generated, is not intended to be edited, and is subject to 5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information. 6 // significant change. Please see the README file for more information.
7 7
8 library engine.index; 8 library engine.index;
9 9
10 import 'dart:collection' show Queue; 10 import 'dart:collection' show Queue;
11 import 'java_core.dart'; 11 import 'java_core.dart';
12 import 'java_engine.dart'; 12 import 'java_engine.dart';
13 import 'source.dart'; 13 import 'source.dart';
14 import 'scanner.dart' show Token; 14 import 'scanner.dart' show Token;
15 import 'ast.dart'; 15 import 'ast.dart';
16 import 'element.dart'; 16 import 'element.dart';
17 import 'resolver.dart' show Namespace, NamespaceBuilder; 17 import 'resolver.dart' show Namespace, NamespaceBuilder;
18 import 'engine.dart'; 18 import 'engine.dart';
19 import 'html.dart' as ht; 19 import 'html.dart' as ht;
20 20
21 /** 21 /**
22 * Instances of the [RemoveSourceOperation] implement an operation that removes from the index 22 * Implementation of [UniverseElement].
23 * any data based on the content of a specified source. 23 */
24 */ 24 class UniverseElementImpl extends ElementImpl implements UniverseElement {
25 class RemoveSourceOperation implements IndexOperation { 25 static UniverseElementImpl INSTANCE = new UniverseElementImpl();
26
27 UniverseElementImpl() : super("--universe--", -1);
28
29 @override
30 accept(ElementVisitor visitor) => null;
31
32 @override
33 ElementKind get kind => ElementKind.UNIVERSE;
34 }
35
36 /**
37 * Container of information computed by the index - relationships between elemen ts.
38 */
39 abstract class IndexStore {
40 /**
41 * Notifies the index store that we are going to index the unit with the given element.
42 *
43 * If the unit is a part of a library, then all its locations are removed. If it is a defining
44 * compilation unit of a library, then index store also checks if some previou sly indexed parts of
45 * the library are not parts of the library anymore, and clears their informat ion.
46 *
47 * @param the [AnalysisContext] in which unit being indexed
48 * @param unitElement the element of the unit being indexed
49 * @return `true` the given [AnalysisContext] is active, or `false` if it was
50 * removed before, so no any unit may be indexed with it
51 */
52 bool aboutToIndexDart(AnalysisContext context, CompilationUnitElement unitElem ent);
53
54 /**
55 * Notifies the index store that we are going to index the given [HtmlElement] .
56 *
57 * @param the [AnalysisContext] in which unit being indexed
58 * @param htmlElement the [HtmlElement] being indexed
59 * @return `true` the given [AnalysisContext] is active, or `false` if it was
60 * removed before, so no any unit may be indexed with it
61 */
62 bool aboutToIndexHtml(AnalysisContext context, HtmlElement htmlElement);
63
64 /**
65 * Return the locations of the elements that have the given relationship with the given element.
66 * For example, if the element represents a method and the relationship is the is-referenced-by
67 * relationship, then the returned locations will be all of the places where t he method is
68 * invoked.
69 *
70 * @param element the the element that has the relationship with the locations to be returned
71 * @param relationship the [Relationship] between the given element and the lo cations to be
72 * returned
73 * @return the locations that have the given relationship with the given eleme nt
74 */
75 List<Location> getRelationships(Element element, Relationship relationship);
76
77 /**
78 * Answer index statistics.
79 */
80 String get statistics;
81
82 /**
83 * Record that the given element and location have the given relationship. For example, if the
84 * relationship is the is-referenced-by relationship, then the element would b e the element being
85 * referenced and the location would be the point at which it is referenced. E ach element can have
86 * the same relationship with multiple locations. In other words, if the follo wing code were
87 * executed
88 *
89 * <pre>
90 * recordRelationship(element, isReferencedBy, location1);
91 * recordRelationship(element, isReferencedBy, location2);
92 * </pre>
93 *
94 * then both relationships would be maintained in the index and the result of executing
95 *
96 * <pre>
97 * getRelationship(element, isReferencedBy);
98 * </pre>
99 *
100 * would be an array containing both <code>location1</code> and <code>location 2</code>.
101 *
102 * @param element the element that is related to the location
103 * @param relationship the [Relationship] between the element and the location
104 * @param location the [Location] where relationship happens
105 */
106 void recordRelationship(Element element, Relationship relationship, Location l ocation);
107
108 /**
109 * Remove from the index all of the information associated with [AnalysisConte xt].
110 *
111 * This method should be invoked when a context is disposed.
112 *
113 * @param the [AnalysisContext] being removed
114 */
115 void removeContext(AnalysisContext context);
116
117 /**
118 * Remove from the index all of the information associated with elements or lo cations in the given
119 * source. This includes relationships between an element in the given source and any other
120 * locations, relationships between any other elements and a location within t he given source.
121 *
122 * This method should be invoked when a source is no longer part of the code b ase.
123 *
124 * @param the [AnalysisContext] in which [Source] being removed
125 * @param source the source being removed
126 */
127 void removeSource(AnalysisContext context, Source source);
128
129 /**
130 * Remove from the index all of the information associated with elements or lo cations in the given
131 * sources. This includes relationships between an element in the given source s and any other
132 * locations, relationships between any other elements and a location within t he given sources.
133 *
134 * This method should be invoked when multiple sources are no longer part of t he code base.
135 *
136 * @param the [AnalysisContext] in which [Source]s being removed
137 * @param container the [SourceContainer] holding the sources being removed
138 */
139 void removeSources(AnalysisContext context, SourceContainer container);
140 }
141
142 /**
143 * Visits resolved [HtmlUnit] and adds relationships into [IndexStore].
144 */
145 class AngularHtmlIndexContributor extends ExpressionVisitor {
146 /**
147 * The [IndexStore] to record relations into.
148 */
149 final IndexStore _store;
150
151 /**
152 * The index contributor used to index Dart [Expression]s.
153 */
154 IndexContributor _indexContributor;
155
156 HtmlElement _htmlUnitElement;
157
158 /**
159 * Initialize a newly created Angular HTML index contributor.
160 *
161 * @param store the [IndexStore] to record relations into.
162 */
163 AngularHtmlIndexContributor(this._store) {
164 _indexContributor = new IndexContributor_AngularHtmlIndexContributor(_store, this);
165 }
166
167 @override
168 void visitExpression(Expression expression) {
169 // Formatter
170 if (expression is SimpleIdentifier) {
171 SimpleIdentifier identifier = expression;
172 Element element = identifier.bestElement;
173 if (element is AngularElement) {
174 _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, _cr eateLocationForIdentifier(identifier));
175 return;
176 }
177 }
178 // index as a normal Dart expression
179 expression.accept(_indexContributor);
180 }
181
182 @override
183 Object visitHtmlUnit(ht.HtmlUnit node) {
184 _htmlUnitElement = node.element;
185 CompilationUnitElement dartUnitElement = _htmlUnitElement.angularCompilation Unit;
186 _indexContributor.enterScope(dartUnitElement);
187 return super.visitHtmlUnit(node);
188 }
189
190 @override
191 Object visitXmlAttributeNode(ht.XmlAttributeNode node) {
192 Element element = node.element;
193 if (element != null) {
194 ht.Token nameToken = node.nameToken;
195 Location location = _createLocationForToken(nameToken);
196 _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, locat ion);
197 }
198 return super.visitXmlAttributeNode(node);
199 }
200
201 @override
202 Object visitXmlTagNode(ht.XmlTagNode node) {
203 Element element = node.element;
204 if (element != null) {
205 // tag
206 {
207 ht.Token tagToken = node.tagToken;
208 Location location = _createLocationForToken(tagToken);
209 _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, loc ation);
210 }
211 // maybe add closing tag range
212 ht.Token closingTag = node.closingTag;
213 if (closingTag != null) {
214 Location location = _createLocationForToken(closingTag);
215 _store.recordRelationship(element, IndexConstants.ANGULAR_CLOSING_TAG_RE FERENCE, location);
216 }
217 }
218 return super.visitXmlTagNode(node);
219 }
220
221 Location _createLocationForIdentifier(SimpleIdentifier identifier) => new Loca tion(_htmlUnitElement, identifier.offset, identifier.length);
222
223 Location _createLocationForToken(ht.Token token) => new Location(_htmlUnitElem ent, token.offset, token.length);
224 }
225
226 class IndexContributor_AngularHtmlIndexContributor extends IndexContributor {
227 final AngularHtmlIndexContributor AngularHtmlIndexContributor_this;
228
229 IndexContributor_AngularHtmlIndexContributor(IndexStore arg0, this.AngularHtml IndexContributor_this) : super(arg0);
230
231 @override
232 Element peekElement() => AngularHtmlIndexContributor_this._htmlUnitElement;
233
234 @override
235 void recordRelationship(Element element, Relationship relationship, Location l ocation) {
236 AngularElement angularElement = AngularHtmlUnitResolver.getAngularElement(el ement);
237 if (angularElement != null) {
238 element = angularElement;
239 relationship = IndexConstants.ANGULAR_REFERENCE;
240 }
241 super.recordRelationship(element, relationship, location);
242 }
243 }
244
245 /**
246 * Recursively visits [HtmlUnit] and every embedded [Expression].
247 */
248 abstract class ExpressionVisitor extends ht.RecursiveXmlVisitor<Object> {
249 /**
250 * Visits the given [Expression]s embedded into tag or attribute.
251 *
252 * @param expression the [Expression] to visit, not `null`
253 */
254 void visitExpression(Expression expression);
255
256 @override
257 Object visitXmlAttributeNode(ht.XmlAttributeNode node) {
258 _visitExpressions(node.expressions);
259 return super.visitXmlAttributeNode(node);
260 }
261
262 @override
263 Object visitXmlTagNode(ht.XmlTagNode node) {
264 _visitExpressions(node.expressions);
265 return super.visitXmlTagNode(node);
266 }
267
268 /**
269 * Visits [Expression]s of the given [XmlExpression]s.
270 */
271 void _visitExpressions(List<ht.XmlExpression> expressions) {
272 for (ht.XmlExpression xmlExpression in expressions) {
273 if (xmlExpression is AngularXmlExpression) {
274 AngularXmlExpression angularXmlExpression = xmlExpression;
275 List<Expression> dartExpressions = angularXmlExpression.expression.expre ssions;
276 for (Expression dartExpression in dartExpressions) {
277 visitExpression(dartExpression);
278 }
279 }
280 if (xmlExpression is ht.RawXmlExpression) {
281 ht.RawXmlExpression rawXmlExpression = xmlExpression;
282 visitExpression(rawXmlExpression.expression);
283 }
284 }
285 }
286 }
287
288 /**
289 * Instances of the [IndexHtmlUnitOperation] implement an operation that adds da ta to the
290 * index based on the resolved [HtmlUnit].
291 */
292 class IndexHtmlUnitOperation implements IndexOperation {
26 /** 293 /**
27 * The index store against which this operation is being run. 294 * The index store against which this operation is being run.
28 */ 295 */
29 final IndexStore _indexStore; 296 final IndexStore _indexStore;
30 297
31 /** 298 /**
32 * The context in which source being removed. 299 * The context in which [HtmlUnit] was resolved.
33 */ 300 */
34 final AnalysisContext _context; 301 final AnalysisContext _context;
35 302
36 /** 303 /**
37 * The source being removed. 304 * The [HtmlUnit] being indexed.
38 */ 305 */
39 final Source source; 306 final ht.HtmlUnit unit;
307
308 /**
309 * The element of the [HtmlUnit] being indexed.
310 */
311 HtmlElement _htmlElement;
312
313 /**
314 * The source being indexed.
315 */
316 Source _source;
317
318 /**
319 * Initialize a newly created operation that will index the specified [HtmlUni t].
320 *
321 * @param indexStore the index store against which this operation is being run
322 * @param context the context in which [HtmlUnit] was resolved
323 * @param unit the fully resolved [HtmlUnit]
324 */
325 IndexHtmlUnitOperation(this._indexStore, this._context, this.unit) {
326 this._htmlElement = unit.element;
327 this._source = _htmlElement.source;
328 }
329
330 /**
331 * @return the [Source] to be indexed.
332 */
333 Source get source => _source;
334
335 @override
336 bool get isQuery => false;
337
338 @override
339 void performOperation() {
340 try {
341 bool mayIndex = _indexStore.aboutToIndexHtml(_context, _htmlElement);
342 if (!mayIndex) {
343 return;
344 }
345 AngularHtmlIndexContributor contributor = new AngularHtmlIndexContributor( _indexStore);
346 unit.accept(contributor);
347 } catch (exception) {
348 AnalysisEngine.instance.logger.logError2("Could not index ${unit.element.l ocation}", exception);
349 }
350 }
351
352 @override
353 bool removeWhenSourceRemoved(Source source) => this._source == source;
354
355 @override
356 String toString() => "IndexHtmlUnitOperation(${_source.fullName})";
357 }
358
359 /**
360 * Visits resolved [CompilationUnit] and adds Angular specific relationships int o
361 * [IndexStore].
362 */
363 class AngularDartIndexContributor extends GeneralizingAstVisitor<Object> {
364 final IndexStore _store;
365
366 AngularDartIndexContributor(this._store);
367
368 @override
369 Object visitClassDeclaration(ClassDeclaration node) {
370 ClassElement classElement = node.element;
371 if (classElement != null) {
372 List<ToolkitObjectElement> toolkitObjects = classElement.toolkitObjects;
373 for (ToolkitObjectElement object in toolkitObjects) {
374 if (object is AngularComponentElement) {
375 _indexComponent(object);
376 }
377 if (object is AngularDecoratorElement) {
378 AngularDecoratorElement directive = object;
379 _indexDirective(directive);
380 }
381 }
382 }
383 // stop visiting
384 return null;
385 }
386
387 @override
388 Object visitCompilationUnitMember(CompilationUnitMember node) => null;
389
390 void _indexComponent(AngularComponentElement component) {
391 _indexProperties(component.properties);
392 }
393
394 void _indexDirective(AngularDecoratorElement directive) {
395 _indexProperties(directive.properties);
396 }
397
398 /**
399 * Index [FieldElement] references from [AngularPropertyElement]s.
400 */
401 void _indexProperties(List<AngularPropertyElement> properties) {
402 for (AngularPropertyElement property in properties) {
403 FieldElement field = property.field;
404 if (field != null) {
405 int offset = property.fieldNameOffset;
406 if (offset == -1) {
407 continue;
408 }
409 int length = field.name.length;
410 Location location = new Location(property, offset, length);
411 // getter reference
412 if (property.propertyKind.callsGetter()) {
413 PropertyAccessorElement getter = field.getter;
414 if (getter != null) {
415 _store.recordRelationship(getter, IndexConstants.IS_REFERENCED_BY_QU ALIFIED, location);
416 }
417 }
418 // setter reference
419 if (property.propertyKind.callsSetter()) {
420 PropertyAccessorElement setter = field.setter;
421 if (setter != null) {
422 _store.recordRelationship(setter, IndexConstants.IS_REFERENCED_BY_QU ALIFIED, location);
423 }
424 }
425 }
426 }
427 }
428 }
429
430 /**
431 * Special [Element] which is used to index references to the name without speci fying concrete
432 * kind of this name - field, method or something else.
433 */
434 class NameElementImpl extends ElementImpl {
435 NameElementImpl(String name) : super("name:${name}", -1);
436
437 @override
438 accept(ElementVisitor visitor) => null;
439
440 @override
441 ElementKind get kind => ElementKind.NAME;
442 }
443
444 /**
445 * The interface <code>RelationshipCallback</code> defines the behavior of objec ts that are invoked
446 * with the results of a query about a given relationship.
447 */
448 abstract class RelationshipCallback {
449 /**
450 * This method is invoked when the locations that have a specified relationshi p with a specified
451 * element are available. For example, if the element is a field and the relat ionship is the
452 * is-referenced-by relationship, then this method will be invoked with each l ocation at which the
453 * field is referenced.
454 *
455 * @param element the [Element] that has the relationship with the locations
456 * @param relationship the relationship between the given element and the loca tions
457 * @param locations the locations that were found
458 */
459 void hasRelationships(Element element, Relationship relationship, List<Locatio n> locations);
460 }
461
462 /**
463 * Instances of the [RemoveSourcesOperation] implement an operation that removes from the
464 * index any data based on the content of source belonging to a [SourceContainer ].
465 */
466 class RemoveSourcesOperation implements IndexOperation {
467 /**
468 * The index store against which this operation is being run.
469 */
470 final IndexStore _indexStore;
471
472 /**
473 * The context to remove container.
474 */
475 final AnalysisContext _context;
476
477 /**
478 * The source container to remove.
479 */
480 final SourceContainer container;
40 481
41 /** 482 /**
42 * Initialize a newly created operation that will remove the specified resourc e. 483 * Initialize a newly created operation that will remove the specified resourc e.
43 * 484 *
44 * @param indexStore the index store against which this operation is being run 485 * @param indexStore the index store against which this operation is being run
45 * @param context the [AnalysisContext] to remove source in 486 * @param context the [AnalysisContext] to remove container in
46 * @param source the [Source] to remove from index 487 * @param container the [SourceContainer] to remove from index
47 */ 488 */
48 RemoveSourceOperation(this._indexStore, this._context, this.source); 489 RemoveSourcesOperation(this._indexStore, this._context, this.container);
49 490
50 @override 491 @override
51 bool get isQuery => false; 492 bool get isQuery => false;
52 493
53 @override 494 @override
54 void performOperation() { 495 void performOperation() {
55 _indexStore.removeSource(_context, source); 496 _indexStore.removeSources(_context, container);
56 } 497 }
57 498
58 @override 499 @override
59 bool removeWhenSourceRemoved(Source source) => false; 500 bool removeWhenSourceRemoved(Source source) => false;
60 501
61 @override 502 @override
62 String toString() => "RemoveSource(${source.fullName})"; 503 String toString() => "RemoveSources(${container})";
63 } 504 }
64 505
65 /** 506 /**
66 * The interface [IndexOperation] defines the behavior of objects used to perfor m operations 507 * Instances of the [IndexUnitOperation] implement an operation that adds data t o the index
67 * on an index. 508 * based on the resolved [CompilationUnit].
68 */ 509 */
69 abstract class IndexOperation { 510 class IndexUnitOperation implements IndexOperation {
70 /** 511 /**
71 * Return `true` if this operation returns information from the index. 512 * The index store against which this operation is being run.
72 * 513 */
73 * @return `true` if this operation returns information from the index 514 final IndexStore _indexStore;
74 */ 515
75 bool get isQuery; 516 /**
76 517 * The context in which compilation unit was resolved.
77 /** 518 */
78 * Perform the operation implemented by this operation. 519 final AnalysisContext _context;
79 */ 520
80 void performOperation(); 521 /**
81 522 * The compilation unit being indexed.
82 /** 523 */
83 * Return `true` if this operation should be removed from the operation queue when the 524 final CompilationUnit unit;
84 * given resource has been removed. 525
85 * 526 /**
86 * @param source the [Source] that has been removed 527 * The element of the compilation unit being indexed.
87 * @return `true` if this operation should be removed from the operation queue as a 528 */
88 * result of removing the resource 529 CompilationUnitElement _unitElement;
89 */ 530
90 bool removeWhenSourceRemoved(Source source); 531 /**
532 * The source being indexed.
533 */
534 Source _source;
535
536 /**
537 * Initialize a newly created operation that will index the specified unit.
538 *
539 * @param indexStore the index store against which this operation is being run
540 * @param context the context in which compilation unit was resolved
541 * @param unit the fully resolved AST structure
542 */
543 IndexUnitOperation(this._indexStore, this._context, this.unit) {
544 this._unitElement = unit.element;
545 this._source = _unitElement.source;
546 }
547
548 /**
549 * @return the [Source] to be indexed.
550 */
551 Source get source => _source;
552
553 @override
554 bool get isQuery => false;
555
556 @override
557 void performOperation() {
558 try {
559 bool mayIndex = _indexStore.aboutToIndexDart(_context, _unitElement);
560 if (!mayIndex) {
561 return;
562 }
563 unit.accept(new IndexContributor(_indexStore));
564 unit.accept(new AngularDartIndexContributor(_indexStore));
565 } catch (exception) {
566 AnalysisEngine.instance.logger.logError2("Could not index ${unit.element.l ocation}", exception);
567 }
568 }
569
570 @override
571 bool removeWhenSourceRemoved(Source source) => this._source == source;
572
573 @override
574 String toString() => "IndexUnitOperation(${_source.fullName})";
91 } 575 }
92 576
93 /** 577 /**
94 * [IndexStore] which keeps full index in memory. 578 * [IndexStore] which keeps full index in memory.
95 */ 579 */
96 class MemoryIndexStoreImpl implements MemoryIndexStore { 580 class MemoryIndexStoreImpl implements MemoryIndexStore {
97 /** 581 /**
98 * When logging is on, [AnalysisEngine] actually creates 582 * When logging is on, [AnalysisEngine] actually creates
99 * [InstrumentedAnalysisContextImpl], which wraps [AnalysisContextImpl] used t o create 583 * [InstrumentedAnalysisContextImpl], which wraps [AnalysisContextImpl] used t o create
100 * actual [Element]s. So, in index we have to unwrap [InstrumentedAnalysisCont extImpl] 584 * actual [Element]s. So, in index we have to unwrap [InstrumentedAnalysisCont extImpl]
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 } 1061 }
578 1062
579 @override 1063 @override
580 int get hashCode => JavaArrays.makeHashCode([_librarySource, _unitSource]); 1064 int get hashCode => JavaArrays.makeHashCode([_librarySource, _unitSource]);
581 1065
582 @override 1066 @override
583 String toString() => "${_librarySource} ${_unitSource}"; 1067 String toString() => "${_librarySource} ${_unitSource}";
584 } 1068 }
585 1069
586 /** 1070 /**
587 * Instances of the [IndexUnitOperation] implement an operation that adds data t o the index
588 * based on the resolved [CompilationUnit].
589 */
590 class IndexUnitOperation implements IndexOperation {
591 /**
592 * The index store against which this operation is being run.
593 */
594 final IndexStore _indexStore;
595
596 /**
597 * The context in which compilation unit was resolved.
598 */
599 final AnalysisContext _context;
600
601 /**
602 * The compilation unit being indexed.
603 */
604 final CompilationUnit unit;
605
606 /**
607 * The element of the compilation unit being indexed.
608 */
609 CompilationUnitElement _unitElement;
610
611 /**
612 * The source being indexed.
613 */
614 Source _source;
615
616 /**
617 * Initialize a newly created operation that will index the specified unit.
618 *
619 * @param indexStore the index store against which this operation is being run
620 * @param context the context in which compilation unit was resolved
621 * @param unit the fully resolved AST structure
622 */
623 IndexUnitOperation(this._indexStore, this._context, this.unit) {
624 this._unitElement = unit.element;
625 this._source = _unitElement.source;
626 }
627
628 /**
629 * @return the [Source] to be indexed.
630 */
631 Source get source => _source;
632
633 @override
634 bool get isQuery => false;
635
636 @override
637 void performOperation() {
638 try {
639 bool mayIndex = _indexStore.aboutToIndexDart(_context, _unitElement);
640 if (!mayIndex) {
641 return;
642 }
643 unit.accept(new IndexContributor(_indexStore));
644 unit.accept(new AngularDartIndexContributor(_indexStore));
645 } catch (exception) {
646 AnalysisEngine.instance.logger.logError2("Could not index ${unit.element.l ocation}", exception);
647 }
648 }
649
650 @override
651 bool removeWhenSourceRemoved(Source source) => this._source == source;
652
653 @override
654 String toString() => "IndexUnitOperation(${_source.fullName})";
655 }
656
657 /**
658 * Recursively visits [HtmlUnit] and every embedded [Expression].
659 */
660 abstract class ExpressionVisitor extends ht.RecursiveXmlVisitor<Object> {
661 /**
662 * Visits the given [Expression]s embedded into tag or attribute.
663 *
664 * @param expression the [Expression] to visit, not `null`
665 */
666 void visitExpression(Expression expression);
667
668 @override
669 Object visitXmlAttributeNode(ht.XmlAttributeNode node) {
670 _visitExpressions(node.expressions);
671 return super.visitXmlAttributeNode(node);
672 }
673
674 @override
675 Object visitXmlTagNode(ht.XmlTagNode node) {
676 _visitExpressions(node.expressions);
677 return super.visitXmlTagNode(node);
678 }
679
680 /**
681 * Visits [Expression]s of the given [XmlExpression]s.
682 */
683 void _visitExpressions(List<ht.XmlExpression> expressions) {
684 for (ht.XmlExpression xmlExpression in expressions) {
685 if (xmlExpression is AngularXmlExpression) {
686 AngularXmlExpression angularXmlExpression = xmlExpression;
687 List<Expression> dartExpressions = angularXmlExpression.expression.expre ssions;
688 for (Expression dartExpression in dartExpressions) {
689 visitExpression(dartExpression);
690 }
691 }
692 if (xmlExpression is ht.RawXmlExpression) {
693 ht.RawXmlExpression rawXmlExpression = xmlExpression;
694 visitExpression(rawXmlExpression.expression);
695 }
696 }
697 }
698 }
699
700 /**
701 * Relationship between an element and a location. Relationships are identified by a globally unique
702 * identifier.
703 */
704 class Relationship {
705 /**
706 * The unique identifier for this relationship.
707 */
708 final String _uniqueId;
709
710 /**
711 * A table mapping relationship identifiers to relationships.
712 */
713 static Map<String, Relationship> _RelationshipMap = {};
714
715 /**
716 * Return the relationship with the given unique identifier.
717 *
718 * @param uniqueId the unique identifier for the relationship
719 * @return the relationship with the given unique identifier
720 */
721 static Relationship getRelationship(String uniqueId) {
722 Relationship relationship = _RelationshipMap[uniqueId];
723 if (relationship == null) {
724 relationship = new Relationship(uniqueId);
725 _RelationshipMap[uniqueId] = relationship;
726 }
727 return relationship;
728 }
729
730 /**
731 * @return all registered [Relationship]s.
732 */
733 static Iterable<Relationship> values() => _RelationshipMap.values;
734
735 /**
736 * Initialize a newly created relationship to have the given unique identifier .
737 *
738 * @param uniqueId the unique identifier for this relationship
739 */
740 Relationship(this._uniqueId);
741
742 /**
743 * Return the unique identifier for this relationship.
744 *
745 * @return the unique identifier for this relationship
746 */
747 String get identifier => _uniqueId;
748
749 @override
750 String toString() => _uniqueId;
751 }
752
753 /**
754 * Instances of the [RemoveSourcesOperation] implement an operation that removes from the
755 * index any data based on the content of source belonging to a [SourceContainer ].
756 */
757 class RemoveSourcesOperation implements IndexOperation {
758 /**
759 * The index store against which this operation is being run.
760 */
761 final IndexStore _indexStore;
762
763 /**
764 * The context to remove container.
765 */
766 final AnalysisContext _context;
767
768 /**
769 * The source container to remove.
770 */
771 final SourceContainer container;
772
773 /**
774 * Initialize a newly created operation that will remove the specified resourc e.
775 *
776 * @param indexStore the index store against which this operation is being run
777 * @param context the [AnalysisContext] to remove container in
778 * @param container the [SourceContainer] to remove from index
779 */
780 RemoveSourcesOperation(this._indexStore, this._context, this.container);
781
782 @override
783 bool get isQuery => false;
784
785 @override
786 void performOperation() {
787 _indexStore.removeSources(_context, container);
788 }
789
790 @override
791 bool removeWhenSourceRemoved(Source source) => false;
792
793 @override
794 String toString() => "RemoveSources(${container})";
795 }
796
797 /**
798 * The interface `UniverseElement` defines element to use when we want to reques t "defines" 1071 * The interface `UniverseElement` defines element to use when we want to reques t "defines"
799 * relations without specifying exact library. 1072 * relations without specifying exact library.
800 */ 1073 */
801 abstract class UniverseElement implements Element { 1074 abstract class UniverseElement implements Element {
802 static final UniverseElement INSTANCE = UniverseElementImpl.INSTANCE; 1075 static final UniverseElement INSTANCE = UniverseElementImpl.INSTANCE;
803 } 1076 }
804 1077
805 /** 1078 /**
806 * The enumeration <code>ProcessorState</code> represents the possible states of an operation 1079 * The enumeration <code>ProcessorState</code> represents the possible states of an operation
807 * processor. 1080 * processor.
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 */ 1244 */
972 static final Relationship ANGULAR_REFERENCE = Relationship.getRelationship("an gular-reference"); 1245 static final Relationship ANGULAR_REFERENCE = Relationship.getRelationship("an gular-reference");
973 1246
974 /** 1247 /**
975 * Reference to some closing tag of an XML element. 1248 * Reference to some closing tag of an XML element.
976 */ 1249 */
977 static final Relationship ANGULAR_CLOSING_TAG_REFERENCE = Relationship.getRela tionship("angular-closing-tag-reference"); 1250 static final Relationship ANGULAR_CLOSING_TAG_REFERENCE = Relationship.getRela tionship("angular-closing-tag-reference");
978 } 1251 }
979 1252
980 /** 1253 /**
981 * Visits resolved [HtmlUnit] and adds relationships into [IndexStore].
982 */
983 class AngularHtmlIndexContributor extends ExpressionVisitor {
984 /**
985 * The [IndexStore] to record relations into.
986 */
987 final IndexStore _store;
988
989 /**
990 * The index contributor used to index Dart [Expression]s.
991 */
992 IndexContributor _indexContributor;
993
994 HtmlElement _htmlUnitElement;
995
996 /**
997 * Initialize a newly created Angular HTML index contributor.
998 *
999 * @param store the [IndexStore] to record relations into.
1000 */
1001 AngularHtmlIndexContributor(this._store) {
1002 _indexContributor = new IndexContributor_AngularHtmlIndexContributor(_store, this);
1003 }
1004
1005 @override
1006 void visitExpression(Expression expression) {
1007 // Formatter
1008 if (expression is SimpleIdentifier) {
1009 SimpleIdentifier identifier = expression;
1010 Element element = identifier.bestElement;
1011 if (element is AngularElement) {
1012 _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, _cr eateLocationForIdentifier(identifier));
1013 return;
1014 }
1015 }
1016 // index as a normal Dart expression
1017 expression.accept(_indexContributor);
1018 }
1019
1020 @override
1021 Object visitHtmlUnit(ht.HtmlUnit node) {
1022 _htmlUnitElement = node.element;
1023 CompilationUnitElement dartUnitElement = _htmlUnitElement.angularCompilation Unit;
1024 _indexContributor.enterScope(dartUnitElement);
1025 return super.visitHtmlUnit(node);
1026 }
1027
1028 @override
1029 Object visitXmlAttributeNode(ht.XmlAttributeNode node) {
1030 Element element = node.element;
1031 if (element != null) {
1032 ht.Token nameToken = node.nameToken;
1033 Location location = _createLocationForToken(nameToken);
1034 _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, locat ion);
1035 }
1036 return super.visitXmlAttributeNode(node);
1037 }
1038
1039 @override
1040 Object visitXmlTagNode(ht.XmlTagNode node) {
1041 Element element = node.element;
1042 if (element != null) {
1043 // tag
1044 {
1045 ht.Token tagToken = node.tagToken;
1046 Location location = _createLocationForToken(tagToken);
1047 _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, loc ation);
1048 }
1049 // maybe add closing tag range
1050 ht.Token closingTag = node.closingTag;
1051 if (closingTag != null) {
1052 Location location = _createLocationForToken(closingTag);
1053 _store.recordRelationship(element, IndexConstants.ANGULAR_CLOSING_TAG_RE FERENCE, location);
1054 }
1055 }
1056 return super.visitXmlTagNode(node);
1057 }
1058
1059 Location _createLocationForIdentifier(SimpleIdentifier identifier) => new Loca tion(_htmlUnitElement, identifier.offset, identifier.length);
1060
1061 Location _createLocationForToken(ht.Token token) => new Location(_htmlUnitElem ent, token.offset, token.length);
1062 }
1063
1064 class IndexContributor_AngularHtmlIndexContributor extends IndexContributor {
1065 final AngularHtmlIndexContributor AngularHtmlIndexContributor_this;
1066
1067 IndexContributor_AngularHtmlIndexContributor(IndexStore arg0, this.AngularHtml IndexContributor_this) : super(arg0);
1068
1069 @override
1070 Element peekElement() => AngularHtmlIndexContributor_this._htmlUnitElement;
1071
1072 @override
1073 void recordRelationship(Element element, Relationship relationship, Location l ocation) {
1074 AngularElement angularElement = AngularHtmlUnitResolver.getAngularElement(el ement);
1075 if (angularElement != null) {
1076 element = angularElement;
1077 relationship = IndexConstants.ANGULAR_REFERENCE;
1078 }
1079 super.recordRelationship(element, relationship, location);
1080 }
1081 }
1082
1083 /**
1084 * The interface [Index] defines the behavior of objects that maintain an index storing
1085 * [Relationship] between [Element]. All of the operations
1086 * defined on the index are asynchronous, and results, when there are any, are p rovided through a
1087 * callback.
1088 *
1089 * Despite being asynchronous, the results of the operations are guaranteed to b e consistent with
1090 * the expectation that operations are performed in the order in which they are requested.
1091 * Modification operations are executed before any read operation. There is no g uarantee about the
1092 * order in which the callbacks for read operations will be invoked.
1093 */
1094 abstract class Index {
1095 /**
1096 * Asynchronously invoke the given callback with an array containing all of th e locations of the
1097 * elements that have the given relationship with the given element. For examp le, if the element
1098 * represents a method and the relationship is the is-referenced-by relationsh ip, then the
1099 * locations that will be passed into the callback will be all of the places w here the method is
1100 * invoked.
1101 *
1102 * @param element the element that has the relationship with the locations to be returned
1103 * @param relationship the relationship between the given element and the loca tions to be returned
1104 * @param callback the callback that will be invoked when the locations are fo und
1105 */
1106 void getRelationships(Element element, Relationship relationship, Relationship Callback callback);
1107
1108 /**
1109 * Answer index statistics.
1110 */
1111 String get statistics;
1112
1113 /**
1114 * Asynchronously process the given [HtmlUnit] in order to record the relation ships.
1115 *
1116 * @param context the [AnalysisContext] in which [HtmlUnit] was resolved
1117 * @param unit the [HtmlUnit] being indexed
1118 */
1119 void indexHtmlUnit(AnalysisContext context, ht.HtmlUnit unit);
1120
1121 /**
1122 * Asynchronously process the given [CompilationUnit] in order to record the r elationships.
1123 *
1124 * @param context the [AnalysisContext] in which [CompilationUnit] was resolve d
1125 * @param unit the [CompilationUnit] being indexed
1126 */
1127 void indexUnit(AnalysisContext context, CompilationUnit unit);
1128
1129 /**
1130 * Asynchronously remove from the index all of the information associated with the given context.
1131 *
1132 * This method should be invoked when a context is disposed.
1133 *
1134 * @param context the [AnalysisContext] to remove
1135 */
1136 void removeContext(AnalysisContext context);
1137
1138 /**
1139 * Asynchronously remove from the index all of the information associated with elements or
1140 * locations in the given source. This includes relationships between an eleme nt in the given
1141 * source and any other locations, relationships between any other elements an d a location within
1142 * the given source.
1143 *
1144 * This method should be invoked when a source is no longer part of the code b ase.
1145 *
1146 * @param context the [AnalysisContext] in which [Source] being removed
1147 * @param source the [Source] being removed
1148 */
1149 void removeSource(AnalysisContext context, Source source);
1150
1151 /**
1152 * Asynchronously remove from the index all of the information associated with elements or
1153 * locations in the given sources. This includes relationships between an elem ent in the given
1154 * sources and any other locations, relationships between any other elements a nd a location within
1155 * the given sources.
1156 *
1157 * This method should be invoked when multiple sources are no longer part of t he code base.
1158 *
1159 * @param the [AnalysisContext] in which [Source]s being removed
1160 * @param container the [SourceContainer] holding the sources being removed
1161 */
1162 void removeSources(AnalysisContext context, SourceContainer container);
1163
1164 /**
1165 * Should be called in separate [Thread] to process request in this [Index]. D oes not
1166 * return until the [stop] method is called.
1167 */
1168 void run();
1169
1170 /**
1171 * Should be called to stop process running [run], so stop processing requests .
1172 */
1173 void stop();
1174 }
1175
1176 /**
1177 * Container of information computed by the index - relationships between elemen ts.
1178 */
1179 abstract class IndexStore {
1180 /**
1181 * Notifies the index store that we are going to index the unit with the given element.
1182 *
1183 * If the unit is a part of a library, then all its locations are removed. If it is a defining
1184 * compilation unit of a library, then index store also checks if some previou sly indexed parts of
1185 * the library are not parts of the library anymore, and clears their informat ion.
1186 *
1187 * @param the [AnalysisContext] in which unit being indexed
1188 * @param unitElement the element of the unit being indexed
1189 * @return `true` the given [AnalysisContext] is active, or `false` if it was
1190 * removed before, so no any unit may be indexed with it
1191 */
1192 bool aboutToIndexDart(AnalysisContext context, CompilationUnitElement unitElem ent);
1193
1194 /**
1195 * Notifies the index store that we are going to index the given [HtmlElement] .
1196 *
1197 * @param the [AnalysisContext] in which unit being indexed
1198 * @param htmlElement the [HtmlElement] being indexed
1199 * @return `true` the given [AnalysisContext] is active, or `false` if it was
1200 * removed before, so no any unit may be indexed with it
1201 */
1202 bool aboutToIndexHtml(AnalysisContext context, HtmlElement htmlElement);
1203
1204 /**
1205 * Return the locations of the elements that have the given relationship with the given element.
1206 * For example, if the element represents a method and the relationship is the is-referenced-by
1207 * relationship, then the returned locations will be all of the places where t he method is
1208 * invoked.
1209 *
1210 * @param element the the element that has the relationship with the locations to be returned
1211 * @param relationship the [Relationship] between the given element and the lo cations to be
1212 * returned
1213 * @return the locations that have the given relationship with the given eleme nt
1214 */
1215 List<Location> getRelationships(Element element, Relationship relationship);
1216
1217 /**
1218 * Answer index statistics.
1219 */
1220 String get statistics;
1221
1222 /**
1223 * Record that the given element and location have the given relationship. For example, if the
1224 * relationship is the is-referenced-by relationship, then the element would b e the element being
1225 * referenced and the location would be the point at which it is referenced. E ach element can have
1226 * the same relationship with multiple locations. In other words, if the follo wing code were
1227 * executed
1228 *
1229 * <pre>
1230 * recordRelationship(element, isReferencedBy, location1);
1231 * recordRelationship(element, isReferencedBy, location2);
1232 * </pre>
1233 *
1234 * then both relationships would be maintained in the index and the result of executing
1235 *
1236 * <pre>
1237 * getRelationship(element, isReferencedBy);
1238 * </pre>
1239 *
1240 * would be an array containing both <code>location1</code> and <code>location 2</code>.
1241 *
1242 * @param element the element that is related to the location
1243 * @param relationship the [Relationship] between the element and the location
1244 * @param location the [Location] where relationship happens
1245 */
1246 void recordRelationship(Element element, Relationship relationship, Location l ocation);
1247
1248 /**
1249 * Remove from the index all of the information associated with [AnalysisConte xt].
1250 *
1251 * This method should be invoked when a context is disposed.
1252 *
1253 * @param the [AnalysisContext] being removed
1254 */
1255 void removeContext(AnalysisContext context);
1256
1257 /**
1258 * Remove from the index all of the information associated with elements or lo cations in the given
1259 * source. This includes relationships between an element in the given source and any other
1260 * locations, relationships between any other elements and a location within t he given source.
1261 *
1262 * This method should be invoked when a source is no longer part of the code b ase.
1263 *
1264 * @param the [AnalysisContext] in which [Source] being removed
1265 * @param source the source being removed
1266 */
1267 void removeSource(AnalysisContext context, Source source);
1268
1269 /**
1270 * Remove from the index all of the information associated with elements or lo cations in the given
1271 * sources. This includes relationships between an element in the given source s and any other
1272 * locations, relationships between any other elements and a location within t he given sources.
1273 *
1274 * This method should be invoked when multiple sources are no longer part of t he code base.
1275 *
1276 * @param the [AnalysisContext] in which [Source]s being removed
1277 * @param container the [SourceContainer] holding the sources being removed
1278 */
1279 void removeSources(AnalysisContext context, SourceContainer container);
1280 }
1281
1282 /**
1283 * Implementation of [UniverseElement].
1284 */
1285 class UniverseElementImpl extends ElementImpl implements UniverseElement {
1286 static UniverseElementImpl INSTANCE = new UniverseElementImpl();
1287
1288 UniverseElementImpl() : super("--universe--", -1);
1289
1290 @override
1291 accept(ElementVisitor visitor) => null;
1292
1293 @override
1294 ElementKind get kind => ElementKind.UNIVERSE;
1295 }
1296
1297 /**
1298 * Visits resolved AST and adds relationships into [IndexStore]. 1254 * Visits resolved AST and adds relationships into [IndexStore].
1299 */ 1255 */
1300 class IndexContributor extends GeneralizingAstVisitor<Object> { 1256 class IndexContributor extends GeneralizingAstVisitor<Object> {
1301 /** 1257 /**
1302 * @return the [Location] representing location of the [Element]. 1258 * @return the [Location] representing location of the [Element].
1303 */ 1259 */
1304 static Location createLocation(Element element) { 1260 static Location createLocation(Element element) {
1305 if (element != null) { 1261 if (element != null) {
1306 int offset = element.nameOffset; 1262 int offset = element.nameOffset;
1307 int length = element.displayName.length; 1263 int length = element.displayName.length;
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
2147 * Information about [ImportElement] and place where it is referenced using 2103 * Information about [ImportElement] and place where it is referenced using
2148 * [PrefixElement]. 2104 * [PrefixElement].
2149 */ 2105 */
2150 class IndexContributor_ImportElementInfo { 2106 class IndexContributor_ImportElementInfo {
2151 ImportElement _element; 2107 ImportElement _element;
2152 2108
2153 int _periodEnd = 0; 2109 int _periodEnd = 0;
2154 } 2110 }
2155 2111
2156 /** 2112 /**
2157 * Special [Element] which is used to index references to the name without speci fying concrete 2113 * The interface [Index] defines the behavior of objects that maintain an index storing
2158 * kind of this name - field, method or something else. 2114 * [Relationship] between [Element]. All of the operations
2159 */ 2115 * defined on the index are asynchronous, and results, when there are any, are p rovided through a
2160 class NameElementImpl extends ElementImpl { 2116 * callback.
2161 NameElementImpl(String name) : super("name:${name}", -1); 2117 *
2162 2118 * Despite being asynchronous, the results of the operations are guaranteed to b e consistent with
2163 @override 2119 * the expectation that operations are performed in the order in which they are requested.
2164 accept(ElementVisitor visitor) => null; 2120 * Modification operations are executed before any read operation. There is no g uarantee about the
2165 2121 * order in which the callbacks for read operations will be invoked.
2166 @override 2122 */
2167 ElementKind get kind => ElementKind.NAME; 2123 abstract class Index {
2168 } 2124 /**
2169 2125 * Asynchronously invoke the given callback with an array containing all of th e locations of the
2170 /** 2126 * elements that have the given relationship with the given element. For examp le, if the element
2171 * Visits resolved [CompilationUnit] and adds Angular specific relationships int o 2127 * represents a method and the relationship is the is-referenced-by relationsh ip, then the
2172 * [IndexStore]. 2128 * locations that will be passed into the callback will be all of the places w here the method is
2173 */ 2129 * invoked.
2174 class AngularDartIndexContributor extends GeneralizingAstVisitor<Object> { 2130 *
2175 final IndexStore _store; 2131 * @param element the element that has the relationship with the locations to be returned
2176 2132 * @param relationship the relationship between the given element and the loca tions to be returned
2177 AngularDartIndexContributor(this._store); 2133 * @param callback the callback that will be invoked when the locations are fo und
2178 2134 */
2179 @override 2135 void getRelationships(Element element, Relationship relationship, Relationship Callback callback);
2180 Object visitClassDeclaration(ClassDeclaration node) { 2136
2181 ClassElement classElement = node.element; 2137 /**
2182 if (classElement != null) { 2138 * Answer index statistics.
2183 List<ToolkitObjectElement> toolkitObjects = classElement.toolkitObjects; 2139 */
2184 for (ToolkitObjectElement object in toolkitObjects) { 2140 String get statistics;
2185 if (object is AngularComponentElement) { 2141
2186 _indexComponent(object); 2142 /**
2187 } 2143 * Asynchronously process the given [HtmlUnit] in order to record the relation ships.
2188 if (object is AngularDecoratorElement) { 2144 *
2189 AngularDecoratorElement directive = object; 2145 * @param context the [AnalysisContext] in which [HtmlUnit] was resolved
2190 _indexDirective(directive); 2146 * @param unit the [HtmlUnit] being indexed
2191 } 2147 */
2192 } 2148 void indexHtmlUnit(AnalysisContext context, ht.HtmlUnit unit);
2193 } 2149
2194 // stop visiting 2150 /**
2195 return null; 2151 * Asynchronously process the given [CompilationUnit] in order to record the r elationships.
2196 } 2152 *
2197 2153 * @param context the [AnalysisContext] in which [CompilationUnit] was resolve d
2198 @override 2154 * @param unit the [CompilationUnit] being indexed
2199 Object visitCompilationUnitMember(CompilationUnitMember node) => null; 2155 */
2200 2156 void indexUnit(AnalysisContext context, CompilationUnit unit);
2201 void _indexComponent(AngularComponentElement component) { 2157
2202 _indexProperties(component.properties); 2158 /**
2203 } 2159 * Asynchronously remove from the index all of the information associated with the given context.
2204 2160 *
2205 void _indexDirective(AngularDecoratorElement directive) { 2161 * This method should be invoked when a context is disposed.
2206 _indexProperties(directive.properties); 2162 *
2207 } 2163 * @param context the [AnalysisContext] to remove
2208 2164 */
2209 /** 2165 void removeContext(AnalysisContext context);
2210 * Index [FieldElement] references from [AngularPropertyElement]s. 2166
2211 */ 2167 /**
2212 void _indexProperties(List<AngularPropertyElement> properties) { 2168 * Asynchronously remove from the index all of the information associated with elements or
2213 for (AngularPropertyElement property in properties) { 2169 * locations in the given source. This includes relationships between an eleme nt in the given
2214 FieldElement field = property.field; 2170 * source and any other locations, relationships between any other elements an d a location within
2215 if (field != null) { 2171 * the given source.
2216 int offset = property.fieldNameOffset; 2172 *
2217 if (offset == -1) { 2173 * This method should be invoked when a source is no longer part of the code b ase.
2218 continue; 2174 *
2219 } 2175 * @param context the [AnalysisContext] in which [Source] being removed
2220 int length = field.name.length; 2176 * @param source the [Source] being removed
2221 Location location = new Location(property, offset, length); 2177 */
2222 // getter reference 2178 void removeSource(AnalysisContext context, Source source);
2223 if (property.propertyKind.callsGetter()) { 2179
2224 PropertyAccessorElement getter = field.getter; 2180 /**
2225 if (getter != null) { 2181 * Asynchronously remove from the index all of the information associated with elements or
2226 _store.recordRelationship(getter, IndexConstants.IS_REFERENCED_BY_QU ALIFIED, location); 2182 * locations in the given sources. This includes relationships between an elem ent in the given
2227 } 2183 * sources and any other locations, relationships between any other elements a nd a location within
2228 } 2184 * the given sources.
2229 // setter reference 2185 *
2230 if (property.propertyKind.callsSetter()) { 2186 * This method should be invoked when multiple sources are no longer part of t he code base.
2231 PropertyAccessorElement setter = field.setter; 2187 *
2232 if (setter != null) { 2188 * @param the [AnalysisContext] in which [Source]s being removed
2233 _store.recordRelationship(setter, IndexConstants.IS_REFERENCED_BY_QU ALIFIED, location); 2189 * @param container the [SourceContainer] holding the sources being removed
2234 } 2190 */
2235 } 2191 void removeSources(AnalysisContext context, SourceContainer container);
2236 } 2192
2237 } 2193 /**
2238 } 2194 * Should be called in separate [Thread] to process request in this [Index]. D oes not
2195 * return until the [stop] method is called.
2196 */
2197 void run();
2198
2199 /**
2200 * Should be called to stop process running [run], so stop processing requests .
2201 */
2202 void stop();
2239 } 2203 }
2240 2204
2241 /** 2205 /**
2242 * Instances of the [RemoveContextOperation] implement an operation that removes from the 2206 * Instances of the [RemoveContextOperation] implement an operation that removes from the
2243 * index any data based on the specified [AnalysisContext]. 2207 * index any data based on the specified [AnalysisContext].
2244 */ 2208 */
2245 class RemoveContextOperation implements IndexOperation { 2209 class RemoveContextOperation implements IndexOperation {
2246 /** 2210 /**
2247 * The index store against which this operation is being run. 2211 * The index store against which this operation is being run.
2248 */ 2212 */
(...skipping 21 matching lines...) Expand all
2270 } 2234 }
2271 2235
2272 @override 2236 @override
2273 bool removeWhenSourceRemoved(Source source) => false; 2237 bool removeWhenSourceRemoved(Source source) => false;
2274 2238
2275 @override 2239 @override
2276 String toString() => "RemoveContext(${context})"; 2240 String toString() => "RemoveContext(${context})";
2277 } 2241 }
2278 2242
2279 /** 2243 /**
2280 * Instances of the [IndexHtmlUnitOperation] implement an operation that adds da ta to the 2244 * Instances of the [GetRelationshipsOperation] implement an operation used to a ccess the
2281 * index based on the resolved [HtmlUnit]. 2245 * locations that have a specified relationship with a specified element.
2282 */ 2246 */
2283 class IndexHtmlUnitOperation implements IndexOperation { 2247 class GetRelationshipsOperation implements IndexOperation {
2248 final IndexStore _indexStore;
2249
2250 final Element element;
2251
2252 final Relationship relationship;
2253
2254 final RelationshipCallback callback;
2255
2256 /**
2257 * Initialize a newly created operation that will access the locations that ha ve a specified
2258 * relationship with a specified element.
2259 */
2260 GetRelationshipsOperation(this._indexStore, this.element, this.relationship, t his.callback);
2261
2262 @override
2263 bool get isQuery => true;
2264
2265 @override
2266 void performOperation() {
2267 List<Location> locations;
2268 locations = _indexStore.getRelationships(element, relationship);
2269 callback.hasRelationships(element, relationship, locations);
2270 }
2271
2272 @override
2273 bool removeWhenSourceRemoved(Source source) => false;
2274
2275 @override
2276 String toString() => "GetRelationships(${element}, ${relationship})";
2277 }
2278
2279 /**
2280 * Instances of the [RemoveSourceOperation] implement an operation that removes from the index
2281 * any data based on the content of a specified source.
2282 */
2283 class RemoveSourceOperation implements IndexOperation {
2284 /** 2284 /**
2285 * The index store against which this operation is being run. 2285 * The index store against which this operation is being run.
2286 */ 2286 */
2287 final IndexStore _indexStore; 2287 final IndexStore _indexStore;
2288 2288
2289 /** 2289 /**
2290 * The context in which [HtmlUnit] was resolved. 2290 * The context in which source being removed.
2291 */ 2291 */
2292 final AnalysisContext _context; 2292 final AnalysisContext _context;
2293 2293
2294 /** 2294 /**
2295 * The [HtmlUnit] being indexed. 2295 * The source being removed.
2296 */ 2296 */
2297 final ht.HtmlUnit unit; 2297 final Source source;
2298 2298
2299 /** 2299 /**
2300 * The element of the [HtmlUnit] being indexed. 2300 * Initialize a newly created operation that will remove the specified resourc e.
2301 */
2302 HtmlElement _htmlElement;
2303
2304 /**
2305 * The source being indexed.
2306 */
2307 Source _source;
2308
2309 /**
2310 * Initialize a newly created operation that will index the specified [HtmlUni t].
2311 * 2301 *
2312 * @param indexStore the index store against which this operation is being run 2302 * @param indexStore the index store against which this operation is being run
2313 * @param context the context in which [HtmlUnit] was resolved 2303 * @param context the [AnalysisContext] to remove source in
2314 * @param unit the fully resolved [HtmlUnit] 2304 * @param source the [Source] to remove from index
2315 */ 2305 */
2316 IndexHtmlUnitOperation(this._indexStore, this._context, this.unit) { 2306 RemoveSourceOperation(this._indexStore, this._context, this.source);
2317 this._htmlElement = unit.element; 2307
2318 this._source = _htmlElement.source; 2308 @override
2309 bool get isQuery => false;
2310
2311 @override
2312 void performOperation() {
2313 _indexStore.removeSource(_context, source);
2319 } 2314 }
2320 2315
2321 /** 2316 @override
2322 * @return the [Source] to be indexed. 2317 bool removeWhenSourceRemoved(Source source) => false;
2323 */ 2318
2324 Source get source => _source; 2319 @override
2325 2320 String toString() => "RemoveSource(${source.fullName})";
2326 @override 2321 }
2327 bool get isQuery => false; 2322
2328 2323 /**
2329 @override 2324 * The interface [IndexOperation] defines the behavior of objects used to perfor m operations
2330 void performOperation() { 2325 * on an index.
2331 try { 2326 */
2332 bool mayIndex = _indexStore.aboutToIndexHtml(_context, _htmlElement); 2327 abstract class IndexOperation {
2333 if (!mayIndex) { 2328 /**
2334 return; 2329 * Return `true` if this operation returns information from the index.
2335 } 2330 *
2336 AngularHtmlIndexContributor contributor = new AngularHtmlIndexContributor( _indexStore); 2331 * @return `true` if this operation returns information from the index
2337 unit.accept(contributor); 2332 */
2338 } catch (exception) { 2333 bool get isQuery;
2339 AnalysisEngine.instance.logger.logError2("Could not index ${unit.element.l ocation}", exception); 2334
2335 /**
2336 * Perform the operation implemented by this operation.
2337 */
2338 void performOperation();
2339
2340 /**
2341 * Return `true` if this operation should be removed from the operation queue when the
2342 * given resource has been removed.
2343 *
2344 * @param source the [Source] that has been removed
2345 * @return `true` if this operation should be removed from the operation queue as a
2346 * result of removing the resource
2347 */
2348 bool removeWhenSourceRemoved(Source source);
2349 }
2350
2351 /**
2352 * [IndexStore] which keeps all information in memory, but can write it to strea m and read
2353 * later.
2354 */
2355 abstract class MemoryIndexStore implements IndexStore {
2356 }
2357
2358 /**
2359 * [Location] with attached data.
2360 */
2361 class LocationWithData<D> extends Location {
2362 final D data;
2363
2364 LocationWithData.con1(Location location, this.data) : super(location.element, location.offset, location.length);
2365
2366 LocationWithData.con2(Element element, int offset, int length, this.data) : su per(element, offset, length);
2367
2368 @override
2369 Location newClone() => new LocationWithData<D>.con2(element, offset, length, d ata);
2370 }
2371
2372 /**
2373 * Relationship between an element and a location. Relationships are identified by a globally unique
2374 * identifier.
2375 */
2376 class Relationship {
2377 /**
2378 * The unique identifier for this relationship.
2379 */
2380 final String _uniqueId;
2381
2382 /**
2383 * A table mapping relationship identifiers to relationships.
2384 */
2385 static Map<String, Relationship> _RelationshipMap = {};
2386
2387 /**
2388 * Return the relationship with the given unique identifier.
2389 *
2390 * @param uniqueId the unique identifier for the relationship
2391 * @return the relationship with the given unique identifier
2392 */
2393 static Relationship getRelationship(String uniqueId) {
2394 Relationship relationship = _RelationshipMap[uniqueId];
2395 if (relationship == null) {
2396 relationship = new Relationship(uniqueId);
2397 _RelationshipMap[uniqueId] = relationship;
2340 } 2398 }
2399 return relationship;
2341 } 2400 }
2342 2401
2343 @override 2402 /**
2344 bool removeWhenSourceRemoved(Source source) => this._source == source; 2403 * @return all registered [Relationship]s.
2345 2404 */
2346 @override 2405 static Iterable<Relationship> values() => _RelationshipMap.values;
2347 String toString() => "IndexHtmlUnitOperation(${_source.fullName})"; 2406
2348 } 2407 /**
2349 2408 * Initialize a newly created relationship to have the given unique identifier .
2350 /** 2409 *
2410 * @param uniqueId the unique identifier for this relationship
2411 */
2412 Relationship(this._uniqueId);
2413
2414 /**
2415 * Return the unique identifier for this relationship.
2416 *
2417 * @return the unique identifier for this relationship
2418 */
2419 String get identifier => _uniqueId;
2420
2421 @override
2422 String toString() => _uniqueId;
2423 }
2424
2425 /**
2351 * Instances of the class <code>Location</code> represent a location related to an element. The 2426 * Instances of the class <code>Location</code> represent a location related to an element. The
2352 * location is expressed as an offset and length, but the offset is relative to the resource 2427 * location is expressed as an offset and length, but the offset is relative to the resource
2353 * containing the element rather than the start of the element within that resou rce. 2428 * containing the element rather than the start of the element within that resou rce.
2354 */ 2429 */
2355 class Location { 2430 class Location {
2356 /** 2431 /**
2357 * An empty array of locations. 2432 * An empty array of locations.
2358 */ 2433 */
2359 static List<Location> EMPTY_ARRAY = new List<Location>(0); 2434 static List<Location> EMPTY_ARRAY = new List<Location>(0);
2360 2435
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2392 } 2467 }
2393 } 2468 }
2394 2469
2395 /** 2470 /**
2396 * Returns a clone of this [Location]. 2471 * Returns a clone of this [Location].
2397 */ 2472 */
2398 Location newClone() => new Location(element, offset, length); 2473 Location newClone() => new Location(element, offset, length);
2399 2474
2400 @override 2475 @override
2401 String toString() => "[${offset} - ${(offset + length)}) in ${element}"; 2476 String toString() => "[${offset} - ${(offset + length)}) in ${element}";
2402 }
2403
2404 /**
2405 * [IndexStore] which keeps all information in memory, but can write it to strea m and read
2406 * later.
2407 */
2408 abstract class MemoryIndexStore implements IndexStore {
2409 }
2410
2411 /**
2412 * Instances of the [GetRelationshipsOperation] implement an operation used to a ccess the
2413 * locations that have a specified relationship with a specified element.
2414 */
2415 class GetRelationshipsOperation implements IndexOperation {
2416 final IndexStore _indexStore;
2417
2418 final Element element;
2419
2420 final Relationship relationship;
2421
2422 final RelationshipCallback callback;
2423
2424 /**
2425 * Initialize a newly created operation that will access the locations that ha ve a specified
2426 * relationship with a specified element.
2427 */
2428 GetRelationshipsOperation(this._indexStore, this.element, this.relationship, t his.callback);
2429
2430 @override
2431 bool get isQuery => true;
2432
2433 @override
2434 void performOperation() {
2435 List<Location> locations;
2436 locations = _indexStore.getRelationships(element, relationship);
2437 callback.hasRelationships(element, relationship, locations);
2438 }
2439
2440 @override
2441 bool removeWhenSourceRemoved(Source source) => false;
2442
2443 @override
2444 String toString() => "GetRelationships(${element}, ${relationship})";
2445 }
2446
2447 /**
2448 * [Location] with attached data.
2449 */
2450 class LocationWithData<D> extends Location {
2451 final D data;
2452
2453 LocationWithData.con1(Location location, this.data) : super(location.element, location.offset, location.length);
2454
2455 LocationWithData.con2(Element element, int offset, int length, this.data) : su per(element, offset, length);
2456
2457 @override
2458 Location newClone() => new LocationWithData<D>.con2(element, offset, length, d ata);
2459 }
2460
2461 /**
2462 * The interface <code>RelationshipCallback</code> defines the behavior of objec ts that are invoked
2463 * with the results of a query about a given relationship.
2464 */
2465 abstract class RelationshipCallback {
2466 /**
2467 * This method is invoked when the locations that have a specified relationshi p with a specified
2468 * element are available. For example, if the element is a field and the relat ionship is the
2469 * is-referenced-by relationship, then this method will be invoked with each l ocation at which the
2470 * field is referenced.
2471 *
2472 * @param element the [Element] that has the relationship with the locations
2473 * @param relationship the relationship between the given element and the loca tions
2474 * @param locations the locations that were found
2475 */
2476 void hasRelationships(Element element, Relationship relationship, List<Locatio n> locations);
2477 } 2477 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698