| Index: pkg/analyzer/lib/src/index/index.dart
|
| diff --git a/pkg/analyzer/lib/src/index/index.dart b/pkg/analyzer/lib/src/index/index.dart
|
| deleted file mode 100644
|
| index db0e350b52bf7cbf94bc70ecd3dc267247434dd1..0000000000000000000000000000000000000000
|
| --- a/pkg/analyzer/lib/src/index/index.dart
|
| +++ /dev/null
|
| @@ -1,1193 +0,0 @@
|
| -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -// This code was auto-generated, is not intended to be edited, and is subject to
|
| -// significant change. Please see the README file for more information.
|
| -
|
| -library engine.src.index;
|
| -
|
| -import 'dart:collection' show Queue;
|
| -
|
| -import 'package:analyzer/index/index.dart';
|
| -import 'package:analyzer/index/index_store.dart';
|
| -import 'package:analyzer/src/generated/ast.dart';
|
| -import 'package:analyzer/src/generated/element.dart';
|
| -import 'package:analyzer/src/generated/engine.dart';
|
| -import 'package:analyzer/src/generated/html.dart' as ht;
|
| -import 'package:analyzer/src/generated/java_core.dart';
|
| -import 'package:analyzer/src/generated/java_engine.dart';
|
| -import 'package:analyzer/src/generated/resolver.dart';
|
| -import 'package:analyzer/src/generated/scanner.dart';
|
| -import 'package:analyzer/src/generated/source.dart';
|
| -
|
| -
|
| -/**
|
| - * Adds data to [store] based on the resolved Dart [unit].
|
| - */
|
| -void indexDartUnit(IndexStore store, AnalysisContext context,
|
| - CompilationUnit unit) {
|
| - CompilationUnitElement unitElement = unit.element;
|
| - bool mayIndex = store.aboutToIndexDart(context, unitElement);
|
| - if (!mayIndex) {
|
| - return;
|
| - }
|
| - unit.accept(new _IndexContributor(store));
|
| - unit.accept(new _AngularDartIndexContributor(store));
|
| - store.doneIndex();
|
| -}
|
| -
|
| -
|
| -/**
|
| - * Adds data to [store] based on the resolved HTML [unit].
|
| - */
|
| -void indexHtmlUnit(IndexStore store, AnalysisContext context, ht.HtmlUnit unit)
|
| - {
|
| - HtmlElement unitElement = unit.element;
|
| - bool mayIndex = store.aboutToIndexHtml(context, unitElement);
|
| - if (!mayIndex) {
|
| - return;
|
| - }
|
| - unit.accept(new _AngularHtmlIndexContributor(store));
|
| - store.doneIndex();
|
| -}
|
| -
|
| -
|
| -/**
|
| - * Visits resolved [CompilationUnit] and adds Angular specific relationships
|
| - * into [IndexStore].
|
| - */
|
| -class _AngularDartIndexContributor extends GeneralizingAstVisitor<Object> {
|
| - final IndexStore _store;
|
| -
|
| - _AngularDartIndexContributor(this._store);
|
| -
|
| - @override
|
| - Object visitClassDeclaration(ClassDeclaration node) {
|
| - ClassElement classElement = node.element;
|
| - if (classElement != null) {
|
| - List<ToolkitObjectElement> toolkitObjects = classElement.toolkitObjects;
|
| - for (ToolkitObjectElement object in toolkitObjects) {
|
| - if (object is AngularComponentElement) {
|
| - _indexComponent(object);
|
| - }
|
| - if (object is AngularDecoratorElement) {
|
| - AngularDecoratorElement directive = object;
|
| - _indexDirective(directive);
|
| - }
|
| - }
|
| - }
|
| - // stop visiting
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - Object visitCompilationUnitMember(CompilationUnitMember node) => null;
|
| -
|
| - void _indexComponent(AngularComponentElement component) {
|
| - _indexProperties(component.properties);
|
| - }
|
| -
|
| - void _indexDirective(AngularDecoratorElement directive) {
|
| - _indexProperties(directive.properties);
|
| - }
|
| -
|
| - /**
|
| - * Index [FieldElement] references from [AngularPropertyElement]s.
|
| - */
|
| - void _indexProperties(List<AngularPropertyElement> properties) {
|
| - for (AngularPropertyElement property in properties) {
|
| - FieldElement field = property.field;
|
| - if (field != null) {
|
| - int offset = property.fieldNameOffset;
|
| - if (offset == -1) {
|
| - continue;
|
| - }
|
| - int length = field.name.length;
|
| - Location location = new Location(property, offset, length);
|
| - // getter reference
|
| - if (property.propertyKind.callsGetter()) {
|
| - PropertyAccessorElement getter = field.getter;
|
| - if (getter != null) {
|
| - _store.recordRelationship(getter,
|
| - IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
|
| - }
|
| - }
|
| - // setter reference
|
| - if (property.propertyKind.callsSetter()) {
|
| - PropertyAccessorElement setter = field.setter;
|
| - if (setter != null) {
|
| - _store.recordRelationship(setter,
|
| - IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| -/**
|
| - * Visits resolved [HtmlUnit] and adds relationships into [IndexStore].
|
| - */
|
| -class _AngularHtmlIndexContributor extends _ExpressionVisitor {
|
| - /**
|
| - * The [IndexStore] to record relations into.
|
| - */
|
| - final IndexStore _store;
|
| -
|
| - /**
|
| - * The index contributor used to index Dart [Expression]s.
|
| - */
|
| - _IndexContributor _indexContributor;
|
| -
|
| - HtmlElement _htmlUnitElement;
|
| -
|
| - /**
|
| - * Initialize a newly created Angular HTML index contributor.
|
| - *
|
| - * [store] - the [IndexStore] to record relations into.
|
| - */
|
| - _AngularHtmlIndexContributor(this._store) {
|
| - _indexContributor = new _AngularHtmlIndexContributor_forEmbeddedDart(_store,
|
| - this);
|
| - }
|
| -
|
| - @override
|
| - void visitExpression(Expression expression) {
|
| - // Formatter
|
| - if (expression is SimpleIdentifier) {
|
| - Element element = expression.bestElement;
|
| - if (element is AngularElement) {
|
| - _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE,
|
| - _createLocationForIdentifier(expression));
|
| - return;
|
| - }
|
| - }
|
| - // index as a normal Dart expression
|
| - expression.accept(_indexContributor);
|
| - }
|
| -
|
| - @override
|
| - Object visitHtmlUnit(ht.HtmlUnit node) {
|
| - _htmlUnitElement = node.element;
|
| - CompilationUnitElement dartUnitElement =
|
| - _htmlUnitElement.angularCompilationUnit;
|
| - _indexContributor.enterScope(dartUnitElement);
|
| - return super.visitHtmlUnit(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitXmlAttributeNode(ht.XmlAttributeNode node) {
|
| - Element element = node.element;
|
| - if (element != null) {
|
| - ht.Token nameToken = node.nameToken;
|
| - Location location = _createLocationForToken(nameToken);
|
| - _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE,
|
| - location);
|
| - }
|
| - return super.visitXmlAttributeNode(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitXmlTagNode(ht.XmlTagNode node) {
|
| - Element element = node.element;
|
| - if (element != null) {
|
| - // tag
|
| - {
|
| - ht.Token tagToken = node.tagToken;
|
| - Location location = _createLocationForToken(tagToken);
|
| - _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE,
|
| - location);
|
| - }
|
| - // maybe add closing tag range
|
| - ht.Token closingTag = node.closingTag;
|
| - if (closingTag != null) {
|
| - Location location = _createLocationForToken(closingTag);
|
| - _store.recordRelationship(element,
|
| - IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE, location);
|
| - }
|
| - }
|
| - return super.visitXmlTagNode(node);
|
| - }
|
| -
|
| - Location _createLocationForIdentifier(SimpleIdentifier identifier) =>
|
| - new Location(_htmlUnitElement, identifier.offset, identifier.length);
|
| -
|
| - Location _createLocationForToken(ht.Token token) => new Location(
|
| - _htmlUnitElement, token.offset, token.length);
|
| -}
|
| -
|
| -
|
| -class _AngularHtmlIndexContributor_forEmbeddedDart extends _IndexContributor {
|
| - final _AngularHtmlIndexContributor angularContributor;
|
| -
|
| - _AngularHtmlIndexContributor_forEmbeddedDart(IndexStore store,
|
| - this.angularContributor) : super(store);
|
| -
|
| - @override
|
| - Element peekElement() => angularContributor._htmlUnitElement;
|
| -
|
| - @override
|
| - void recordRelationship(Element element, Relationship relationship,
|
| - Location location) {
|
| - AngularElement angularElement = AngularHtmlUnitResolver.getAngularElement(
|
| - element);
|
| - if (angularElement != null) {
|
| - element = angularElement;
|
| - relationship = IndexConstants.ANGULAR_REFERENCE;
|
| - }
|
| - super.recordRelationship(element, relationship, location);
|
| - }
|
| -}
|
| -
|
| -
|
| -/**
|
| - * Recursively visits an [HtmlUnit] and every embedded [Expression].
|
| - */
|
| -abstract class _ExpressionVisitor extends ht.RecursiveXmlVisitor<Object> {
|
| - /**
|
| - * Visits the given [Expression]s embedded into tag or attribute.
|
| - *
|
| - * [expression] - the [Expression] to visit, not `null`
|
| - */
|
| - void visitExpression(Expression expression);
|
| -
|
| - @override
|
| - Object visitXmlAttributeNode(ht.XmlAttributeNode node) {
|
| - _visitExpressions(node.expressions);
|
| - return super.visitXmlAttributeNode(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitXmlTagNode(ht.XmlTagNode node) {
|
| - _visitExpressions(node.expressions);
|
| - return super.visitXmlTagNode(node);
|
| - }
|
| -
|
| - /**
|
| - * Visits [Expression]s of the given [XmlExpression]s.
|
| - */
|
| - void _visitExpressions(List<ht.XmlExpression> expressions) {
|
| - for (ht.XmlExpression xmlExpression in expressions) {
|
| - if (xmlExpression is AngularXmlExpression) {
|
| - AngularXmlExpression angularXmlExpression = xmlExpression;
|
| - List<Expression> dartExpressions =
|
| - angularXmlExpression.expression.expressions;
|
| - for (Expression dartExpression in dartExpressions) {
|
| - visitExpression(dartExpression);
|
| - }
|
| - }
|
| - if (xmlExpression is ht.RawXmlExpression) {
|
| - ht.RawXmlExpression rawXmlExpression = xmlExpression;
|
| - visitExpression(rawXmlExpression.expression);
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| -/**
|
| - * Information about [ImportElement] and place where it is referenced using
|
| - * [PrefixElement].
|
| - */
|
| -class _ImportElementInfo {
|
| - ImportElement _element;
|
| -
|
| - int _periodEnd = 0;
|
| -}
|
| -
|
| -
|
| -/**
|
| - * Visits a resolved AST and adds relationships into [IndexStore].
|
| - */
|
| -class _IndexContributor extends GeneralizingAstVisitor<Object> {
|
| - final IndexStore _store;
|
| -
|
| - LibraryElement _libraryElement;
|
| -
|
| - Map<ImportElement, Set<Element>> _importElementsMap = {};
|
| -
|
| - /**
|
| - * A stack whose top element (the element with the largest index) is an element representing the
|
| - * inner-most enclosing scope.
|
| - */
|
| - Queue<Element> _elementStack = new Queue();
|
| -
|
| - _IndexContributor(this._store);
|
| -
|
| - /**
|
| - * Enter a new scope represented by the given [Element].
|
| - */
|
| - void enterScope(Element element) {
|
| - _elementStack.addFirst(element);
|
| - }
|
| -
|
| - /**
|
| - * @return the inner-most enclosing [Element], may be `null`.
|
| - */
|
| - Element peekElement() {
|
| - for (Element element in _elementStack) {
|
| - if (element != null) {
|
| - return element;
|
| - }
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * Record the given relationship between the given [Element] and [Location].
|
| - */
|
| - void recordRelationship(Element element, Relationship relationship,
|
| - Location location) {
|
| - if (element != null && location != null) {
|
| - _store.recordRelationship(element, relationship, location);
|
| - }
|
| - }
|
| -
|
| - @override
|
| - Object visitAssignmentExpression(AssignmentExpression node) {
|
| - _recordOperatorReference(node.operator, node.bestElement);
|
| - return super.visitAssignmentExpression(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitBinaryExpression(BinaryExpression node) {
|
| - _recordOperatorReference(node.operator, node.bestElement);
|
| - return super.visitBinaryExpression(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitClassDeclaration(ClassDeclaration node) {
|
| - ClassElement element = node.element;
|
| - enterScope(element);
|
| - try {
|
| - _recordElementDefinition(element, IndexConstants.DEFINES_CLASS);
|
| - {
|
| - ExtendsClause extendsClause = node.extendsClause;
|
| - if (extendsClause != null) {
|
| - TypeName superclassNode = extendsClause.superclass;
|
| - _recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY);
|
| - } else {
|
| - InterfaceType superType = element.supertype;
|
| - if (superType != null) {
|
| - ClassElement objectElement = superType.element;
|
| - recordRelationship(objectElement, IndexConstants.IS_EXTENDED_BY,
|
| - _createLocationFromOffset(node.name.offset, 0));
|
| - }
|
| - }
|
| - }
|
| - {
|
| - WithClause withClause = node.withClause;
|
| - if (withClause != null) {
|
| - for (TypeName mixinNode in withClause.mixinTypes) {
|
| - _recordSuperType(mixinNode, IndexConstants.IS_MIXED_IN_BY);
|
| - }
|
| - }
|
| - }
|
| - {
|
| - ImplementsClause implementsClause = node.implementsClause;
|
| - if (implementsClause != null) {
|
| - for (TypeName interfaceNode in implementsClause.interfaces) {
|
| - _recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY);
|
| - }
|
| - }
|
| - }
|
| - return super.visitClassDeclaration(node);
|
| - } finally {
|
| - _exitScope();
|
| - }
|
| - }
|
| -
|
| - @override
|
| - Object visitClassTypeAlias(ClassTypeAlias node) {
|
| - ClassElement element = node.element;
|
| - enterScope(element);
|
| - try {
|
| - _recordElementDefinition(element, IndexConstants.DEFINES_CLASS_ALIAS);
|
| - {
|
| - TypeName superclassNode = node.superclass;
|
| - if (superclassNode != null) {
|
| - _recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY);
|
| - }
|
| - }
|
| - {
|
| - WithClause withClause = node.withClause;
|
| - if (withClause != null) {
|
| - for (TypeName mixinNode in withClause.mixinTypes) {
|
| - _recordSuperType(mixinNode, IndexConstants.IS_MIXED_IN_BY);
|
| - }
|
| - }
|
| - }
|
| - {
|
| - ImplementsClause implementsClause = node.implementsClause;
|
| - if (implementsClause != null) {
|
| - for (TypeName interfaceNode in implementsClause.interfaces) {
|
| - _recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY);
|
| - }
|
| - }
|
| - }
|
| - return super.visitClassTypeAlias(node);
|
| - } finally {
|
| - _exitScope();
|
| - }
|
| - }
|
| -
|
| - @override
|
| - Object visitCompilationUnit(CompilationUnit node) {
|
| - CompilationUnitElement unitElement = node.element;
|
| - if (unitElement != null) {
|
| - _elementStack.add(unitElement);
|
| - _libraryElement = unitElement.enclosingElement;
|
| - if (_libraryElement != null) {
|
| - return super.visitCompilationUnit(node);
|
| - }
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - Object visitConstructorDeclaration(ConstructorDeclaration node) {
|
| - ConstructorElement element = node.element;
|
| - // define
|
| - {
|
| - Location location;
|
| - if (node.name != null) {
|
| - int start = node.period.offset;
|
| - int end = node.name.end;
|
| - location = _createLocationFromOffset(start, end - start);
|
| - } else {
|
| - int start = node.returnType.end;
|
| - location = _createLocationFromOffset(start, 0);
|
| - }
|
| - recordRelationship(element, IndexConstants.IS_DEFINED_BY, location);
|
| - }
|
| - // visit children
|
| - enterScope(element);
|
| - try {
|
| - return super.visitConstructorDeclaration(node);
|
| - } finally {
|
| - _exitScope();
|
| - }
|
| - }
|
| -
|
| - @override
|
| - Object visitConstructorName(ConstructorName node) {
|
| - ConstructorElement element = node.staticElement;
|
| - // in 'class B = A;' actually A constructors are invoked
|
| - if (element != null && element.isSynthetic && element.redirectedConstructor
|
| - != null) {
|
| - element = element.redirectedConstructor;
|
| - }
|
| - // prepare location
|
| - Location location;
|
| - if (node.name != null) {
|
| - int start = node.period.offset;
|
| - int end = node.name.end;
|
| - location = _createLocationFromOffset(start, end - start);
|
| - } else {
|
| - int start = node.type.end;
|
| - location = _createLocationFromOffset(start, 0);
|
| - }
|
| - // record relationship
|
| - recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
|
| - return super.visitConstructorName(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitExportDirective(ExportDirective node) {
|
| - ExportElement element = node.element;
|
| - if (element != null) {
|
| - LibraryElement expLibrary = element.exportedLibrary;
|
| - _recordLibraryReference(node, expLibrary);
|
| - }
|
| - return super.visitExportDirective(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitFormalParameter(FormalParameter node) {
|
| - ParameterElement element = node.element;
|
| - enterScope(element);
|
| - try {
|
| - return super.visitFormalParameter(node);
|
| - } finally {
|
| - _exitScope();
|
| - }
|
| - }
|
| -
|
| - @override
|
| - Object visitFunctionDeclaration(FunctionDeclaration node) {
|
| - Element element = node.element;
|
| - _recordElementDefinition(element, IndexConstants.DEFINES_FUNCTION);
|
| - enterScope(element);
|
| - try {
|
| - return super.visitFunctionDeclaration(node);
|
| - } finally {
|
| - _exitScope();
|
| - }
|
| - }
|
| -
|
| - @override
|
| - Object visitFunctionTypeAlias(FunctionTypeAlias node) {
|
| - Element element = node.element;
|
| - _recordElementDefinition(element, IndexConstants.DEFINES_FUNCTION_TYPE);
|
| - return super.visitFunctionTypeAlias(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitImportDirective(ImportDirective node) {
|
| - ImportElement element = node.element;
|
| - if (element != null) {
|
| - LibraryElement impLibrary = element.importedLibrary;
|
| - _recordLibraryReference(node, impLibrary);
|
| - }
|
| - return super.visitImportDirective(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitIndexExpression(IndexExpression node) {
|
| - MethodElement element = node.bestElement;
|
| - if (element is MethodElement) {
|
| - Token operator = node.leftBracket;
|
| - Location location = _createLocationFromToken(operator);
|
| - recordRelationship(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
|
| - location);
|
| - }
|
| - return super.visitIndexExpression(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitMethodDeclaration(MethodDeclaration node) {
|
| - ExecutableElement element = node.element;
|
| - enterScope(element);
|
| - try {
|
| - return super.visitMethodDeclaration(node);
|
| - } finally {
|
| - _exitScope();
|
| - }
|
| - }
|
| -
|
| - @override
|
| - Object visitMethodInvocation(MethodInvocation node) {
|
| - SimpleIdentifier name = node.methodName;
|
| - Element element = name.bestElement;
|
| - if (element is MethodElement || element is PropertyAccessorElement) {
|
| - Location location = _createLocationFromNode(name);
|
| - Relationship relationship;
|
| - if (node.target != null) {
|
| - relationship = IndexConstants.IS_INVOKED_BY_QUALIFIED;
|
| - } else {
|
| - relationship = IndexConstants.IS_INVOKED_BY_UNQUALIFIED;
|
| - }
|
| - recordRelationship(element, relationship, location);
|
| - }
|
| - if (element is FunctionElement || element is VariableElement) {
|
| - Location location = _createLocationFromNode(name);
|
| - recordRelationship(element, IndexConstants.IS_INVOKED_BY, location);
|
| - }
|
| - // name invocation
|
| - {
|
| - Element nameElement = new NameElement(name.name);
|
| - Location location = _createLocationFromNode(name);
|
| - Relationship kind = element != null ?
|
| - IndexConstants.NAME_IS_INVOKED_BY_RESOLVED :
|
| - IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED;
|
| - _store.recordRelationship(nameElement, kind, location);
|
| - }
|
| - _recordImportElementReferenceWithoutPrefix(name);
|
| - return super.visitMethodInvocation(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitPartDirective(PartDirective node) {
|
| - Element element = node.element;
|
| - Location location = _createLocationFromNode(node.uri);
|
| - recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
|
| - return super.visitPartDirective(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitPartOfDirective(PartOfDirective node) {
|
| - Location location = _createLocationFromNode(node.libraryName);
|
| - recordRelationship(node.element, IndexConstants.IS_REFERENCED_BY, location);
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - Object visitPostfixExpression(PostfixExpression node) {
|
| - _recordOperatorReference(node.operator, node.bestElement);
|
| - return super.visitPostfixExpression(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitPrefixExpression(PrefixExpression node) {
|
| - _recordOperatorReference(node.operator, node.bestElement);
|
| - return super.visitPrefixExpression(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitSimpleIdentifier(SimpleIdentifier node) {
|
| - Element nameElement = new NameElement(node.name);
|
| - Location location = _createLocationFromNode(node);
|
| - // name in declaration
|
| - if (node.inDeclarationContext()) {
|
| - recordRelationship(nameElement, IndexConstants.IS_DEFINED_BY, location);
|
| - return null;
|
| - }
|
| - // prepare information
|
| - Element element = node.bestElement;
|
| - // qualified name reference
|
| - _recordQualifiedMemberReference(node, element, nameElement, location);
|
| - // stop if already handled
|
| - if (_isAlreadyHandledName(node)) {
|
| - return null;
|
| - }
|
| - // record name read/write
|
| - {
|
| - bool inGetterContext = node.inGetterContext();
|
| - bool inSetterContext = node.inSetterContext();
|
| - if (inGetterContext && inSetterContext) {
|
| - Relationship kind = element != null ?
|
| - IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED :
|
| - IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED;
|
| - _store.recordRelationship(nameElement, kind, location);
|
| - } else if (inGetterContext) {
|
| - Relationship kind = element != null ?
|
| - IndexConstants.NAME_IS_READ_BY_RESOLVED :
|
| - IndexConstants.NAME_IS_READ_BY_UNRESOLVED;
|
| - _store.recordRelationship(nameElement, kind, location);
|
| - } else if (inSetterContext) {
|
| - Relationship kind = element != null ?
|
| - IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED :
|
| - IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED;
|
| - _store.recordRelationship(nameElement, kind, location);
|
| - }
|
| - }
|
| - // record specific relations
|
| - if (element is ClassElement || element is FunctionElement || element is
|
| - FunctionTypeAliasElement || element is LabelElement || element is
|
| - TypeParameterElement) {
|
| - recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
|
| - } else if (element is FieldElement) {
|
| - location = _getLocationWithInitializerType(node, location);
|
| - recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
|
| - } else if (element is FieldFormalParameterElement) {
|
| - FieldFormalParameterElement fieldParameter = element;
|
| - FieldElement field = fieldParameter.field;
|
| - recordRelationship(field, IndexConstants.IS_REFERENCED_BY_QUALIFIED,
|
| - location);
|
| - } else if (element is PrefixElement) {
|
| - _recordImportElementReferenceWithPrefix(node);
|
| - } else if (element is PropertyAccessorElement || element is MethodElement) {
|
| - location = _getLocationWithTypeAssignedToField(node, element, location);
|
| - if (node.isQualified) {
|
| - recordRelationship(element, IndexConstants.IS_REFERENCED_BY_QUALIFIED,
|
| - location);
|
| - } else {
|
| - recordRelationship(element, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
|
| - location);
|
| - }
|
| - } else if (element is ParameterElement || element is LocalVariableElement) {
|
| - bool inGetterContext = node.inGetterContext();
|
| - bool inSetterContext = node.inSetterContext();
|
| - if (inGetterContext && inSetterContext) {
|
| - recordRelationship(element, IndexConstants.IS_READ_WRITTEN_BY,
|
| - location);
|
| - } else if (inGetterContext) {
|
| - recordRelationship(element, IndexConstants.IS_READ_BY, location);
|
| - } else if (inSetterContext) {
|
| - recordRelationship(element, IndexConstants.IS_WRITTEN_BY, location);
|
| - } else {
|
| - recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
|
| - }
|
| - }
|
| - _recordImportElementReferenceWithoutPrefix(node);
|
| - return super.visitSimpleIdentifier(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
|
| - ConstructorElement element = node.staticElement;
|
| - Location location;
|
| - if (node.constructorName != null) {
|
| - int start = node.period.offset;
|
| - int end = node.constructorName.end;
|
| - location = _createLocationFromOffset(start, end - start);
|
| - } else {
|
| - int start = node.keyword.end;
|
| - location = _createLocationFromOffset(start, 0);
|
| - }
|
| - recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
|
| - return super.visitSuperConstructorInvocation(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
|
| - VariableDeclarationList variables = node.variables;
|
| - for (VariableDeclaration variableDeclaration in variables.variables) {
|
| - Element element = variableDeclaration.element;
|
| - _recordElementDefinition(element, IndexConstants.DEFINES_VARIABLE);
|
| - }
|
| - return super.visitTopLevelVariableDeclaration(node);
|
| - }
|
| -
|
| - @override
|
| - Object visitTypeParameter(TypeParameter node) {
|
| - TypeParameterElement element = node.element;
|
| - enterScope(element);
|
| - try {
|
| - return super.visitTypeParameter(node);
|
| - } finally {
|
| - _exitScope();
|
| - }
|
| - }
|
| -
|
| - @override
|
| - Object visitVariableDeclaration(VariableDeclaration node) {
|
| - VariableElement element = node.element;
|
| - // record declaration
|
| - {
|
| - SimpleIdentifier name = node.name;
|
| - Location location = _createLocationFromNode(name);
|
| - location = _getLocationWithExpressionType(location, node.initializer);
|
| - recordRelationship(element, IndexConstants.IS_DEFINED_BY, location);
|
| - }
|
| - // visit
|
| - enterScope(element);
|
| - try {
|
| - return super.visitVariableDeclaration(node);
|
| - } finally {
|
| - _exitScope();
|
| - }
|
| - }
|
| -
|
| - @override
|
| - Object visitVariableDeclarationList(VariableDeclarationList node) {
|
| - NodeList<VariableDeclaration> variables = node.variables;
|
| - if (variables != null) {
|
| - // use first VariableDeclaration as Element for Location(s) in type
|
| - {
|
| - TypeName type = node.type;
|
| - if (type != null) {
|
| - for (VariableDeclaration variableDeclaration in variables) {
|
| - enterScope(variableDeclaration.element);
|
| - try {
|
| - type.accept(this);
|
| - } finally {
|
| - _exitScope();
|
| - }
|
| - // only one iteration
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - // visit variables
|
| - variables.accept(this);
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * @return the [Location] representing location of the [AstNode].
|
| - */
|
| - Location _createLocationFromNode(AstNode node) => _createLocationFromOffset(
|
| - node.offset, node.length);
|
| -
|
| - /**
|
| - * [offset] - the offset of the location within [Source].
|
| - * [length] - the length of the location.
|
| - *
|
| - * Returns the [Location] representing the given offset and length within the
|
| - * inner-most [Element].
|
| - */
|
| - Location _createLocationFromOffset(int offset, int length) {
|
| - Element element = peekElement();
|
| - return new Location(element, offset, length);
|
| - }
|
| -
|
| - /**
|
| - * @return the [Location] representing location of the [Token].
|
| - */
|
| - Location _createLocationFromToken(Token token) => _createLocationFromOffset(
|
| - token.offset, token.length);
|
| -
|
| - /**
|
| - * Exit the current scope.
|
| - */
|
| - void _exitScope() {
|
| - _elementStack.removeFirst();
|
| - }
|
| -
|
| - /**
|
| - * @return `true` if given node already indexed as more interesting reference, so it should
|
| - * not be indexed again.
|
| - */
|
| - bool _isAlreadyHandledName(SimpleIdentifier node) {
|
| - AstNode parent = node.parent;
|
| - if (parent is MethodInvocation) {
|
| - return identical(parent.methodName, node);
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - /**
|
| - * Records the [Element] definition in the library and universe.
|
| - */
|
| - void _recordElementDefinition(Element element, Relationship relationship) {
|
| - Location location = createLocation(element);
|
| - recordRelationship(_libraryElement, relationship, location);
|
| - recordRelationship(IndexConstants.UNIVERSE, relationship, location);
|
| - }
|
| -
|
| - /**
|
| - * Records [ImportElement] that declares given prefix and imports library with element used
|
| - * with given prefix node.
|
| - */
|
| - void _recordImportElementReferenceWithPrefix(SimpleIdentifier prefixNode) {
|
| - _ImportElementInfo info = getImportElementInfo(prefixNode);
|
| - if (info != null) {
|
| - int offset = prefixNode.offset;
|
| - int length = info._periodEnd - offset;
|
| - Location location = _createLocationFromOffset(offset, length);
|
| - recordRelationship(info._element, IndexConstants.IS_REFERENCED_BY,
|
| - location);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Records [ImportElement] reference if given [SimpleIdentifier] references some
|
| - * top-level element and not qualified with import prefix.
|
| - */
|
| - void _recordImportElementReferenceWithoutPrefix(SimpleIdentifier node) {
|
| - if (_isIdentifierInImportCombinator(node)) {
|
| - return;
|
| - }
|
| - if (_isIdentifierInPrefixedIdentifier(node)) {
|
| - return;
|
| - }
|
| - Element element = node.staticElement;
|
| - ImportElement importElement = _internalGetImportElement(_libraryElement,
|
| - null, element, _importElementsMap);
|
| - if (importElement != null) {
|
| - Location location = _createLocationFromOffset(node.offset, 0);
|
| - recordRelationship(importElement, IndexConstants.IS_REFERENCED_BY,
|
| - location);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Records reference to defining [CompilationUnitElement] of the given
|
| - * [LibraryElement].
|
| - */
|
| - void _recordLibraryReference(UriBasedDirective node, LibraryElement library) {
|
| - if (library != null) {
|
| - Location location = _createLocationFromNode(node.uri);
|
| - recordRelationship(library.definingCompilationUnit,
|
| - IndexConstants.IS_REFERENCED_BY, location);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Record reference to the given operator [Element] and name.
|
| - */
|
| - void _recordOperatorReference(Token operator, Element element) {
|
| - // prepare location
|
| - Location location = _createLocationFromToken(operator);
|
| - // record name reference
|
| - {
|
| - String name = operator.lexeme;
|
| - if (name == "++") {
|
| - name = "+";
|
| - }
|
| - if (name == "--") {
|
| - name = "-";
|
| - }
|
| - if (StringUtilities.endsWithChar(name, 0x3D) && name != "==") {
|
| - name = name.substring(0, name.length - 1);
|
| - }
|
| - Element nameElement = new NameElement(name);
|
| - Relationship relationship = element != null ?
|
| - IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED :
|
| - IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED;
|
| - recordRelationship(nameElement, relationship, location);
|
| - }
|
| - // record element reference
|
| - if (element != null) {
|
| - recordRelationship(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
|
| - location);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Records reference if the given [SimpleIdentifier] looks like a qualified property access
|
| - * or method invocation.
|
| - */
|
| - void _recordQualifiedMemberReference(SimpleIdentifier node, Element element,
|
| - Element nameElement, Location location) {
|
| - if (node.isQualified) {
|
| - Relationship relationship = element != null ?
|
| - IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED :
|
| - IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED;
|
| - recordRelationship(nameElement, relationship, location);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Records extends/implements relationships between given [ClassElement] and [Type] of
|
| - * "superNode".
|
| - */
|
| - void _recordSuperType(TypeName superNode, Relationship relationship) {
|
| - if (superNode != null) {
|
| - Identifier superName = superNode.name;
|
| - if (superName != null) {
|
| - Element superElement = superName.staticElement;
|
| - recordRelationship(superElement, relationship, _createLocationFromNode(
|
| - superNode));
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * @return the [Location] representing location of the [Element].
|
| - */
|
| - static Location createLocation(Element element) {
|
| - if (element != null) {
|
| - int offset = element.nameOffset;
|
| - int length = element.displayName.length;
|
| - return new Location(element, offset, length);
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * @return the [ImportElement] that is referenced by this node with [PrefixElement],
|
| - * may be `null`.
|
| - */
|
| - static ImportElement getImportElement(SimpleIdentifier prefixNode) {
|
| - _ImportElementInfo info = getImportElementInfo(prefixNode);
|
| - return info != null ? info._element : null;
|
| - }
|
| -
|
| - /**
|
| - * @return the [ImportElementInfo] with [ImportElement] that is referenced by this
|
| - * node with [PrefixElement], may be `null`.
|
| - */
|
| - static _ImportElementInfo getImportElementInfo(SimpleIdentifier prefixNode) {
|
| - _ImportElementInfo info = new _ImportElementInfo();
|
| - // prepare environment
|
| - AstNode parent = prefixNode.parent;
|
| - CompilationUnit unit = prefixNode.getAncestor((node) => node is
|
| - CompilationUnit);
|
| - LibraryElement libraryElement = unit.element.library;
|
| - // prepare used element
|
| - Element usedElement = null;
|
| - if (parent is PrefixedIdentifier) {
|
| - PrefixedIdentifier prefixed = parent;
|
| - if (identical(prefixed.prefix, prefixNode)) {
|
| - usedElement = prefixed.staticElement;
|
| - info._periodEnd = prefixed.period.end;
|
| - }
|
| - }
|
| - if (parent is MethodInvocation) {
|
| - MethodInvocation invocation = parent;
|
| - if (identical(invocation.target, prefixNode)) {
|
| - usedElement = invocation.methodName.staticElement;
|
| - info._periodEnd = invocation.period.end;
|
| - }
|
| - }
|
| - // we need used Element
|
| - if (usedElement == null) {
|
| - return null;
|
| - }
|
| - // find ImportElement
|
| - String prefix = prefixNode.name;
|
| - Map<ImportElement, Set<Element>> importElementsMap = {};
|
| - info._element = _internalGetImportElement(libraryElement, prefix,
|
| - usedElement, importElementsMap);
|
| - if (info._element == null) {
|
| - return null;
|
| - }
|
| - return info;
|
| - }
|
| -
|
| - /**
|
| - * If the given expression has resolved type, returns the new location with this type.
|
| - *
|
| - * [location] - the base location
|
| - * [expression] - the expression assigned at the given location
|
| - */
|
| - static Location _getLocationWithExpressionType(Location location,
|
| - Expression expression) {
|
| - if (expression != null) {
|
| - return new LocationWithData<DartType>(location, expression.bestType);
|
| - }
|
| - return location;
|
| - }
|
| -
|
| - /**
|
| - * If the given node is the part of the [ConstructorFieldInitializer], returns location with
|
| - * type of the initializer expression.
|
| - */
|
| - static Location _getLocationWithInitializerType(SimpleIdentifier node,
|
| - Location location) {
|
| - if (node.parent is ConstructorFieldInitializer) {
|
| - ConstructorFieldInitializer initializer = node.parent as
|
| - ConstructorFieldInitializer;
|
| - if (identical(initializer.fieldName, node)) {
|
| - location = _getLocationWithExpressionType(location,
|
| - initializer.expression);
|
| - }
|
| - }
|
| - return location;
|
| - }
|
| -
|
| - /**
|
| - * If the given identifier has a synthetic [PropertyAccessorElement], i.e.
|
| - * accessor for normal field, and it is LHS of assignment, then include [Type]
|
| - * of the assigned value into the [Location].
|
| - *
|
| - * [identifier] - the identifier to record location.
|
| - * [element] - the [Element] of the identifier.
|
| - * [location] - the raw location
|
| - *
|
| - * Returns the [Location] with the type of the assigned value
|
| - */
|
| - static Location
|
| - _getLocationWithTypeAssignedToField(SimpleIdentifier identifier,
|
| - Element element, Location location) {
|
| - // we need accessor
|
| - if (element is! PropertyAccessorElement) {
|
| - return location;
|
| - }
|
| - PropertyAccessorElement accessor = element as PropertyAccessorElement;
|
| - // should be setter
|
| - if (!accessor.isSetter) {
|
| - return location;
|
| - }
|
| - // accessor should be synthetic, i.e. field normal
|
| - if (!accessor.isSynthetic) {
|
| - return location;
|
| - }
|
| - // should be LHS of assignment
|
| - AstNode parent;
|
| - {
|
| - AstNode node = identifier;
|
| - parent = node.parent;
|
| - // new T().field = x;
|
| - if (parent is PropertyAccess) {
|
| - PropertyAccess propertyAccess = parent as PropertyAccess;
|
| - if (identical(propertyAccess.propertyName, node)) {
|
| - node = propertyAccess;
|
| - parent = propertyAccess.parent;
|
| - }
|
| - }
|
| - // obj.field = x;
|
| - if (parent is PrefixedIdentifier) {
|
| - PrefixedIdentifier prefixedIdentifier = parent as PrefixedIdentifier;
|
| - if (identical(prefixedIdentifier.identifier, node)) {
|
| - node = prefixedIdentifier;
|
| - parent = prefixedIdentifier.parent;
|
| - }
|
| - }
|
| - }
|
| - // OK, remember the type
|
| - if (parent is AssignmentExpression) {
|
| - AssignmentExpression assignment = parent as AssignmentExpression;
|
| - Expression rhs = assignment.rightHandSide;
|
| - location = _getLocationWithExpressionType(location, rhs);
|
| - }
|
| - // done
|
| - return location;
|
| - }
|
| -
|
| - /**
|
| - * @return the [ImportElement] that declares given [PrefixElement] and imports library
|
| - * with given "usedElement".
|
| - */
|
| - static ImportElement _internalGetImportElement(LibraryElement libraryElement,
|
| - String prefix, Element usedElement, Map<ImportElement,
|
| - Set<Element>> importElementsMap) {
|
| - // validate Element
|
| - if (usedElement == null) {
|
| - return null;
|
| - }
|
| - if (usedElement.enclosingElement is! CompilationUnitElement) {
|
| - return null;
|
| - }
|
| - LibraryElement usedLibrary = usedElement.library;
|
| - // find ImportElement that imports used library with used prefix
|
| - List<ImportElement> candidates = null;
|
| - for (ImportElement importElement in libraryElement.imports) {
|
| - // required library
|
| - if (importElement.importedLibrary != usedLibrary) {
|
| - continue;
|
| - }
|
| - // required prefix
|
| - PrefixElement prefixElement = importElement.prefix;
|
| - if (prefix == null) {
|
| - if (prefixElement != null) {
|
| - continue;
|
| - }
|
| - } else {
|
| - if (prefixElement == null) {
|
| - continue;
|
| - }
|
| - if (prefix != prefixElement.name) {
|
| - continue;
|
| - }
|
| - }
|
| - // no combinators => only possible candidate
|
| - if (importElement.combinators.length == 0) {
|
| - return importElement;
|
| - }
|
| - // OK, we have candidate
|
| - if (candidates == null) {
|
| - candidates = [];
|
| - }
|
| - candidates.add(importElement);
|
| - }
|
| - // no candidates, probably element is defined in this library
|
| - if (candidates == null) {
|
| - return null;
|
| - }
|
| - // one candidate
|
| - if (candidates.length == 1) {
|
| - return candidates[0];
|
| - }
|
| - // ensure that each ImportElement has set of elements
|
| - for (ImportElement importElement in candidates) {
|
| - if (importElementsMap.containsKey(importElement)) {
|
| - continue;
|
| - }
|
| - Namespace namespace = new NamespaceBuilder(
|
| - ).createImportNamespaceForDirective(importElement);
|
| - Set<Element> elements = new Set();
|
| - importElementsMap[importElement] = elements;
|
| - }
|
| - // use import namespace to choose correct one
|
| - for (MapEntry<ImportElement, Set<Element>> entry in getMapEntrySet(
|
| - importElementsMap)) {
|
| - if (entry.getValue().contains(usedElement)) {
|
| - return entry.getKey();
|
| - }
|
| - }
|
| - // not found
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * @return `true` if given "node" is part of an import [Combinator].
|
| - */
|
| - static bool _isIdentifierInImportCombinator(SimpleIdentifier node) {
|
| - AstNode parent = node.parent;
|
| - return parent is Combinator;
|
| - }
|
| -
|
| - /**
|
| - * @return `true` if given "node" is part of [PrefixedIdentifier] "prefix.node".
|
| - */
|
| - static bool _isIdentifierInPrefixedIdentifier(SimpleIdentifier node) {
|
| - AstNode parent = node.parent;
|
| - return parent is PrefixedIdentifier && identical(parent.identifier, node);
|
| - }
|
| -}
|
|
|