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

Unified Diff: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/index/IndexContributor.java

Issue 11787017: Initial implementation of MemoryIndexStoreImpl and IndexContributor. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update for review comments Created 7 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/index/IndexContributor.java
diff --git a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/index/IndexContributor.java b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/index/IndexContributor.java
index 323fa7c1cb28fd17337cf4c0f52a1808f89bb63c..24c26845593519dfeae6131435cf5449d301dad4 100644
--- a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/index/IndexContributor.java
+++ b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/index/IndexContributor.java
@@ -14,18 +14,263 @@
package com.google.dart.engine.internal.index;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import com.google.dart.engine.ast.ASTNode;
+import com.google.dart.engine.ast.ClassDeclaration;
+import com.google.dart.engine.ast.CompilationUnit;
+import com.google.dart.engine.ast.ExtendsClause;
+import com.google.dart.engine.ast.FunctionDeclaration;
+import com.google.dart.engine.ast.FunctionTypeAlias;
+import com.google.dart.engine.ast.ImplementsClause;
+import com.google.dart.engine.ast.MethodInvocation;
+import com.google.dart.engine.ast.PrefixedIdentifier;
+import com.google.dart.engine.ast.SimpleIdentifier;
+import com.google.dart.engine.ast.TopLevelVariableDeclaration;
+import com.google.dart.engine.ast.TypeName;
+import com.google.dart.engine.ast.VariableDeclaration;
+import com.google.dart.engine.ast.VariableDeclarationList;
import com.google.dart.engine.ast.visitor.RecursiveASTVisitor;
+import com.google.dart.engine.element.ClassElement;
+import com.google.dart.engine.element.CompilationUnitElement;
+import com.google.dart.engine.element.Element;
+import com.google.dart.engine.element.ElementProxy;
+import com.google.dart.engine.element.FieldElement;
+import com.google.dart.engine.element.LibraryElement;
import com.google.dart.engine.index.IndexStore;
+import com.google.dart.engine.index.Location;
+import com.google.dart.engine.index.Relationship;
+import com.google.dart.engine.source.Source;
+import com.google.dart.engine.type.Type;
+import com.google.dart.engine.utilities.collection.IntStack;
+
+import java.util.LinkedList;
/**
* Visits resolved AST and adds relationships into {@link IndexStore}.
*/
public class IndexContributor extends RecursiveASTVisitor<Void> {
+ /**
+ * @return the {@link Location} representing location of the {@link Element}.
+ */
+ @VisibleForTesting
+ static Location createElementLocation(Element element) {
+ if (element != null) {
+ int offset = element.getNameOffset();
+ int length = element.getName().length();
+ String prefix = null;
+ return new Location(new ElementProxy(element), offset, length, prefix);
+ }
+ return null;
+ }
+
+ /**
+ * @return <code>true</code> if given {@link SimpleIdentifier} is "name" part of prefixed
+ * identifier or method invocation.
+ */
+ private static boolean isQualified(SimpleIdentifier node) {
+ if (node.getParent() instanceof PrefixedIdentifier) {
+ return ((PrefixedIdentifier) node.getParent()).getIdentifier() == node;
+ }
+ if (node.getParent() instanceof MethodInvocation) {
+ return ((MethodInvocation) node.getParent()).getMethodName() == node;
+ }
+ return false;
+ }
+
private final IndexStore store;
+ private LibraryElement libraryElement;
+
+ /**
+ * A stack whose top element (the element with the largest index) is an element representing the
+ * inner-most enclosing scope.
+ */
+ private LinkedList<Element> elementStack = Lists.newLinkedList();
+
+ /**
+ * A stack containing one value for each name scope that has been entered, where the values are a
+ * count of the number of unnamed functions that have been found within that scope. These counts
+ * are used to synthesize a name for those functions. The innermost scope is at the top of the
+ * stack.
+ */
+ private IntStack unnamedFunctionCount = new IntStack();
+
public IndexContributor(IndexStore store) {
this.store = store;
}
+ @Override
+ public Void visitClassDeclaration(ClassDeclaration node) {
+ // TODO(scheglov) mixins
+ ClassElement element = node.getElement();
+ enterScope(element);
+ try {
+ recordRelationship(
+ libraryElement,
+ IndexConstants.DEFINES_CLASS,
+ createElementLocation(element));
+ {
+ ExtendsClause extendsClause = node.getExtendsClause();
+ if (extendsClause != null) {
+ TypeName superclassNode = extendsClause.getSuperclass();
+ recordSuperType(element, superclassNode, IndexConstants.IS_EXTENDED_BY);
+ }
+ }
+ {
+ ImplementsClause implementsClause = node.getImplementsClause();
+ if (implementsClause != null) {
+ for (TypeName interfaceNode : implementsClause.getInterfaces()) {
+ recordSuperType(element, interfaceNode, IndexConstants.IS_IMPLEMENTED_BY);
+ }
+ }
+ }
+ return super.visitClassDeclaration(node);
+ } finally {
+ exitScope();
+ }
+ }
+
+ @Override
+ public Void visitCompilationUnit(CompilationUnit node) {
+ CompilationUnitElement unitElement = node.getElement();
+ if (unitElement != null) {
+ elementStack.add(unitElement);
+ libraryElement = unitElement.getEnclosingElement();
+ if (libraryElement != null) {
+ return super.visitCompilationUnit(node);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Void visitFunctionDeclaration(FunctionDeclaration node) {
+ Element element = node.getElement();
+ Location location = createElementLocation(element);
+ recordRelationship(libraryElement, IndexConstants.DEFINES_FUNCTION, location);
+ return super.visitFunctionDeclaration(node);
+ }
+
+ @Override
+ public Void visitFunctionTypeAlias(FunctionTypeAlias node) {
+ Element element = node.getElement();
+ Location location = createElementLocation(element);
+ recordRelationship(libraryElement, IndexConstants.DEFINES_FUNCTION_TYPE, location);
+ return super.visitFunctionTypeAlias(node);
+ }
+
+ @Override
+ public Void visitSimpleIdentifier(SimpleIdentifier node) {
+ Element element = node.getElement();
+ if (element instanceof FieldElement) {
+ FieldElement fieldElement = (FieldElement) element;
+ Location location = createLocation(node);
+ if (node.inGetterContext()) {
+ if (isQualified(node)) {
+ recordRelationship(fieldElement, IndexConstants.IS_ACCESSED_BY_QUALIFIED, location);
+ } else {
+ recordRelationship(fieldElement, IndexConstants.IS_ACCESSED_BY_UNQUALIFIED, location);
+ }
+ } else {
+ // TODO(scheglov)
+ throw new UnsupportedOperationException();
+ }
+ }
+ return super.visitSimpleIdentifier(node);
+ }
+
+ @Override
+ public Void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ VariableDeclarationList variables = node.getVariables();
+ for (VariableDeclaration variableDeclaration : variables.getVariables()) {
+ Element element = variableDeclaration.getElement();
+ Location location = createElementLocation(element);
+ recordRelationship(libraryElement, IndexConstants.DEFINES_VARIABLE, location);
+ }
+ return super.visitTopLevelVariableDeclaration(node);
+ }
+
+ /**
+ * Enter a new scope represented by the given {@link Element}.
+ */
+ @VisibleForTesting
+ void enterScope(Element element) {
+ elementStack.addFirst(element);
+ unnamedFunctionCount.push(0);
+ }
+
+// /**
+// * @return the {@link Location} representing the location of the name of the given class.
+// */
+// private Location createNameLocation(ClassDeclaration node) {
+// return createNameLocation(node.getName());
+// }
+
+ /**
+ * @return the inner-most enclosing {@link Element}, may be <code>null</code>.
+ */
+ @VisibleForTesting
+ Element peekElement() {
+ for (Element element : elementStack) {
+ if (element != null) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return the {@link Location} representing location of the {@link ASTNode}.
+ */
+ private Location createLocation(ASTNode node) {
+ // TODO(scheglov) get actual prefix
+ String prefix = null;
+ return createLocation(node.getOffset(), node.getLength(), prefix);
+ }
+
+ /**
+ * @param offset the offset of the location within {@link Source}
+ * @param length the length of the location
+ * @param prefix the import prefix of top-level element, may be <code>null</code>
+ * @return the {@link Location} representing the given offset and length within the inner-most
+ * {@link Element}.
+ */
+ private Location createLocation(int offset, int length, String prefix) {
+ Element element = peekElement();
+ return new Location(new ElementProxy(element), offset, length, prefix);
+ }
+
+ /**
+ * Exit the current scope.
+ */
+ private void exitScope() {
+ elementStack.removeFirst();
+ unnamedFunctionCount.pop();
+ }
+
+ /**
+ * Record the given relationship between the given {@link Element} and {@link Location}.
+ */
+ private void recordRelationship(Element element, Relationship relationship, Location location) {
+ if (element != null && location != null) {
+ store.recordRelationship(new ElementProxy(element), relationship, location);
+ }
+ }
+
+ /**
+ * Records extends/implements relationships between given {@link ClassElement} and {@link Type} of
+ * "superNode".
+ */
+ private void recordSuperType(ClassElement element, TypeName superNode, Relationship relationship) {
+ if (element != null) {
+ Type superType = superNode.getType();
+ if (superType != null) {
+ Element superElement = superType.getElement();
+ recordRelationship(superElement, relationship, createLocation(superNode));
+ }
+ }
+ }
+
}

Powered by Google App Engine
This is Rietveld 408576698