|
From: <caw...@us...> - 2007-06-06 14:37:07
|
Revision: 2584
http://svn.sourceforge.net/rubyeclipse/?rev=2584&view=rev
Author: cawilliams
Date: 2007-06-06 07:37:04 -0700 (Wed, 06 Jun 2007)
Log Message:
-----------
rename DefaultOccurrencesFinder to OccurrencesFinder to match JDT more
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyAbstractEditor.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/actions/FindOccurrencesInFileAction.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/search/MarkOccurrencesTest.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/OccurrencesFinder.java
Removed Paths:
-------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/DefaultOccurrencesFinder.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyAbstractEditor.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyAbstractEditor.java 2007-06-06 14:34:57 UTC (rev 2583)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyAbstractEditor.java 2007-06-06 14:37:04 UTC (rev 2584)
@@ -82,7 +82,7 @@
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.internal.ui.RubyPlugin;
import org.rubypeople.rdt.internal.ui.rubyeditor.RubyEditor.ITextConverter;
-import org.rubypeople.rdt.internal.ui.search.DefaultOccurrencesFinder;
+import org.rubypeople.rdt.internal.ui.search.OccurrencesFinder;
import org.rubypeople.rdt.internal.ui.search.IOccurrencesFinder;
import org.rubypeople.rdt.internal.ui.text.ContentAssistPreference;
import org.rubypeople.rdt.internal.ui.text.IRubyPartitions;
@@ -1422,7 +1422,7 @@
protected void installOccurrencesFinder(boolean forceUpdate) {
fMarkOccurrenceAnnotations= true;
- fOccurrencesFinder = new DefaultOccurrencesFinder();
+ fOccurrencesFinder = new OccurrencesFinder();
fPostSelectionListener = new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
Deleted: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/DefaultOccurrencesFinder.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/DefaultOccurrencesFinder.java 2007-06-06 14:34:57 UTC (rev 2583)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/DefaultOccurrencesFinder.java 2007-06-06 14:37:04 UTC (rev 2584)
@@ -1,729 +0,0 @@
-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.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)) {
- return getTypeRefName(node).equals(matchName);
- }
- return false;
- }
- });
-
- for (Node searchResult : searchResults) {
- occurrences.add(searchResult);
- }
- }
-
- private void pushReturns(Node root, Node orig, List<Node> 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);
- }
- }
-
- // ****************************************************************************
- // *
- // * Utility methods
- // *
- // ****************************************************************************
-
- /**
- * Gets the position of the name for the specified node.
- *
- * @param node
- * Node that responds to getName() or some variant
- * @return ISourcePosition that holds the name of the node
- */
- private ISourcePosition getPositionOfName(Node node) {
- ISourcePosition pos = node.getPosition();
-
- // TODO refactor the getting-of-name
- String name = null;
- if (node instanceof ReturnNode) {
- return node.getPosition();
- } else 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());
- }
- 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);
- }
-
- public String getElementName() {
- if (fSelectedNode != null) {
- return ASTUtil.stringRepresentation(fSelectedNode);
- }
- return null;
- }
-
-}
Copied: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/OccurrencesFinder.java (from rev 2583, trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/DefaultOccurrencesFinder.java)
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/OccurrencesFinder.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/OccurrencesFinder.java 2007-06-06 14:37:04 UTC (rev 2584)
@@ -0,0 +1,729 @@
+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.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 OccurrencesFinder 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)) {
+ return getTypeRefName(node).equals(matchName);
+ }
+ return false;
+ }
+ });
+
+ for (Node searchResult : searchResults) {
+ occurrences.add(searchResult);
+ }
+ }
+
+ private void pushReturns(Node root, Node orig, List<Node> 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);
+ }
+ }
+
+ // ****************************************************************************
+ // *
+ // * Utility methods
+ // *
+ // ****************************************************************************
+
+ /**
+ * Gets the position of the name for the specified node.
+ *
+ * @param node
+ * Node that responds to getName() or some variant
+ * @return ISourcePosition that holds the name of the node
+ */
+ private ISourcePosition getPositionOfName(Node node) {
+ ISourcePosition pos = node.getPosition();
+
+ // TODO refactor the getting-of-name
+ String name = null;
+ if (node instanceof ReturnNode) {
+ return node.getPosition();
+ } else 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());
+ }
+ 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);
+ }
+
+ public String getElementName() {
+ if (fSelectedNode != null) {
+ return ASTUtil.stringRepresentation(fSelectedNode);
+ }
+ return null;
+ }
+
+}
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/actions/FindOccurrencesInFileAction.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/actions/FindOccurrencesInFileAction.java 2007-06-06 14:34:57 UTC (rev 2583)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/actions/FindOccurrencesInFileAction.java 2007-06-06 14:37:04 UTC (rev 2584)
@@ -33,7 +33,7 @@
import org.rubypeople.rdt.internal.ui.actions.ActionUtil;
import org.rubypeople.rdt.internal.ui.rubyeditor.IRubyScriptEditorInput;
import org.rubypeople.rdt.internal.ui.rubyeditor.RubyEditor;
-import org.rubypeople.rdt.internal.ui.search.DefaultOccurrencesFinder;
+import org.rubypeople.rdt.internal.ui.search.OccurrencesFinder;
import org.rubypeople.rdt.internal.ui.search.FindOccurrencesEngine;
import org.rubypeople.rdt.internal.ui.search.SearchMessages;
@@ -143,7 +143,7 @@
IMember member= getMember(selection);
if (!ActionUtil.isProcessable(getShell(), member))
return;
- FindOccurrencesEngine engine= FindOccurrencesEngine.create(member, new DefaultOccurrencesFinder());
+ FindOccurrencesEngine engine= FindOccurrencesEngine.create(member, new OccurrencesFinder());
try {
ISourceRange range= member.getNameRange();
String result= engine.run(range.getOffset(), range.getLength());
@@ -178,7 +178,7 @@
IRubyElement input= getEditorInput(fEditor);
if (!ActionUtil.isProcessable(getShell(), input))
return;
- FindOccurrencesEngine engine= FindOccurrencesEngine.create(input, new DefaultOccurrencesFinder());
+ FindOccurrencesEngine engine= FindOccurrencesEngine.create(input, new OccurrencesFinder());
try {
String result= engine.run(ts.getOffset(), ts.getLength());
if (result != null)
Modified: trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/search/MarkOccurrencesTest.java
===================================================================
--- trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/search/MarkOccurrencesTest.java 2007-06-06 14:34:57 UTC (rev 2583)
+++ trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/search/MarkOccurrencesTest.java 2007-06-06 14:37:04 UTC (rev 2584)
@@ -5,7 +5,7 @@
import junit.framework.TestCase;
import org.eclipse.jface.text.Position;
-import org.rubypeople.rdt.internal.ui.search.DefaultOccurrencesFinder;
+import org.rubypeople.rdt.internal.ui.search.OccurrencesFinder;
/**
* Tests related to matching occurrences.
@@ -17,7 +17,7 @@
private IOccurrencesFinder occurrencesFinder;
public void setUp() {
- occurrencesFinder = new DefaultOccurrencesFinder();
+ occurrencesFinder = new OccurrencesFinder();
occurrencesFinder.setFMarkConstantOccurrences(true);
occurrencesFinder.setFMarkFieldOccurrences(true);
occurrencesFinder.setFMarkLocalVariableOccurrences(true);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|