|
From: <caw...@us...> - 2007-06-06 14:30:30
|
Revision: 2581
http://svn.sourceforge.net/rubyeclipse/?rev=2581&view=rev
Author: cawilliams
Date: 2007-06-06 07:30:28 -0700 (Wed, 06 Jun 2007)
Log Message:
-----------
move occurrences finder over to ui plugin
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/AbstractOccurencesFinder.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TS_TypeInference.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/search/TS_InternalUiRubySearch.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/IOccurrencesFinder.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/DefaultOccurrencesFinder.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/search/MarkOccurrencesTest.java
Removed Paths:
-------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DefaultOccurrencesFinder.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/IOccurrencesFinder.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/MarkOccurrencesTest.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/IOccurrencesFinder.java
Copied: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/IOccurrencesFinder.java (from rev 2395, trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/IOccurrencesFinder.java)
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/IOccurrencesFinder.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/IOccurrencesFinder.java 2007-06-06 14:30:28 UTC (rev 2581)
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.core.search;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.jruby.ast.Node;
+import org.rubypeople.rdt.core.IRubyElement;
+
+public interface IOccurrencesFinder {
+
+ /**
+ *
+ * @param source
+ * Ruby source to search for occurrences
+ * @param offset
+ * position in source where selection is
+ * @param length
+ * length of the selection
+ * @return
+ */
+ public String initialize(String source, int offset, int length);
+
+ /**
+ *
+ * @param root
+ * the root node
+ * @param offset
+ * position in source where selection is
+ * @param length
+ * length of the selection
+ * @return
+ */
+ public String initialize(Node root, int offset, int length);
+
+ /**
+ * Returns a lit of AST Nodes back (which contain their associated
+ * positions).
+ *
+ * @return List of AST Nodes
+ */
+ public List<Position> perform();
+
+ public String getJobLabel();
+
+ /**
+ * Returns the plural label for this finder with 3 placeholders:
+ * <ul>
+ * <li>{0} for the {@link #getElementName() element name}</li>
+ * <li>{1} for the number of results found</li>
+ * <li>{2} for the scope (name of the compilation unit)</li>
+ * </ul>
+ *
+ * @return the unformatted label
+ */
+ public String getUnformattedPluralLabel();
+
+ /**
+ * Returns the singular label for this finder with 2 placeholders:
+ * <ul>
+ * <li>{0} for the {@link #getElementName() element name}</li>
+ * <li>{1} for the scope (name of the compilation unit)</li>
+ * </ul>
+ *
+ * @return the unformatted label
+ */
+ public String getUnformattedSingularLabel();
+
+ /**
+ * Returns the name of the element to look for or <code>null</code> if the
+ * finder hasn't been initialized yet.
+ *
+ * @return the name of the element
+ */
+ public String getElementName();
+
+ public void collectOccurrenceMatches(IRubyElement element,
+ IDocument document, Collection resultingMatches);
+
+ /* Preferences */
+ public void setFMarkConstantOccurrences(boolean markConstantOccurrences);
+ public void setFMarkFieldOccurrences(boolean markFieldOccurrences);
+ public void setFMarkLocalVariableOccurrences(boolean markLocalVariableOccurrences);
+ public void setFMarkMethodExitPoints(boolean markMethodExitPoints);
+ public void setFMarkMethodOccurrences(boolean markMethodOccurrences);
+ public void setFMarkOccurrenceAnnotations(boolean markOccurrenceAnnotations);
+ public void setFMarkTypeOccurrences(boolean markTypeOccurrences);
+ public void setFStickyOccurrenceAnnotations(boolean stickyOccurrenceAnnotations);
+
+}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/AbstractOccurencesFinder.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/AbstractOccurencesFinder.java 2007-06-05 15:44:47 UTC (rev 2580)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/AbstractOccurencesFinder.java 2007-06-06 14:30:28 UTC (rev 2581)
@@ -1,12 +1,8 @@
package org.rubypeople.rdt.internal.ti;
-import java.util.Collection;
-import java.util.List;
+import org.rubypeople.rdt.core.search.IOccurrencesFinder;
-import org.eclipse.jface.text.IDocument;
-import org.rubypeople.rdt.core.IRubyElement;
-
-public class AbstractOccurencesFinder implements IOccurrencesFinder {
+public abstract class AbstractOccurencesFinder implements IOccurrencesFinder {
protected boolean fMarkOccurrenceAnnotations;
protected boolean fStickyOccurrenceAnnotations;
@@ -17,41 +13,6 @@
protected boolean fMarkLocalVariableOccurrences;
protected boolean fMarkMethodExitPoints;
- public void collectOccurrenceMatches(IRubyElement element,
- IDocument document, Collection resultingMatches) {
- // TODO Auto-generated method stub
- }
-
- public String getElementName() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public String getJobLabel() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public String getUnformattedPluralLabel() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public String getUnformattedSingularLabel() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public String initialize(String source, int offset, int length) {
- // TODO Auto-generated method stub
- return null;
- }
-
- public List perform() {
- // TODO Auto-generated method stub
- return null;
- }
-
public void setFMarkConstantOccurrences(boolean markConstantOccurrences) {
fMarkConstantOccurrences = markConstantOccurrences;
}
Deleted: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DefaultOccurrencesFinder.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DefaultOccurrencesFinder.java 2007-06-05 15:44:47 UTC (rev 2580)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DefaultOccurrencesFinder.java 2007-06-06 14:30:28 UTC (rev 2581)
@@ -1,665 +0,0 @@
-package org.rubypeople.rdt.internal.ti;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.eclipse.jface.text.Position;
-import org.jruby.ast.ArgumentNode;
-import org.jruby.ast.BlockArgNode;
-import org.jruby.ast.BlockNode;
-import org.jruby.ast.ClassNode;
-import org.jruby.ast.ClassVarAsgnNode;
-import org.jruby.ast.ClassVarDeclNode;
-import org.jruby.ast.ClassVarNode;
-import org.jruby.ast.Colon2Node;
-import org.jruby.ast.ConstNode;
-import org.jruby.ast.DAsgnNode;
-import org.jruby.ast.DVarNode;
-import org.jruby.ast.DefnNode;
-import org.jruby.ast.DefsNode;
-import org.jruby.ast.GlobalAsgnNode;
-import org.jruby.ast.GlobalVarNode;
-import org.jruby.ast.InstAsgnNode;
-import org.jruby.ast.InstVarNode;
-import org.jruby.ast.LocalAsgnNode;
-import org.jruby.ast.LocalVarNode;
-import org.jruby.ast.ModuleNode;
-import org.jruby.ast.Node;
-import org.jruby.ast.ReturnNode;
-import org.jruby.ast.SymbolNode;
-import org.jruby.lexer.yacc.ISourcePosition;
-import org.jruby.lexer.yacc.SourcePosition;
-import org.jruby.lexer.yacc.SyntaxException;
-import org.rubypeople.rdt.internal.core.parser.RubyParser;
-import org.rubypeople.rdt.internal.core.util.ASTUtil;
-import org.rubypeople.rdt.internal.ti.util.FirstPrecursorNodeLocator;
-import org.rubypeople.rdt.internal.ti.util.INodeAcceptor;
-import org.rubypeople.rdt.internal.ti.util.OffsetNodeLocator;
-import org.rubypeople.rdt.internal.ti.util.ScopedNodeLocator;
-
-/**
- * Implements "Mark Occurences" feature
- *
- * @author Jason Morrison
- *
- */
-public class DefaultOccurrencesFinder extends AbstractOccurencesFinder {
-
- // Root of the document to search
- private Node root;
-
- // Originating node; corresponds to cursor selection
- private Node orig;
-
- // Original source
- private String source;
-
- public String initialize(String source, int offset, int length) {
- if (source == null) {
- return null;
- }
-
- this.source = source;
- try {
- RubyParser rubyParser = new RubyParser();
- this.root = rubyParser.parse(source);
- if (this.root == null) {
- return null;
- }
- }
- // TODO: Is there anything else the parsing could choke on that should
- // be silently ignored with no markings?
- catch (SyntaxException se) {
- this.root = null;
- return null;
- }
- this.orig = OffsetNodeLocator.Instance().getNodeAtOffset(root, offset);
- if (orig == null) {
- return null;
- }
- if (orig.getPosition().getEndOffset() > offset + length) {
- // Selection spans nodes; not handling that for now.
- return "Selection spans nodes; can only search for a single node.";
- }
-
- return null;
- }
-
- /**
- * Determines the kind of originating node, and collects occurrences
- * accordingly
- */
- public List<Position> perform() {
- // Mark no occurrences if root is null (AST couldn't be parsed
- // correctly.)
- if (root == null)
- return new LinkedList<Position>();
- if (orig == null)
- return new LinkedList<Position>();
-
- // occurrences to return
- List<ISourcePosition> occurrences = new LinkedList<ISourcePosition>();
-
- if (fMarkLocalVariableOccurrences && isLocalVarRef(orig)) {
- pushLocalVarRefs(root, orig, occurrences);
- }
-
- if (fMarkLocalVariableOccurrences && isDVarRef(orig)) {
- pushDVarRefs(root, orig, occurrences);
- }
-
- // XXX: Add pref for instvars
- if (fMarkLocalVariableOccurrences && isInstanceVarRef(orig)) {
- pushInstVarRefs(root, orig, occurrences);
- }
-
- // XXX: Add pref for classvars
- if (fMarkLocalVariableOccurrences && isClassVarRef(orig)) {
- pushClassVarRefs(root, orig, occurrences);
- }
-
- // XXX: Add pref for global vars
- if (fMarkLocalVariableOccurrences && isGlobalVarRef(orig)) {
- pushGlobalVarRefs(root, orig, occurrences);
- }
-
- // XXX: Add pref for symbols
- if (fMarkConstantOccurrences && orig instanceof SymbolNode) {
- pushSymbolRefs(root, orig, occurrences);
- }
-
- // if ( isMethodRefNode(orig)) {
- // pushMethodRefs( root, orig, occurrences );
- // }
-
- if (fMarkConstantOccurrences && isConstRef(orig)) {
- pushConstRefs(root, orig, occurrences);
- }
-
- if (fMarkTypeOccurrences && isTypeRef(orig)) {
- pushTypeRefs(root, orig, occurrences);
- }
-
- if (fMarkMethodExitPoints) {
- pushReturns(root, orig, occurrences);
- }
-
- // Convert ISourcePosition to IPosition
- List<Position> positions = new LinkedList<Position>();
- for (ISourcePosition occurrence : occurrences) {
- Position position = new Position(occurrence.getStartOffset(), occurrence.getEndOffset() - occurrence.getStartOffset());
- positions.add(position);
- }
-
- // Uniqueify positions
- positions = new LinkedList<Position>(new HashSet<Position>(positions));
-
- return positions;
- }
-
- // ****************************************************************************
- // *
- // * Reference kind definitions
- // *
- // ****************************************************************************
-
- /**
- * Determines whether a given node is a local variable reference
- *
- * @param node
- * @return
- */
- private boolean isLocalVarRef(Node node) {
- return ((node instanceof LocalAsgnNode) || (node instanceof ArgumentNode) || (node instanceof LocalVarNode));
- }
-
- /**
- * Determines whether a given node is a dynamic variable reference
- *
- * @param node
- * @return
- */
- private boolean isDVarRef(Node node) {
- return ((node instanceof DVarNode) || (node instanceof DAsgnNode));
- }
-
- /**
- * Determines whether a given node is an instance variable reference
- *
- * @param node
- * @return
- */
- private boolean isInstanceVarRef(Node node) {
- return ((node instanceof InstAsgnNode) || (node instanceof InstVarNode));
- }
-
- /**
- * Determines whether a given node is a class variable reference
- *
- * @param node
- * @return
- */
- private boolean isClassVarRef(Node node) {
- return ((node instanceof ClassVarNode) || (node instanceof ClassVarAsgnNode) || (node instanceof ClassVarDeclNode));
- }
-
- /**
- * Determines whether a given node is a global variable reference
- *
- * @param node
- * @return
- */
- private boolean isGlobalVarRef(Node node) {
- return ((node instanceof GlobalAsgnNode) || (node instanceof GlobalVarNode));
- }
-
- /**
- * Determines whether a given node is a constant reference (constant)
- *
- * @param node
- * @return
- */
- private boolean isConstRef(Node node) {
- return (node instanceof ConstNode);
- }
-
- /**
- * Determines whether a given node is a type reference (class, module)
- *
- * @param node
- * @return
- */
- private boolean isTypeRef(Node node) {
- // TODO: Classes can be referred to as a ConstNode; i.e. "class
- // Klass;end; k = Klass.new" the last reference is a ConstNode, not a
- // ClassNode. Special way to handle this?
- return ((node instanceof ClassNode) || (node instanceof ModuleNode) || (node instanceof ConstNode));
- }
-
- // ****************************************************************************
- // *
- // * Worker methods - handles delegation of occurrence searches
- // *
- // ****************************************************************************
-
- /**
- * Collects all corresponding local variable occurrences
- *
- * @param root
- * Root node to search
- * @param orig
- * Originating node
- * @param occurrences
- */
- private void pushLocalVarRefs(Node root, Node orig, List<ISourcePosition> occurrences) {
- // Find the search space
- Node searchSpace = FirstPrecursorNodeLocator.Instance().findFirstPrecursor(root, orig.getPosition().getStartOffset(), new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- return ((node instanceof DefnNode) || (node instanceof DefsNode) ); // TODO: Block Body?
- }
- });
-
- // If no enclosing node found, search the entire space
- if (searchSpace == null) {
- searchSpace = root;
- }
-
- // Finalize searchSpace because Java's scoping rules are the awesome
- final Node finalSearchSpace = searchSpace;
-
- // Get name of local variable reference
- final String origName = ASTUtil.getNameReflectively(orig);
-
- // Find all pertinent nodes
- List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- String name = ASTUtil.getNameReflectively(node);
- return (name != null && name.equals(origName));
- }
- });
-
- // Scrape position from pertinent nodes
- for (Node searchResult : searchResults) {
- occurrences.add(getPositionOfName(searchResult, searchSpace));
- }
- }
-
- /**
- * Collects all corresponding dynamic variable occurrences
- *
- * @param root
- * Root node to search
- * @param orig
- * Originating node
- * @param occurrences
- */
- private void pushDVarRefs(Node root, Node orig, List<ISourcePosition> occurrences) {
- // Find the search space
- Node searchSpace = FirstPrecursorNodeLocator.Instance().findFirstPrecursor(root, orig.getPosition().getStartOffset(), new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- return ((node instanceof DefnNode) || (node instanceof DefsNode) ); // TODO: Block Body?
- }
- });
-
- // If no enclosing node found, search the entire space
- if (searchSpace == null) {
- searchSpace = root;
- }
-
- // Get name of local variable reference
- final String origName = ASTUtil.getNameReflectively(orig);
-
- // Find all pertinent nodes
- List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- if (isDVarRef(node)) {
- String name = ASTUtil.getNameReflectively(node);
- return (name != null && name.equals(origName));
- }
- return false;
- }
- });
-
- // Scrape position from pertinent nodes
- for (Node searchResult : searchResults) {
- occurrences.add(getPositionOfName(searchResult, searchSpace));
- }
- }
-
- /**
- * Collects all instance variable occurrences
- *
- * @param root
- * @param orig
- * @param occurrences
- */
- private void pushInstVarRefs(Node root, Node orig, List<ISourcePosition> occurrences) {
- Node searchSpace = determineSearchSpace(root, orig);
-
- // Finalize searchSpace because Java's scoping rules are the awesome
- // todo: not needed?
- // final Node finalSearchSpace = searchSpace;
-
- // Get name of local variable reference
- final String origName = ASTUtil.getNameReflectively(orig);
-
- // Find all pertinent nodes
- List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- if (isInstanceVarRef(node)) {
- String name = ASTUtil.getNameReflectively(node);
- return (name != null && name.equals(origName));
- }
- return false;
- }
- });
-
- // Scrape position from pertinent nodes
- for (Node searchResult : searchResults) {
- occurrences.add(getPositionOfName(searchResult, searchSpace));
- }
-
- }
-
- private Node determineSearchSpace(Node root, Node orig) {
-
- // Find the name of the enclosing class
- ClassNode enclosingClass = (ClassNode) FirstPrecursorNodeLocator.Instance().findFirstPrecursor(root, orig.getPosition().getStartOffset(), new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- return (node instanceof ClassNode);
- }
- });
-
- // If no enclosing class is identified, search root.
- if (enclosingClass == null) {
- return root;
- }
- // Find the search space - all ClassNodes for that name within root
- // scope
- else {
- final String className = getClassNodeName(enclosingClass);
- List<Node> classNodes = ScopedNodeLocator.Instance().findNodesInScope(root, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- if (node instanceof ClassNode) {
- return getClassNodeName((ClassNode) node).equals(className);
- }
- return false;
- }
- });
- BlockNode blockNode = new BlockNode(new SourcePosition());
- for (Node classNode : classNodes) {
- blockNode.add(classNode);
- }
- return blockNode;
- }
- }
-
- /**
- * Collects all class variable occurrences
- *
- * @param root
- * @param orig
- * @param occurrences
- */
- private void pushClassVarRefs(Node root, Node orig, List<ISourcePosition> occurrences) {
- Node searchSpace = determineSearchSpace(root, orig);
-
- // Finalize searchSpace because Java's scoping rules are the awesome
- // todo: not needed?
- // final Node finalSearchSpace = searchSpace;
-
- // Get name of local variable reference
- final String origName = ASTUtil.getNameReflectively(orig);
-
- // Find all pertinent nodes
- List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- if (isClassVarRef(node)) {
- String name = ASTUtil.getNameReflectively(node);
- return (name != null && name.equals(origName));
- }
- return false;
- }
- });
-
- // Scrape position from pertinent nodes
- for (Node searchResult : searchResults) {
- occurrences.add(getPositionOfName(searchResult, searchSpace));
- }
-
- }
-
- /**
- * Collects all global variable occurrences
- *
- * @param root
- * @param orig
- * @param occurrences
- */
- private void pushGlobalVarRefs(Node root, Node orig, List<ISourcePosition> occurrences) {
- final Node searchSpace = root;
- final String origName = ASTUtil.getNameReflectively(orig);
-
- // Find all pertinent nodes
- List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- return isGlobalVarRef(node) && ASTUtil.getNameReflectively(node).equals(origName);
- }
- });
-
- // Scrape position from pertinent nodes
- for (Node searchResult : searchResults) {
- occurrences.add(getPositionOfName(searchResult, searchSpace));
- }
- }
-
- /**
- * Collects all symbol occurrences
- *
- * @param root
- * @param orig
- * @param occurrences
- */
- private void pushSymbolRefs(Node root, Node orig, List<ISourcePosition> occurrences) {
- final Node searchSpace = root;
- final String origName = ((SymbolNode) orig).getName();
-
- // Find all pertinent nodes
- List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- return (node instanceof SymbolNode) && ((SymbolNode) node).getName().equals(origName);
- }
- });
-
- // Scrape position from pertinent nodes
- for (Node searchResult : searchResults) {
- occurrences.add(getPositionOfName(searchResult, searchSpace));
- }
- }
-
- // todo: complete
- // private void pushMethodRefs( Node root, Node orig, List<ISourcePosition>
- // occurrences) {
- //
- // // DefnNode DefsNode CallNode VCallNode
- //
- // System.out.println("Finding occurrences for method reference node " +
- // orig.toString() );
- //
- // final Node searchSpace = root;
- // String origName = getMethodRefName(orig);
- //
- // // If orig is a method definition, find all occurrences to that selector
- // for the orig's enclosing type
- // if ( orig instanceof DefnNode || orig instanceof DefsNode )
- // {
- // ((DefnNode)orig).g
- // }
- //
- // Node receiver = getMethodReceiver(orig);
- // }
-
- /**
- * Collects all pertinent const occurrences
- */
- private void pushConstRefs(Node root, Node orig, List<ISourcePosition> occurrences) {
- if (!isConstRef(orig)) {
- return;
- }
-
- final String matchName = ASTUtil.getNameReflectively(orig);
- List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(root, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- if (isConstRef(node)) {
- return ASTUtil.getNameReflectively(node).equals(matchName);
- }
- return false;
- }
- });
-
- for (Node searchResult : searchResults) {
- occurrences.add(getPositionOfName(searchResult, root));
- }
- }
-
- /**
- * Collects all pertinent type ref occurrences
- */
- private void pushTypeRefs(Node root, Node orig, List<ISourcePosition> occurrences) {
- if (!isTypeRef(orig)) {
- return;
- }
-
- final String matchName = ASTUtil.getNameReflectively(orig);
- List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(root, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- if (isTypeRef(node)) {
- return getTypeRefName(node).equals(matchName);
- }
- return false;
- }
- });
-
- for (Node searchResult : searchResults) {
- occurrences.add(getPositionOfName(searchResult, root));
- }
- }
-
- private void pushReturns(Node root, Node orig, List<ISourcePosition> occurrences) {
- // TODO Combine most of this stuff with the stuff in pushLocalVareRefs
- // Find the search space
- Node searchSpace = FirstPrecursorNodeLocator.Instance().findFirstPrecursor(root, orig.getPosition().getStartOffset(), new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- return ((node instanceof DefnNode) || (node instanceof DefsNode) ); // TODO: Block Body?
- }
- });
-
- // If no enclosing node found, search the entire space
- if (searchSpace == null) {
- searchSpace = root;
- }
-// Find all return nodes
- List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- return (node instanceof ReturnNode);
- }
- });
-
- // Scrape position from pertinent nodes
- for (Node searchResult : searchResults) {
- occurrences.add(searchResult.getPosition());
- }
- }
-
- // ****************************************************************************
- // *
- // * Utility methods
- // *
- // ****************************************************************************
-
- /**
- * Gets the position of the name for the specified node.
- *
- * @param node
- * Node that responds to getName() or some variant
- * @param scope
- * Scope that holds the node (pertinent for locals and args)
- * @return ISourcePosition that holds the name of the node
- */
- private ISourcePosition getPositionOfName(Node node, Node scope) {
- ISourcePosition pos = node.getPosition();
-
- // TODO refactor the getting-of-name
- String name = null;
- if (isLocalVarRef(node) || isDVarRef(node) || isInstanceVarRef(node) || isGlobalVarRef(node) || isClassVarRef(node) || isConstRef(node) || node instanceof BlockArgNode) {
- name = ASTUtil.getNameReflectively(node);
- } else if (node instanceof ClassNode) {
- name = getClassNodeName((ClassNode) node);
- String classDeclString = source.substring(pos.getStartOffset(), pos.getEndOffset());
- int begin = pos.getStartOffset() + classDeclString.indexOf(name);
- return new SourcePosition(pos.getFile(), pos.getStartLine(), pos.getEndLine(), begin, begin + name.length());
- } else if (node instanceof ModuleNode) {
- name = getModuleNodeName((ModuleNode) node);
- String moduleDeclString = source.substring(pos.getStartOffset(), pos.getEndOffset());
- int begin = moduleDeclString.indexOf(name);
- return new SourcePosition(pos.getFile(), pos.getStartLine(), pos.getEndLine(), begin, begin + name.length());
- } else if (node instanceof SymbolNode) {
- // XXX: This is a hack to get around improper offsets in my JRuby
- // copy; ":foo" returns offset for ":fo", so compensate by adding
- // one
- name = ((SymbolNode) node).getName();
- return new SourcePosition(pos.getFile(), pos.getStartLine(), pos.getEndLine(), pos.getStartOffset(), pos.getStartOffset() + name.length() + 1);
- }
-
- if (name == null) {
- throw new RuntimeException("Couldn't get the name for: " + node.toString() + " in " + scope.toString());
- }
- return new SourcePosition(pos.getFile(), pos.getStartLine(), pos.getEndLine(), pos.getStartOffset(), pos.getStartOffset() + name.length());
- }
-
- /**
- * Helper method to get the class name froma ClassNode
- *
- * @param classNode
- * @return
- */
- private String getClassNodeName(ClassNode classNode) {
- if (classNode.getCPath() instanceof Colon2Node) {
- Colon2Node c2node = (Colon2Node) classNode.getCPath();
- return c2node.getName();
- }
- throw new RuntimeException("ClassNode.getCPath() returned other than Colon2Node: " + classNode.toString());
- }
-
- /**
- * Helper method to get the class name from a ModuleNode
- *
- * @param classNode
- * @return
- */
- private String getModuleNodeName(ModuleNode moduleNode) {
- if (moduleNode.getCPath() instanceof Colon2Node) {
- Colon2Node c2node = (Colon2Node) moduleNode.getCPath();
- return c2node.getName();
- }
- throw new RuntimeException("ModuleNode.getCPath() returned other than Colon2Node: " + moduleNode.toString());
- }
-
- /**
- * Helper method to get the class name from a const ref node (Class/Module)
- *
- * @param node
- * @return
- */
- private String getTypeRefName(Node node) {
- if (node instanceof ClassNode) {
- return getClassNodeName((ClassNode) node);
- }
- if (node instanceof ModuleNode) {
- return getModuleNodeName((ModuleNode) node);
- }
- return ASTUtil.getNameReflectively(node);
- }
-
-}
Deleted: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/IOccurrencesFinder.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/IOccurrencesFinder.java 2007-06-05 15:44:47 UTC (rev 2580)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/IOccurrencesFinder.java 2007-06-06 14:30:28 UTC (rev 2581)
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.rubypeople.rdt.internal.ti;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.Position;
-import org.rubypeople.rdt.core.IRubyElement;
-
-public interface IOccurrencesFinder {
-
- /**
- *
- * @param source
- * Ruby source to search for occurrences
- * @param offset
- * position in source where selection is
- * @param length
- * length of the selection
- * @return
- */
- public String initialize(String source, int offset, int length);
-
- /**
- * Returns a lit of AST Nodes back (which contain their associated
- * positions).
- *
- * @return List of AST Nodes
- */
- public List<Position> perform();
-
- public String getJobLabel();
-
- /**
- * Returns the plural label for this finder with 3 placeholders:
- * <ul>
- * <li>{0} for the {@link #getElementName() element name}</li>
- * <li>{1} for the number of results found</li>
- * <li>{2} for the scope (name of the compilation unit)</li>
- * </ul>
- *
- * @return the unformatted label
- */
- public String getUnformattedPluralLabel();
-
- /**
- * Returns the singular label for this finder with 2 placeholders:
- * <ul>
- * <li>{0} for the {@link #getElementName() element name}</li>
- * <li>{1} for the scope (name of the compilation unit)</li>
- * </ul>
- *
- * @return the unformatted label
- */
- public String getUnformattedSingularLabel();
-
- /**
- * Returns the name of the lement to look for or <code>null</code> if the
- * finder hasn't been initialized yet.
- *
- * @return the name of the element
- */
- public String getElementName();
-
- public void collectOccurrenceMatches(IRubyElement element,
- IDocument document, Collection resultingMatches);
-
- /* Preferences */
- public void setFMarkConstantOccurrences(boolean markConstantOccurrences);
- public void setFMarkFieldOccurrences(boolean markFieldOccurrences);
- public void setFMarkLocalVariableOccurrences(boolean markLocalVariableOccurrences);
- public void setFMarkMethodExitPoints(boolean markMethodExitPoints);
- public void setFMarkMethodOccurrences(boolean markMethodOccurrences);
- public void setFMarkOccurrenceAnnotations(boolean markOccurrenceAnnotations);
- public void setFMarkTypeOccurrences(boolean markTypeOccurrences);
- public void setFStickyOccurrenceAnnotations(boolean stickyOccurrenceAnnotations);
-
-}
Deleted: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/MarkOccurrencesTest.java
===================================================================
--- trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/MarkOccurrencesTest.java 2007-06-05 15:44:47 UTC (rev 2580)
+++ trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/MarkOccurrencesTest.java 2007-06-06 14:30:28 UTC (rev 2581)
@@ -1,215 +0,0 @@
-package org.rubypeople.rdt.internal.ti;
-
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.eclipse.jface.text.Position;
-
-/**
- * Tests related to matching occurrences.
- *
- * @author Jason Morrison
- *`
- */
-public class MarkOccurrencesTest extends TestCase {
-
- private IOccurrencesFinder occurrencesFinder;
- public void setUp() {
- occurrencesFinder = new DefaultOccurrencesFinder();
- occurrencesFinder.setFMarkConstantOccurrences(true);
- occurrencesFinder.setFMarkFieldOccurrences(true);
- occurrencesFinder.setFMarkLocalVariableOccurrences(true);
- occurrencesFinder.setFMarkMethodExitPoints(true);
- occurrencesFinder.setFMarkMethodOccurrences(true);
- occurrencesFinder.setFMarkOccurrenceAnnotations(true);
- occurrencesFinder.setFMarkTypeOccurrences(true);
- occurrencesFinder.setFStickyOccurrenceAnnotations(true);
- }
-
- private void assertOccurrencesEqual(String source, int offset, String matchName, int[][] offsets )
- {
- occurrencesFinder.initialize(source, offset, 0);
- List<Position> occurrences = occurrencesFinder.perform();
- assertEquals( offsets.length, occurrences.size() );
-
- for ( int i = 0; i < offsets.length; i++ ) {
- int start = occurrences.get(i).getOffset();
- int length = occurrences.get(i).getLength();
- int end = occurrences.get(i).getOffset() + length;
-
- Position testPosition = new Position( start, length );
-
- assertTrue( occurrences.contains( testPosition ) );
-
-// assertEquals( offsets[i][0], start );
-// assertEquals( offsets[i][1], end );
- assertEquals( matchName, source.substring(start, end));
- }
- }
-
- /**
- * Match locals within ClassNode::DefnNode
- */
- public void testLocalVariableMatches() {
- String source = "class Klass;def foo(x);puts x*2;end;def bar;my_var = 5;my_var = 6;puts my_var;foo(my_var);end;end";
- int[][] offsets = {{44,50},{55,61},{71,77},{82,88}};
- assertOccurrencesEqual( source, 46, "my_var", offsets );
- }
-
- /**
- * Match args to locals
- */
- public void testArgMatches() {
- String source = "class Klass;def foo(my_arg);puts my_arg*2;end;end";
- int[][] offsets = {{20,26},{33,39}};
- assertOccurrencesEqual( source, 22, "my_arg", offsets );
- }
-
- /**
- * Match locals within Kernel::DefnNode
- */
- public void testLocalVariablesInKernelDefnScope() {
- String source = "def foo;my_var=5;puts my_var*2;end";
- int[][] offsets = {{8,14},{22,28}};
- assertOccurrencesEqual( source, 10, "my_var", offsets );
- }
-
- /**
- * Match locals in Kernel
- */
- public void testLocalVariablesInKernelScope() {
- String source = "my_var = 5;puts my_var*2;other_var = my_var * my_var";
- int[][] offsets = {{0,6},{16,22},{37,43},{46,52}};
- assertOccurrencesEqual( source, 1, "my_var", offsets );
- }
-
- /**
- * Match instance vars inside one ClassNode across DefnNode
- */
- public void testInstanceVariableMatches() {
- String source = "class Klass;def foo(param);@inst_var = param;puts @inst_var;end;def bar;y @inst_var;end;end";
- int[][] offsets = {{27,36},{50,59},{74,83}};
- assertOccurrencesEqual( source, 29, "@inst_var", offsets );
- }
-
- /**
- * Match instance vars inside two DefnNodes, each in a separate ClassNode (for the same class)
- */
- public void testInstanceVariableMatchInReopenedClass() {
- String source = "class Klass;def foo;@inst_var=5;end;end;class Klass;def bar;@inst_var=6;end;end";
- int[][] offsets = {{20,29},{60,69}};
- assertOccurrencesEqual( source, 23, "@inst_var", offsets );
- }
-
- /**
- * Test matching a local variable before, inside, and after a block.
- */
- public void testLocalVariableMatchesIntoBlockScope() {
- String source = "class Klass;def foo;my_var = 5;5.times { puts my_var };puts my_var;end;end";
- int[][] offsets = {{20,26},{46,52},{60,66}};
- assertOccurrencesEqual( source, 23, "my_var", offsets );
- }
-
- /**
- * Test referencing a global variable in various contexts.
- *
- */
- public void testGlobalVariableMatches() {
- String source = "$foo = 'bar';class Klass;def foo;$foo = 5;end;def bar;puts $foo;end;end;puts $foo";
- int[][] offsets = {{0,4},{33,37},{59,63},{77,81}};
- assertOccurrencesEqual(source, 0, "$foo", offsets);
- }
-
- /**
- * Test referencing a symbol in various contexts.
- *
- */
- public void testSymbolMatches() {
- String source = "a_var = :foo;class Klass;def foo;l = :foo;end;def bar;puts :foo;end;end;puts :foo.to_s";
-// String source = "$foo = 'bar';class Klass;def foo;$foo = 5;end;def bar;puts $foo;end;end;puts $foo";
- int[][] offsets = {{8,12},{37,41},{59,63},{77,81}};
- assertOccurrencesEqual(source, 9, ":foo", offsets);
- }
-
-//TODO: Method invocation tests need to know the type of their receiver.
-// Sub-goals are becoming necessary, i.e. for determining arg-type to match selectors by more
-// than name, and determining receiver-type to match selectors applied to other same-typed receivers.
-
-// public void testMethodInvocationMatchInsideMethod() {
-// String source = "class Klass;def foo;my_var = 5;y = my_var.to_s;puts y.to_s;end;end";
-// int[][] offsets = {{42,46},{54,58}};
-// assertOccurrencesEquals( source, 42, "to_s", offsets );
-// }
-//
-// public void testMethodInvocationMatchInKernelScope() {
-// String source = "my_var = 5;y = my_var.to_s;puts y.to_s";
-// int[][] offsets = {{22,26},{34,38}};
-// assertOccurrencesEquals(source, 22, "to_s", offsets);
-// }
-//
-// public void testStaticMethodInvocationMatchInKernelScope() {
-// String source = "puts 5;puts 6;puts 7;";
-// int[][] offsets = {{0,4},{7,11},{14,18}};
-// assertOccurrencesEquals( source, 0, "puts", offsets );
-// }
-//
-// public void testMethodInvocationMatchAgainstMultipleInstancesOfSameType() {
-// String source = "xvar = 5;yvar = 6;puts xvar.to_s;puts yvar.to_s";
-// int[][] offsets = {{28,32},{43,47}};
-// assertOccurrencesEquals(source, 28, "to_s", offsets);
-// }
-
- /**
- * Test matching against ConstNodes; specifically class occurrences
- */
- public void testTypeMatches() {
- String source = "f = String.new;class Klass;def foo;c = String;end;end;class MyString < String;end";
- int[][] offsets = {{4,10},{39,45},{71,77}};
- assertOccurrencesEqual( source, 4, "String", offsets );
- }
-
- public void testConstNodeToClassDeclNode() {
- String source = "class Klass;def foo;5;end;end;k = Klass.new";
- int[][] offsets = {{6,11},{34,39}};
- assertOccurrencesEqual( source, 34, "Klass", offsets );
- }
-
- public void testBlockArguments() {
- String source = "[1,2,3].each { |number| puts number }";
- int[][] offsets = {{16,22},{29,35}};
- assertOccurrencesEqual(source, 16, "number", offsets);
-// assertOccurrencesEqual(source, 29, "number", offsets);
- }
-
-
- /**
- * Match instance vars inside one ClassNode across DefnNode
- */
- public void testClassVariableMatches() {
- String source = "class Klass;def foo(param);@@cls_var = param;puts @@cls_var;end;def bar;y @@cls_var;end;end";
- int[][] offsets = {{27,36},{50,59},{74,83}};
- assertOccurrencesEqual( source, 29, "@@cls_var", offsets );
- }
-
- /**
- * Match instance vars inside two DefnNodes, each in a separate ClassNode (for the same class)
- */
- public void testClassVariableMatchInReopenedClass() {
- String source = "class Klass;def foo;@@cls_var=5;end;end;class Klass;def bar;@@cls_var=6;end;end";
- int[][] offsets = {{20,29},{60,69}};
- assertOccurrencesEqual( source, 23, "@@cls_var", offsets );
- }
-
-// Oddity with local/dvars:
-//
-// foo = Printer.new
-// [person, place, thing].each do |noun|
-// foo.print(noun)
-// end
-// noun = "hi"
-//
-// There are 3 refs to "noun". Clicking the first highlights 1&2, clicking 2 highlights 1&2
-// but clicking 3 highlights 2&3 - ????!
-
-}
Modified: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TS_TypeInference.java
===================================================================
--- trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TS_TypeInference.java 2007-06-05 15:44:47 UTC (rev 2580)
+++ trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TS_TypeInference.java 2007-06-06 14:30:28 UTC (rev 2581)
@@ -7,7 +7,6 @@
public static Test suite() {
TestSuite suite = new TestSuite("Type Inference");
suite.addTestSuite(DataFlowTypeInferrerTest.class);
- suite.addTestSuite(MarkOccurrencesTest.class);
suite.addTestSuite(ReferenceMatchTest.class);
suite.addTestSuite(TypeInferrerTest.class);
return suite;
Copied: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/DefaultOccurrencesFinder.java (from rev 2574, trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DefaultOccurrencesFinder.java)
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/DefaultOccurrencesFinder.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/DefaultOccurrencesFinder.java 2007-06-06 14:30:28 UTC (rev 2581)
@@ -0,0 +1,730 @@
+package org.rubypeople.rdt.internal.ui.search;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.search.ui.text.Match;
+import org.jruby.ast.ArgumentNode;
+import org.jruby.ast.BlockArgNode;
+import org.jruby.ast.BlockNode;
+import org.jruby.ast.ClassNode;
+import org.jruby.ast.ClassVarAsgnNode;
+import org.jruby.ast.ClassVarDeclNode;
+import org.jruby.ast.ClassVarNode;
+import org.jruby.ast.Colon2Node;
+import org.jruby.ast.ConstNode;
+import org.jruby.ast.DAsgnNode;
+import org.jruby.ast.DVarNode;
+import org.jruby.ast.DefnNode;
+import org.jruby.ast.DefsNode;
+import org.jruby.ast.GlobalAsgnNode;
+import org.jruby.ast.GlobalVarNode;
+import org.jruby.ast.InstAsgnNode;
+import org.jruby.ast.InstVarNode;
+import org.jruby.ast.LocalAsgnNode;
+import org.jruby.ast.LocalVarNode;
+import org.jruby.ast.ModuleNode;
+import org.jruby.ast.Node;
+import org.jruby.ast.ReturnNode;
+import org.jruby.ast.SymbolNode;
+import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.lexer.yacc.SourcePosition;
+import org.jruby.lexer.yacc.SyntaxException;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.internal.core.parser.RubyParser;
+import org.rubypeople.rdt.internal.core.util.ASTUtil;
+import org.rubypeople.rdt.internal.ti.AbstractOccurencesFinder;
+import org.rubypeople.rdt.internal.ti.util.FirstPrecursorNodeLocator;
+import org.rubypeople.rdt.internal.ti.util.INodeAcceptor;
+import org.rubypeople.rdt.internal.ti.util.OffsetNodeLocator;
+import org.rubypeople.rdt.internal.ti.util.ScopedNodeLocator;
+
+/**
+ * Implements "Mark Occurences" feature
+ *
+ * @author Jason Morrison
+ *
+ */
+public class DefaultOccurrencesFinder extends AbstractOccurencesFinder {
+
+ // Root of the document to search
+ private Node root;
+
+ // Originating node; corresponds to cursor selection
+ private Node fSelectedNode;
+
+ private List<Node> fUsages= new ArrayList<Node>();
+ private List<Node> fWriteUsages= new ArrayList<Node>();
+
+ // Original source
+ private String source;
+
+ public String getJobLabel() {
+ return SearchMessages.OccurrencesFinder_searchfor;
+ }
+
+ public String getUnformattedPluralLabel() {
+ return SearchMessages.OccurrencesFinder_label_plural;
+ }
+
+ public String getUnformattedSingularLabel() {
+ return SearchMessages.OccurrencesFinder_label_singular;
+ }
+
+ public void collectOccurrenceMatches(IRubyElement element, IDocument document, Collection resultingMatches) {
+ HashMap lineToGroup= new HashMap();
+
+ for (Iterator iter= fUsages.iterator(); iter.hasNext();) {
+ Node node= (Node) iter.next();
+ ISourcePosition position = getPositionOfName(node);
+ int startPosition= position.getStartOffset();
+ int length= position.getEndOffset() - position.getStartOffset();
+ try {
+ boolean isWriteAccess= fWriteUsages.contains(node);
+ int line= document.getLineOfOffset(startPosition);
+ Integer lineInteger= new Integer(line);
+ OccurrencesGroupKey groupKey= (OccurrencesGroupKey) lineToGroup.get(lineInteger);
+ if (groupKey == null) {
+ IRegion region= document.getLineInformation(line);
+ String lineContents= document.get(region.getOffset(), region.getLength()).trim();
+ groupKey= new OccurrencesGroupKey(element, line, lineContents, isWriteAccess, isVariable(element));
+ lineToGroup.put(lineInteger, groupKey);
+ } else if (isWriteAccess) {
+ // a line with read an write access is considered as write access:
+ groupKey.setWriteAccess(true);
+ }
+ Match match= new Match(groupKey, startPosition, length);
+ resultingMatches.add(match);
+ } catch (BadLocationException e) {
+ //nothing
+ }
+ }
+ }
+
+ private boolean isVariable(IRubyElement element) {
+ return element.isType(IRubyElement.INSTANCE_VAR) || element.isType(IRubyElement.GLOBAL) || element.isType(IRubyElement.CLASS_VAR) || element.isType(IRubyElement.LOCAL_VARIABLE) || element.isType(IRubyElement.DYNAMIC_VAR);
+ }
+
+ public String initialize(Node root, int offset, int length) {
+ if (root == null) {
+ return null;
+ }
+ this.root = root;
+ this.fSelectedNode = OffsetNodeLocator.Instance().getNodeAtOffset(root, offset);
+ if (fSelectedNode == null) {
+ return SearchMessages.OccurrencesFinder_no_element;
+ }
+// if (fSelectedNode.getPosition().getEndOffset() > offset + length) {
+// // Selection spans nodes; not handling that for now.
+// return "Selection spans nodes; can only search for a single node.";
+// }
+ return null;
+ }
+
+ public String initialize(String source, int offset, int length) {
+ if (source == null) {
+ return null;
+ } else {
+ this.source = source;
+ }
+
+ Node root = null;
+ try {
+ RubyParser rubyParser = new RubyParser();
+ root = rubyParser.parse(source);
+ }
+ // TODO: Is there anything else the parsing could choke on that should
+ // be silently ignored with no markings?
+ catch (SyntaxException se) {
+ // ignore
+ }
+ return initialize(root, offset, length);
+ }
+
+ /**
+ * Determines the kind of originating node, and collects occurrences
+ * accordingly
+ */
+ public List<Position> perform() {
+ // Mark no occurrences if root is null (AST couldn't be parsed
+ // correctly.)
+ if (root == null)
+ return new LinkedList<Position>();
+ if (fSelectedNode == null)
+ return new LinkedList<Position>();
+
+ if (fMarkLocalVariableOccurrences && isLocalVarRef(fSelectedNode)) {
+ pushLocalVarRefs(root, fSelectedNode, fUsages);
+ }
+
+ if (fMarkLocalVariableOccurrences && isDVarRef(fSelectedNode)) {
+ pushDVarRefs(root, fSelectedNode, fUsages);
+ }
+
+ if (fMarkLocalVariableOccurrences && isInstanceVarRef(fSelectedNode)) {
+ pushInstVarRefs(root, fSelectedNode, fUsages);
+ }
+
+ if (fMarkLocalVariableOccurrences && isClassVarRef(fSelectedNode)) {
+ pushClassVarRefs(root, fSelectedNode, fUsages);
+ }
+
+ if (fMarkLocalVariableOccurrences && isGlobalVarRef(fSelectedNode)) {
+ pushGlobalVarRefs(root, fSelectedNode, fUsages);
+ }
+
+ if (fMarkConstantOccurrences && fSelectedNode instanceof SymbolNode) {
+ pushSymbolRefs(root, fSelectedNode, fUsages);
+ }
+
+ // if ( isMethodRefNode(fSelectedNode)) {
+ // pushMethodRefs( root, fSelectedNode, occurrences );
+ // }
+
+ if (fMarkConstantOccurrences && isConstRef(fSelectedNode)) {
+ pushConstRefs(root, fSelectedNode, fUsages);
+ }
+
+ if (fMarkTypeOccurrences && isTypeRef(fSelectedNode)) {
+ pushTypeRefs(root, fSelectedNode, fUsages);
+ }
+
+ if (fMarkMethodExitPoints) {
+ pushReturns(root, fSelectedNode, fUsages);
+ }
+
+ // Convert ISourcePosition to IPosition
+ List<Position> positions = new LinkedList<Position>();
+ for (Node node : fUsages) {
+ ISourcePosition occurrence = getPositionOfName(node);
+ Position position = new Position(occurrence.getStartOffset(), occurrence.getEndOffset() - occurrence.getStartOffset());
+ positions.add(position);
+ }
+
+ // Uniqueify positions
+ positions = new LinkedList<Position>(new HashSet<Position>(positions));
+
+ return positions;
+ }
+
+ // ****************************************************************************
+ // *
+ // * Reference kind definitions
+ // *
+ // ****************************************************************************
+
+ /**
+ * Determines whether a given node is a local variable reference
+ *
+ * @param node
+ * @return
+ */
+ private boolean isLocalVarRef(Node node) {
+ return ((node instanceof LocalAsgnNode) || (node instanceof ArgumentNode) || (node instanceof LocalVarNode));
+ }
+
+ /**
+ * Determines whether a given node is a dynamic variable reference
+ *
+ * @param node
+ * @return
+ */
+ private boolean isDVarRef(Node node) {
+ return ((node instanceof DVarNode) || (node instanceof DAsgnNode));
+ }
+
+ /**
+ * Determines whether a given node is an instance variable reference
+ *
+ * @param node
+ * @return
+ */
+ private boolean isInstanceVarRef(Node node) {
+ return ((node instanceof InstAsgnNode) || (node instanceof InstVarNode));
+ }
+
+ /**
+ * Determines whether a given node is a class variable reference
+ *
+ * @param node
+ * @return
+ */
+ private boolean isClassVarRef(Node node) {
+ return ((node instanceof ClassVarNode) || (node instanceof ClassVarAsgnNode) || (node instanceof ClassVarDeclNode));
+ }
+
+ /**
+ * Determines whether a given node is a global variable reference
+ *
+ * @param node
+ * @return
+ */
+ private boolean isGlobalVarRef(Node node) {
+ return ((node instanceof GlobalAsgnNode) || (node instanceof GlobalVarNode));
+ }
+
+ /**
+ * Determines whether a given node is a constant reference (constant)
+ *
+ * @param node
+ * @return
+ */
+ private boolean isConstRef(Node node) {
+ return (node instanceof ConstNode);
+ }
+
+ /**
+ * Determines whether a given node is a type reference (class, module)
+ *
+ * @param node
+ * @return
+ */
+ private boolean isTypeRef(Node node) {
+ // TODO: Classes can be referred to as a ConstNode; i.e. "class
+ // Klass;end; k = Klass.new" the last reference is a ConstNode, not a
+ // ClassNode. Special way to handle this?
+ return ((node instanceof ClassNode) || (node instanceof ModuleNode) || (node instanceof ConstNode));
+ }
+
+ // ****************************************************************************
+ // *
+ // * Worker methods - handles delegation of occurrence searches
+ // *
+ // ****************************************************************************
+
+ /**
+ * Collects all corresponding local variable occurrences
+ *
+ * @param root
+ * Root node to search
+ * @param fSelectedNode
+ * Originating node
+ * @param occurrences
+ */
+ private void pushLocalVarRefs(Node root, Node orig, List<Node> occurrences) {
+ // Find the search space
+ Node searchSpace = FirstPrecursorNodeLocator.Instance().findFirstPrecursor(root, orig.getPosition().getStartOffset(), new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ return ((node instanceof DefnNode) || (node instanceof DefsNode) ); // TODO: Block Body?
+ }
+ });
+
+ // If no enclosing node found, search the entire space
+ if (searchSpace == null) {
+ searchSpace = root;
+ }
+
+ // Finalize searchSpace because Java's scoping rules are the awesome
+ final Node finalSearchSpace = searchSpace;
+
+ // Get name of local variable reference
+ final String origName = ASTUtil.getNameReflectively(orig);
+
+ // Find all pertinent nodes
+ List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ String name = ASTUtil.getNameReflectively(node);
+ return (name != null && name.equals(origName));
+ }
+ });
+
+ // Scrape position from pertinent nodes
+ for (Node searchResult : searchResults) {
+ occurrences.add(searchResult);
+ }
+ }
+
+ /**
+ * Collects all corresponding dynamic variable occurrences
+ *
+ * @param root
+ * Root node to search
+ * @param fSelectedNode
+ * Originating node
+ * @param occurrences
+ */
+ private void pushDVarRefs(Node root, Node orig, List<Node> occurrences) {
+ // Find the search space
+ Node searchSpace = FirstPrecursorNodeLocator.Instance().findFirstPrecursor(root, orig.getPosition().getStartOffset(), new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ return ((node instanceof DefnNode) || (node instanceof DefsNode) ); // TODO: Block Body?
+ }
+ });
+
+ // If no enclosing node found, search the entire space
+ if (searchSpace == null) {
+ searchSpace = root;
+ }
+
+ // Get name of local variable reference
+ final String origName = ASTUtil.getNameReflectively(orig);
+
+ // Find all pertinent nodes
+ List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ if (isDVarRef(node)) {
+ String name = ASTUtil.getNameReflectively(node);
+ return (name != null && name.equals(origName));
+ }
+ return false;
+ }
+ });
+
+ // Scrape position from pertinent nodes
+ for (Node searchResult : searchResults) {
+ occurrences.add(searchResult);
+ }
+ }
+
+ /**
+ * Collects all instance variable occurrences
+ *
+ * @param root
+ * @param fSelectedNode
+ * @param occurrences
+ */
+ private void pushInstVarRefs(Node root, Node orig, List<Node> occurrences) {
+ Node searchSpace = determineSearchSpace(root, orig);
+
+ // Finalize searchSpace because Java's scoping rules are the awesome
+ // todo: not needed?
+ // final Node finalSearchSpace = searchSpace;
+
+ // Get name of local variable reference
+ final String origName = ASTUtil.getNameReflectively(orig);
+
+ // Find all pertinent nodes
+ List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ if (isInstanceVarRef(node)) {
+ String name = ASTUtil.getNameReflectively(node);
+ return (name != null && name.equals(origName));
+ }
+ return false;
+ }
+ });
+
+ // Scrape position from pertinent nodes
+ for (Node searchResult : searchResults) {
+ occurrences.add(searchResult);
+ }
+
+ }
+
+ private Node determineSearchSpace(Node root, Node orig) {
+
+ // Find the name of the enclosing class
+ ClassNode enclosingClass = (ClassNode) FirstPrecursorNodeLocator.Instance().findFirstPrecursor(root, orig.getPosition().getStartOffset(), new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ return (node instanceof ClassNode);
+ }
+ });
+
+ // If no enclosing class is identified, search root.
+ if (enclosingClass == null) {
+ return root;
+ }
+ // Find the search space - all ClassNodes for that name within root
+ // scope
+ else {
+ final String className = getClassNodeName(enclosingClass);
+ List<Node> classNodes = ScopedNodeLocator.Instance().findNodesInScope(root, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ if (node instanceof ClassNode) {
+ return getClassNodeName((ClassNode) node).equals(className);
+ }
+ return false;
+ }
+ });
+ BlockNode blockNode = new BlockNode(new SourcePosition());
+ for (Node classNode : classNodes) {
+ blockNode.add(classNode);
+ }
+ return blockNode;
+ }
+ }
+
+ /**
+ * Collects all class variable occurrences
+ *
+ * @param root
+ * @param fSelectedNode
+ * @param occurrences
+ */
+ private void pushClassVarRefs(Node root, Node orig, List<Node> occurrences) {
+ Node searchSpace = determineSearchSpace(root, orig);
+
+ // Finalize searchSpace because Java's scoping rules are the awesome
+ // todo: not needed?
+ // final Node finalSearchSpace = searchSpace;
+
+ // Get name of local variable reference
+ final String origName = ASTUtil.getNameReflectively(orig);
+
+ // Find all pertinent nodes
+ List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ if (isClassVarRef(node)) {
+ String name = ASTUtil.getNameReflectively(node);
+ return (name != null && name.equals(origName));
+ }
+ return false;
+ }
+ });
+
+ // Scrape position from pertinent nodes
+ for (Node searchResult : searchResults) {
+ occurrences.add(searchResult);
+ }
+
+ }
+
+ /**
+ * Collects all global variable occurrences
+ *
+ * @param root
+ * @param fSelectedNode
+ * @param occurrences
+ */
+ private void pushGlobalVarRefs(Node root, Node orig, List<Node> occurrences) {
+ final Node searchSpace = root;
+ final String origName = ASTUtil.getNameReflectively(orig);
+
+ // Find all pertinent nodes
+ List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ return isGlobalVarRef(node) && ASTUtil.getNameReflectively(node).equals(origName);
+ }
+ });
+
+ // Scrape position from pertinent nodes
+ for (Node searchResult : searchResults) {
+ occurrences.add(searchResult);
+ }
+ }
+
+ /**
+ * Collects all symbol occurrences
+ *
+ * @param root
+ * @param fSelectedNode
+ * @param occurrences
+ */
+ private void pushSymbolRefs(Node root, Node orig, List<Node> occurrences) {
+ final Node searchSpace = root;
+ final String origName = ((SymbolNode) orig).getName();
+
+ // Find all pertinent nodes
+ List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(searchSpace, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ return (node instanceof SymbolNode) && ((SymbolNode) node).getName().equals(origName);
+ }
+ });
+
+ // Scrape position from pertinent nodes
+ for (Node searchResult : searchResults) {
+ occurrences.add(searchResult);
+ }
+ }
+
+ // todo: complete
+ // private void pushMethodRefs( Node root, Node fSelectedNode, List<ISourcePosition>
+ // occurrences) {
+ //
+ // // DefnNode DefsNode CallNode VCallNode
+ //
+ // System.out.println("Finding occurrences for method reference node " +
+ // fSelectedNode.toString() );
+ //
+ // final Node searchSpace = root;
+ // String origName = getMethodRefName(fSelectedNode);
+ //
+ // // If fSelectedNode is a method definition, find all occurrences to that selector
+ // for the fSelectedNode's enclosing type
+ // if ( fSelectedNode instanceof DefnNode || fSelectedNode instanceof DefsNode )
+ // {
+ // ((DefnNode)fSelectedNode).g
+ // }
+ //
+ // Node receiver = getMethodReceiver(fSelectedNode);
+ // }
+
+ /**
+ * Collects all pertinent const occurrences
+ */
+ private void pushConstRefs(Node root, Node orig, List<Node> occurrences) {
+ if (!isConstRef(orig)) {
+ return;
+ }
+
+ final String matchName = ASTUtil.getNameReflectively(orig);
+ List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(root, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ if (isConstRef(node)) {
+ return ASTUtil.getNameReflectively(node).equals(matchName);
+ }
+ return false;
+ }
+ });
+
+ for (Node searchResult : searchResults) {
+ occurrences.add(searchResult);
+ }
+ }
+
+ /**
+ * Collects all pertinent type ref occurrences
+ */
+ private void pushTypeRefs(Node root, Node orig, List<Node> occurrences) {
+ if (!isTypeRef(orig)) {
+ return;
+ }
+
+ final String matchName = ASTUtil.getNameReflectively(orig);
+ List<Node> searchResults = ScopedNodeLocator.Instance().findNodesInScope(root, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ if (isTypeRef(node...
[truncated message content] |