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

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

Issue 1801883002: Remove old index and search implementations. (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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library services.src.index.index_contributor;
6
7 import 'dart:collection' show Queue;
8
9 import 'package:analysis_server/src/provisional/index/index_core.dart';
10 import 'package:analysis_server/src/services/correction/namespace.dart';
11 import 'package:analysis_server/src/services/index/index.dart';
12 import 'package:analysis_server/src/services/index/index_store.dart';
13 import 'package:analysis_server/src/services/index/indexable_element.dart';
14 import 'package:analysis_server/src/services/index/indexable_file.dart';
15 import 'package:analyzer/dart/ast/ast.dart';
16 import 'package:analyzer/dart/ast/token.dart';
17 import 'package:analyzer/dart/ast/visitor.dart';
18 import 'package:analyzer/dart/element/element.dart';
19 import 'package:analyzer/dart/element/type.dart';
20 import 'package:analyzer/src/generated/engine.dart';
21 import 'package:analyzer/src/generated/java_engine.dart';
22 import 'package:analyzer/src/generated/source.dart';
23
24 /**
25 * An [IndexContributor] that contributes relationships for Dart files.
26 */
27 class DartIndexContributor extends IndexContributor {
28 @override
29 void contributeTo(IndexStore store, AnalysisContext context, Object object) {
30 if (store is InternalIndexStore && object is CompilationUnit) {
31 _IndexContributor contributor = new _IndexContributor(store);
32 object.accept(contributor);
33 }
34 }
35 }
36
37 /**
38 * Visits a resolved AST and adds relationships into [InternalIndexStore].
39 */
40 class _IndexContributor extends GeneralizingAstVisitor {
41 final InternalIndexStore _store;
42
43 CompilationUnitElement _unitElement;
44 LibraryElement _libraryElement;
45
46 Map<ImportElement, Set<Element>> _importElementsMap = {};
47
48 /**
49 * A stack whose top element (the element with the largest index) is an
50 * element representing the inner-most enclosing scope.
51 */
52 Queue<Element> _elementStack = new Queue();
53
54 _IndexContributor(this._store);
55
56 /**
57 * Enter a new scope represented by the given [Element].
58 */
59 void enterScope(Element element) {
60 _elementStack.addFirst(element);
61 }
62
63 /**
64 * Return the inner-most enclosing [Element], wrapped as an indexable object,
65 * or `null` if there is no enclosing element.
66 */
67 IndexableElement peekElement() {
68 for (Element element in _elementStack) {
69 if (element != null) {
70 return new IndexableElement(element);
71 }
72 }
73 return null;
74 }
75
76 /**
77 * Record the given relationship between the given [Element] and
78 * [LocationImpl].
79 */
80 void recordRelationshipElement(
81 Element element, RelationshipImpl relationship, LocationImpl location) {
82 if (element != null && location != null) {
83 _store.recordRelationship(
84 new IndexableElement(element), relationship, location);
85 }
86 }
87
88 /**
89 * Record the given relationship between the given [IndexableObject] and
90 * [LocationImpl].
91 */
92 void recordRelationshipIndexable(IndexableObject indexable,
93 RelationshipImpl relationship, LocationImpl location) {
94 if (indexable != null && location != null) {
95 _store.recordRelationship(indexable, relationship, location);
96 }
97 }
98
99 @override
100 visitAssignmentExpression(AssignmentExpression node) {
101 _recordOperatorReference(node.operator, node.bestElement);
102 super.visitAssignmentExpression(node);
103 }
104
105 @override
106 visitBinaryExpression(BinaryExpression node) {
107 _recordOperatorReference(node.operator, node.bestElement);
108 super.visitBinaryExpression(node);
109 }
110
111 @override
112 visitClassDeclaration(ClassDeclaration node) {
113 ClassElement element = node.element;
114 enterScope(element);
115 try {
116 _recordTopLevelElementDefinition(element);
117 _recordHasAncestor(element);
118 {
119 ExtendsClause extendsClause = node.extendsClause;
120 if (extendsClause != null) {
121 TypeName superclassNode = extendsClause.superclass;
122 _recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY);
123 } else {
124 InterfaceType superType = element.supertype;
125 if (superType != null) {
126 ClassElement objectElement = superType.element;
127 recordRelationshipElement(
128 objectElement,
129 IndexConstants.IS_EXTENDED_BY,
130 _createLocationForOffset(node.name.offset, 0));
131 }
132 }
133 }
134 {
135 WithClause withClause = node.withClause;
136 if (withClause != null) {
137 for (TypeName mixinNode in withClause.mixinTypes) {
138 _recordSuperType(mixinNode, IndexConstants.IS_MIXED_IN_BY);
139 }
140 }
141 }
142 {
143 ImplementsClause implementsClause = node.implementsClause;
144 if (implementsClause != null) {
145 for (TypeName interfaceNode in implementsClause.interfaces) {
146 _recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY);
147 }
148 }
149 }
150 super.visitClassDeclaration(node);
151 } finally {
152 _exitScope();
153 }
154 }
155
156 @override
157 visitClassTypeAlias(ClassTypeAlias node) {
158 ClassElement element = node.element;
159 enterScope(element);
160 try {
161 _recordTopLevelElementDefinition(element);
162 _recordHasAncestor(element);
163 {
164 TypeName superclassNode = node.superclass;
165 if (superclassNode != null) {
166 _recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY);
167 }
168 }
169 {
170 WithClause withClause = node.withClause;
171 if (withClause != null) {
172 for (TypeName mixinNode in withClause.mixinTypes) {
173 _recordSuperType(mixinNode, IndexConstants.IS_MIXED_IN_BY);
174 }
175 }
176 }
177 {
178 ImplementsClause implementsClause = node.implementsClause;
179 if (implementsClause != null) {
180 for (TypeName interfaceNode in implementsClause.interfaces) {
181 _recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY);
182 }
183 }
184 }
185 super.visitClassTypeAlias(node);
186 } finally {
187 _exitScope();
188 }
189 }
190
191 @override
192 visitCompilationUnit(CompilationUnit node) {
193 _unitElement = node.element;
194 if (_unitElement != null) {
195 _elementStack.add(_unitElement);
196 _libraryElement = _unitElement.enclosingElement;
197 if (_libraryElement != null) {
198 super.visitCompilationUnit(node);
199 }
200 }
201 }
202
203 @override
204 visitConstructorDeclaration(ConstructorDeclaration node) {
205 ConstructorElement element = node.element;
206 enterScope(element);
207 try {
208 super.visitConstructorDeclaration(node);
209 } finally {
210 _exitScope();
211 }
212 }
213
214 @override
215 visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
216 SimpleIdentifier fieldName = node.fieldName;
217 Expression expression = node.expression;
218 // field reference is write here
219 if (fieldName != null) {
220 Element element = fieldName.staticElement;
221 LocationImpl location = _createLocationForNode(fieldName);
222 recordRelationshipElement(
223 element, IndexConstants.IS_WRITTEN_BY, location);
224 }
225 // index expression
226 if (expression != null) {
227 expression.accept(this);
228 }
229 }
230
231 @override
232 visitConstructorName(ConstructorName node) {
233 ConstructorElement element = node.staticElement;
234 // in 'class B = A;' actually A constructors are invoked
235 if (element != null &&
236 element.isSynthetic &&
237 element.redirectedConstructor != null) {
238 element = element.redirectedConstructor;
239 }
240 // prepare location
241 LocationImpl location;
242 if (node.name != null) {
243 int start = node.period.offset;
244 int end = node.name.end;
245 location = _createLocationForOffset(start, end - start);
246 } else {
247 int start = node.type.end;
248 location = _createLocationForOffset(start, 0);
249 }
250 // record relationship
251 recordRelationshipElement(
252 element, IndexConstants.IS_REFERENCED_BY, location);
253 super.visitConstructorName(node);
254 }
255
256 @override
257 visitDeclaredIdentifier(DeclaredIdentifier node) {
258 LocalVariableElement element = node.element;
259 enterScope(element);
260 try {
261 super.visitDeclaredIdentifier(node);
262 } finally {
263 _exitScope();
264 }
265 }
266
267 @override
268 visitEnumDeclaration(EnumDeclaration node) {
269 ClassElement element = node.element;
270 enterScope(element);
271 try {
272 _recordTopLevelElementDefinition(element);
273 super.visitEnumDeclaration(node);
274 } finally {
275 _exitScope();
276 }
277 }
278
279 @override
280 visitExportDirective(ExportDirective node) {
281 ExportElement element = node.element;
282 if (element != null) {
283 LibraryElement expLibrary = element.exportedLibrary;
284 _recordLibraryReference(node, expLibrary);
285 }
286 _recordUriFileReference(node);
287 super.visitExportDirective(node);
288 }
289
290 @override
291 visitFormalParameter(FormalParameter node) {
292 ParameterElement element = node.element;
293 enterScope(element);
294 try {
295 super.visitFormalParameter(node);
296 } finally {
297 _exitScope();
298 }
299 }
300
301 @override
302 visitFunctionDeclaration(FunctionDeclaration node) {
303 Element element = node.element;
304 _recordTopLevelElementDefinition(element);
305 enterScope(element);
306 try {
307 super.visitFunctionDeclaration(node);
308 } finally {
309 _exitScope();
310 }
311 }
312
313 @override
314 visitFunctionTypeAlias(FunctionTypeAlias node) {
315 Element element = node.element;
316 _recordTopLevelElementDefinition(element);
317 super.visitFunctionTypeAlias(node);
318 }
319
320 @override
321 visitImportDirective(ImportDirective node) {
322 ImportElement element = node.element;
323 if (element != null) {
324 LibraryElement impLibrary = element.importedLibrary;
325 _recordLibraryReference(node, impLibrary);
326 }
327 _recordUriFileReference(node);
328 super.visitImportDirective(node);
329 }
330
331 @override
332 visitIndexExpression(IndexExpression node) {
333 MethodElement element = node.bestElement;
334 if (element is MethodElement) {
335 Token operator = node.leftBracket;
336 LocationImpl location =
337 _createLocationForToken(operator, element != null);
338 recordRelationshipElement(
339 element, IndexConstants.IS_INVOKED_BY, location);
340 }
341 super.visitIndexExpression(node);
342 }
343
344 @override
345 visitMethodDeclaration(MethodDeclaration node) {
346 ExecutableElement element = node.element;
347 enterScope(element);
348 try {
349 super.visitMethodDeclaration(node);
350 } finally {
351 _exitScope();
352 }
353 }
354
355 @override
356 visitMethodInvocation(MethodInvocation node) {
357 SimpleIdentifier name = node.methodName;
358 LocationImpl location = _createLocationForNode(name);
359 // name invocation
360 recordRelationshipIndexable(
361 new IndexableName(name.name), IndexConstants.IS_INVOKED_BY, location);
362 // element invocation
363 Element element = name.bestElement;
364 if (element is MethodElement ||
365 element is PropertyAccessorElement ||
366 element is FunctionElement ||
367 element is VariableElement) {
368 recordRelationshipElement(
369 element, IndexConstants.IS_INVOKED_BY, location);
370 } else if (element is ClassElement) {
371 recordRelationshipElement(
372 element, IndexConstants.IS_REFERENCED_BY, location);
373 }
374 _recordImportElementReferenceWithoutPrefix(name);
375 super.visitMethodInvocation(node);
376 }
377
378 @override
379 visitPartDirective(PartDirective node) {
380 Element element = node.element;
381 LocationImpl location = _createLocationForNode(node.uri);
382 recordRelationshipElement(
383 element, IndexConstants.IS_REFERENCED_BY, location);
384 _recordUriFileReference(node);
385 super.visitPartDirective(node);
386 }
387
388 @override
389 visitPartOfDirective(PartOfDirective node) {
390 LocationImpl location = _createLocationForNode(node.libraryName);
391 recordRelationshipElement(
392 node.element, IndexConstants.IS_REFERENCED_BY, location);
393 }
394
395 @override
396 visitPostfixExpression(PostfixExpression node) {
397 _recordOperatorReference(node.operator, node.bestElement);
398 super.visitPostfixExpression(node);
399 }
400
401 @override
402 visitPrefixExpression(PrefixExpression node) {
403 _recordOperatorReference(node.operator, node.bestElement);
404 super.visitPrefixExpression(node);
405 }
406
407 @override
408 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
409 ConstructorElement element = node.staticElement;
410 LocationImpl location;
411 if (node.constructorName != null) {
412 int start = node.period.offset;
413 int end = node.constructorName.end;
414 location = _createLocationForOffset(start, end - start);
415 } else {
416 int start = node.thisKeyword.end;
417 location = _createLocationForOffset(start, 0);
418 }
419 recordRelationshipElement(
420 element, IndexConstants.IS_REFERENCED_BY, location);
421 super.visitRedirectingConstructorInvocation(node);
422 }
423
424 @override
425 visitSimpleIdentifier(SimpleIdentifier node) {
426 IndexableName indexableName = new IndexableName(node.name);
427 LocationImpl location = _createLocationForNode(node);
428 if (location == null) {
429 return;
430 }
431 // name in declaration
432 if (node.inDeclarationContext()) {
433 recordRelationshipIndexable(
434 indexableName, IndexConstants.NAME_IS_DEFINED_BY, location);
435 return;
436 }
437 // prepare information
438 Element element = node.bestElement;
439 // stop if already handled
440 if (_isAlreadyHandledName(node)) {
441 return;
442 }
443 // record name read/write
444 if (element != null && element.enclosingElement is ClassElement ||
445 element == null && location.isQualified) {
446 bool inGetterContext = node.inGetterContext();
447 bool inSetterContext = node.inSetterContext();
448 if (inGetterContext && inSetterContext) {
449 recordRelationshipIndexable(
450 indexableName, IndexConstants.IS_READ_WRITTEN_BY, location);
451 } else if (inGetterContext) {
452 recordRelationshipIndexable(
453 indexableName, IndexConstants.IS_READ_BY, location);
454 } else if (inSetterContext) {
455 recordRelationshipIndexable(
456 indexableName, IndexConstants.IS_WRITTEN_BY, location);
457 }
458 }
459 // this.field parameter
460 if (element is FieldFormalParameterElement) {
461 RelationshipImpl relationship = peekElement().element == element
462 ? IndexConstants.IS_WRITTEN_BY
463 : IndexConstants.IS_REFERENCED_BY;
464 recordRelationshipElement(element.field, relationship, location);
465 return;
466 }
467 // record specific relations
468 if (element is ClassElement ||
469 element is FunctionElement ||
470 element is FunctionTypeAliasElement ||
471 element is LabelElement ||
472 element is MethodElement ||
473 element is PropertyAccessorElement ||
474 element is PropertyInducingElement ||
475 element is TypeParameterElement) {
476 recordRelationshipElement(
477 element, IndexConstants.IS_REFERENCED_BY, location);
478 } else if (element is PrefixElement) {
479 recordRelationshipElement(
480 element, IndexConstants.IS_REFERENCED_BY, location);
481 _recordImportElementReferenceWithPrefix(node);
482 } else if (element is ParameterElement || element is LocalVariableElement) {
483 bool inGetterContext = node.inGetterContext();
484 bool inSetterContext = node.inSetterContext();
485 if (inGetterContext && inSetterContext) {
486 recordRelationshipElement(
487 element, IndexConstants.IS_READ_WRITTEN_BY, location);
488 } else if (inGetterContext) {
489 recordRelationshipElement(element, IndexConstants.IS_READ_BY, location);
490 } else if (inSetterContext) {
491 recordRelationshipElement(
492 element, IndexConstants.IS_WRITTEN_BY, location);
493 } else {
494 recordRelationshipElement(
495 element, IndexConstants.IS_REFERENCED_BY, location);
496 }
497 }
498 _recordImportElementReferenceWithoutPrefix(node);
499 super.visitSimpleIdentifier(node);
500 }
501
502 @override
503 visitSuperConstructorInvocation(SuperConstructorInvocation node) {
504 ConstructorElement element = node.staticElement;
505 LocationImpl location;
506 if (node.constructorName != null) {
507 int start = node.period.offset;
508 int end = node.constructorName.end;
509 location = _createLocationForOffset(start, end - start);
510 } else {
511 int start = node.superKeyword.end;
512 location = _createLocationForOffset(start, 0);
513 }
514 recordRelationshipElement(
515 element, IndexConstants.IS_REFERENCED_BY, location);
516 super.visitSuperConstructorInvocation(node);
517 }
518
519 @override
520 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
521 VariableDeclarationList variables = node.variables;
522 for (VariableDeclaration variableDeclaration in variables.variables) {
523 Element element = variableDeclaration.element;
524 _recordTopLevelElementDefinition(element);
525 }
526 super.visitTopLevelVariableDeclaration(node);
527 }
528
529 @override
530 visitTypeParameter(TypeParameter node) {
531 TypeParameterElement element = node.element;
532 enterScope(element);
533 try {
534 super.visitTypeParameter(node);
535 } finally {
536 _exitScope();
537 }
538 }
539
540 @override
541 visitVariableDeclaration(VariableDeclaration node) {
542 VariableElement element = node.element;
543 // record declaration
544 {
545 SimpleIdentifier name = node.name;
546 LocationImpl location = _createLocationForNode(name);
547 location = _getLocationWithExpressionType(location, node.initializer);
548 recordRelationshipElement(
549 element, IndexConstants.NAME_IS_DEFINED_BY, location);
550 }
551 // visit
552 enterScope(element);
553 try {
554 super.visitVariableDeclaration(node);
555 } finally {
556 _exitScope();
557 }
558 }
559
560 @override
561 visitVariableDeclarationList(VariableDeclarationList node) {
562 NodeList<VariableDeclaration> variables = node.variables;
563 if (variables != null) {
564 // use first VariableDeclaration as Element for Location(s) in type
565 {
566 TypeName type = node.type;
567 if (type != null) {
568 for (VariableDeclaration variableDeclaration in variables) {
569 enterScope(variableDeclaration.element);
570 try {
571 type.accept(this);
572 } finally {
573 _exitScope();
574 }
575 // only one iteration
576 break;
577 }
578 }
579 }
580 // visit variables
581 variables.accept(this);
582 }
583 }
584
585 /**
586 * @return the [LocationImpl] representing location of the [AstNode].
587 */
588 LocationImpl _createLocationForNode(AstNode node) {
589 bool isQualified = _isQualifiedClassMemberAccess(node);
590 bool isResolved = true;
591 if (node is SimpleIdentifier) {
592 isResolved = node.bestElement != null;
593 }
594 IndexableObject indexable = peekElement();
595 return new LocationImpl(indexable, node.offset, node.length,
596 isQualified: isQualified, isResolved: isResolved);
597 }
598
599 /**
600 * [offset] - the offset of the location within [Source].
601 * [length] - the length of the location.
602 *
603 * Returns the [LocationImpl] representing the given offset and length within the
604 * inner-most [Element].
605 */
606 LocationImpl _createLocationForOffset(int offset, int length) {
607 IndexableObject element = peekElement();
608 return new LocationImpl(element, offset, length);
609 }
610
611 /**
612 * @return the [LocationImpl] representing location of the [Token].
613 */
614 LocationImpl _createLocationForToken(Token token, bool isResolved) {
615 IndexableObject element = peekElement();
616 return new LocationImpl(element, token.offset, token.length,
617 isQualified: true, isResolved: isResolved);
618 }
619
620 /**
621 * Exit the current scope.
622 */
623 void _exitScope() {
624 _elementStack.removeFirst();
625 }
626
627 /**
628 * @return `true` if given node already indexed as more interesting reference, so it should
629 * not be indexed again.
630 */
631 bool _isAlreadyHandledName(SimpleIdentifier node) {
632 AstNode parent = node.parent;
633 if (parent is MethodInvocation) {
634 return parent.methodName == node;
635 }
636 return false;
637 }
638
639 bool _isQualifiedClassMemberAccess(AstNode node) {
640 if (node is SimpleIdentifier) {
641 AstNode parent = node.parent;
642 if (parent is PrefixedIdentifier && parent.identifier == node) {
643 return parent.prefix.staticElement is! PrefixElement;
644 }
645 if (parent is PropertyAccess && parent.propertyName == node) {
646 return parent.realTarget != null;
647 }
648 if (parent is MethodInvocation && parent.methodName == node) {
649 Expression target = parent.realTarget;
650 if (target is SimpleIdentifier &&
651 target.staticElement is PrefixElement) {
652 return false;
653 }
654 return target != null;
655 }
656 }
657 return false;
658 }
659
660 void _recordHasAncestor(ClassElement element) {
661 int offset = element.nameOffset;
662 int length = element.nameLength;
663 LocationImpl location = _createLocationForOffset(offset, length);
664 _recordHasAncestor0(location, element, false, <ClassElement>[]);
665 }
666
667 void _recordHasAncestor0(LocationImpl location, ClassElement element,
668 bool includeThis, List<ClassElement> visitedElements) {
669 if (element == null) {
670 return;
671 }
672 if (visitedElements.contains(element)) {
673 return;
674 }
675 visitedElements.add(element);
676 if (includeThis) {
677 recordRelationshipElement(element, IndexConstants.HAS_ANCESTOR, location);
678 }
679 {
680 InterfaceType superType = element.supertype;
681 if (superType != null) {
682 _recordHasAncestor0(location, superType.element, true, visitedElements);
683 }
684 }
685 for (InterfaceType mixinType in element.mixins) {
686 _recordHasAncestor0(location, mixinType.element, true, visitedElements);
687 }
688 for (InterfaceType implementedType in element.interfaces) {
689 _recordHasAncestor0(
690 location, implementedType.element, true, visitedElements);
691 }
692 }
693
694 /**
695 * Records [ImportElement] reference if given [SimpleIdentifier] references so me
696 * top-level element and not qualified with import prefix.
697 */
698 void _recordImportElementReferenceWithoutPrefix(SimpleIdentifier node) {
699 if (_isIdentifierInImportCombinator(node)) {
700 return;
701 }
702 if (_isIdentifierInPrefixedIdentifier(node)) {
703 return;
704 }
705 Element element = node.staticElement;
706 ImportElement importElement = internal_getImportElement(
707 _libraryElement, null, element, _importElementsMap);
708 if (importElement != null) {
709 LocationImpl location = _createLocationForOffset(node.offset, 0);
710 recordRelationshipElement(
711 importElement, IndexConstants.IS_REFERENCED_BY, location);
712 }
713 }
714
715 /**
716 * Records [ImportElement] that declares given prefix and imports library with element used
717 * with given prefix node.
718 */
719 void _recordImportElementReferenceWithPrefix(SimpleIdentifier prefixNode) {
720 ImportElementInfo info = internal_getImportElementInfo(prefixNode);
721 if (info != null) {
722 int offset = prefixNode.offset;
723 int length = info.periodEnd - offset;
724 LocationImpl location = _createLocationForOffset(offset, length);
725 recordRelationshipElement(
726 info.element, IndexConstants.IS_REFERENCED_BY, location);
727 }
728 }
729
730 /**
731 * Records reference to defining [CompilationUnitElement] of the given
732 * [LibraryElement].
733 */
734 void _recordLibraryReference(UriBasedDirective node, LibraryElement library) {
735 if (library != null) {
736 LocationImpl location = _createLocationForNode(node.uri);
737 recordRelationshipElement(library.definingCompilationUnit,
738 IndexConstants.IS_REFERENCED_BY, location);
739 }
740 }
741
742 /**
743 * Record reference to the given operator [Element] and name.
744 */
745 void _recordOperatorReference(Token operator, Element element) {
746 // prepare location
747 LocationImpl location = _createLocationForToken(operator, element != null);
748 // record name reference
749 {
750 String name = operator.lexeme;
751 if (name == "++") {
752 name = "+";
753 }
754 if (name == "--") {
755 name = "-";
756 }
757 if (StringUtilities.endsWithChar(name, 0x3D) && name != "==") {
758 name = name.substring(0, name.length - 1);
759 }
760 IndexableName indexableName = new IndexableName(name);
761 recordRelationshipIndexable(
762 indexableName, IndexConstants.IS_INVOKED_BY, location);
763 }
764 // record element reference
765 if (element != null) {
766 recordRelationshipElement(
767 element, IndexConstants.IS_INVOKED_BY, location);
768 }
769 }
770
771 /**
772 * Records a relation between [superNode] and its [Element].
773 */
774 void _recordSuperType(TypeName superNode, RelationshipImpl relationship) {
775 if (superNode != null) {
776 Identifier superName = superNode.name;
777 if (superName != null) {
778 Element superElement = superName.staticElement;
779 recordRelationshipElement(
780 superElement, relationship, _createLocationForNode(superNode));
781 }
782 }
783 }
784
785 /**
786 * Records the [Element] definition in the library and universe.
787 */
788 void _recordTopLevelElementDefinition(Element element) {
789 if (element != null) {
790 IndexableElement indexable = new IndexableElement(element);
791 int offset = element.nameOffset;
792 int length = element.nameLength;
793 LocationImpl location = new LocationImpl(indexable, offset, length);
794 recordRelationshipElement(
795 _libraryElement, IndexConstants.DEFINES, location);
796 _store.recordTopLevelDeclaration(element);
797 }
798 }
799
800 void _recordUriFileReference(UriBasedDirective directive) {
801 Source source = directive.source;
802 if (source != null) {
803 LocationImpl location = new LocationImpl(
804 new IndexableFile(_unitElement.source.fullName),
805 directive.uri.offset,
806 directive.uri.length);
807 _store.recordRelationship(new IndexableFile(source.fullName),
808 IndexConstants.IS_REFERENCED_BY, location);
809 }
810 }
811
812 /**
813 * If the given expression has resolved type, returns the new location with th is type.
814 *
815 * [location] - the base location
816 * [expression] - the expression assigned at the given location
817 */
818 static LocationImpl _getLocationWithExpressionType(
819 LocationImpl location, Expression expression) {
820 if (expression != null) {
821 return new LocationWithData<DartType>(location, expression.bestType);
822 }
823 return location;
824 }
825
826 /**
827 * @return `true` if given "node" is part of an import [Combinator].
828 */
829 static bool _isIdentifierInImportCombinator(SimpleIdentifier node) {
830 AstNode parent = node.parent;
831 return parent is Combinator;
832 }
833
834 /**
835 * @return `true` if given "node" is part of [PrefixedIdentifier] "prefix.node ".
836 */
837 static bool _isIdentifierInPrefixedIdentifier(SimpleIdentifier node) {
838 AstNode parent = node.parent;
839 return parent is PrefixedIdentifier && parent.identifier == node;
840 }
841 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698