|
From: <caw...@us...> - 2007-05-23 16:01:17
|
Revision: 2526
http://svn.sourceforge.net/rubyeclipse/?rev=2526&view=rev
Author: cawilliams
Date: 2007-05-23 09:01:12 -0700 (Wed, 23 May 2007)
Log Message:
-----------
implement finding field references (not just declarations)
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/FieldReferenceMatch.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/FieldLocator.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchLocator.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/FieldReferenceMatch.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/FieldReferenceMatch.java 2007-05-23 16:00:37 UTC (rev 2525)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/FieldReferenceMatch.java 2007-05-23 16:01:12 UTC (rev 2526)
@@ -26,11 +26,13 @@
private boolean isReadAccess;
private boolean isWriteAccess;
+ private IRubyElement binding;
/**
* Creates a new field reference match.
*
* @param enclosingElement the inner-most enclosing member that references this field
+ * @param binding The actual field we are referring to
* @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
* @param offset the offset the match starts at, or -1 if unknown
* @param length the length of the match, or -1 if unknown
@@ -41,9 +43,10 @@
* @param participant the search participant that created the match
* @param resource the resource of the element
*/
- public FieldReferenceMatch(IRubyElement enclosingElement, int accuracy, int offset, int length, boolean isReadAccess, boolean isWriteAccess, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+ public FieldReferenceMatch(IRubyElement enclosingElement, IRubyElement binding, int accuracy, int offset, int length, boolean isReadAccess, boolean isWriteAccess, boolean insideDocComment, SearchParticipant participant, IResource resource) {
super(enclosingElement, accuracy, offset, length, participant, resource);
- this.isReadAccess = isReadAccess;
+ this.binding = binding;
+ this.isReadAccess = isReadAccess;
this.isWriteAccess = isWriteAccess;
setInsideDocComment(insideDocComment);
}
@@ -68,4 +71,8 @@
return this.isWriteAccess;
}
+ public IRubyElement getBinding() {
+ return this.binding;
+ }
+
}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/FieldLocator.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/FieldLocator.java 2007-05-23 16:00:37 UTC (rev 2525)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/FieldLocator.java 2007-05-23 16:01:12 UTC (rev 2526)
@@ -1,13 +1,26 @@
package org.rubypeople.rdt.internal.core.search.matching;
import org.eclipse.core.runtime.CoreException;
-import org.rubypeople.rdt.core.IField;
+import org.jruby.ast.ClassVarAsgnNode;
+import org.jruby.ast.ClassVarNode;
+import org.jruby.ast.ConstDeclNode;
+import org.jruby.ast.GlobalAsgnNode;
+import org.jruby.ast.GlobalVarNode;
+import org.jruby.ast.InstAsgnNode;
+import org.jruby.ast.InstVarNode;
+import org.jruby.ast.Node;
+import org.jruby.ast.types.INameNode;
+import org.jruby.evaluator.Instruction;
import org.rubypeople.rdt.core.IMember;
import org.rubypeople.rdt.core.IParent;
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.ISourceRange;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.internal.core.RubyScript;
+import org.rubypeople.rdt.internal.core.parser.InOrderVisitor;
+import org.rubypeople.rdt.internal.core.parser.RubyParser;
public class FieldLocator extends PatternLocator {
@@ -19,10 +32,95 @@
}
@Override
- public void reportMatches(RubyScript script, MatchLocator locator) {
- reportMatches((IParent) script, locator);
+ public void reportMatches(final RubyScript script, final MatchLocator locator) {
+// reportMatches((IParent) script, locator);
+ reportASTMatches(script, locator);
}
+ private void reportASTMatches(final RubyScript script, final MatchLocator locator) {
+ try {
+ Node ast = script.lastGoodAST;
+ if (ast == null) {
+ ast = new RubyParser().parse(script.getSource());
+ }
+ new InOrderVisitor() {
+
+ @Override
+ public Instruction visitInstVarNode(InstVarNode iVisited) {
+ match(iVisited);
+ return super.visitInstVarNode(iVisited);
+ }
+
+ // XXX Handle constants!
+
+ @Override
+ public Instruction visitGlobalVarNode(GlobalVarNode iVisited) {
+ match(iVisited);
+ return super.visitGlobalVarNode(iVisited);
+ }
+
+ @Override
+ public Instruction visitConstDeclNode(ConstDeclNode iVisited) {
+ match(iVisited);
+ return super.visitConstDeclNode(iVisited);
+ }
+
+ @Override
+ public Instruction visitGlobalAsgnNode(GlobalAsgnNode iVisited) {
+ match(iVisited);
+ return super.visitGlobalAsgnNode(iVisited);
+ }
+
+ @Override
+ public Instruction visitClassVarNode(ClassVarNode iVisited) {
+ match(iVisited);
+ return super.visitClassVarNode(iVisited);
+ }
+
+ @Override
+ public Instruction visitClassVarAsgnNode(ClassVarAsgnNode iVisited) {
+ match(iVisited);
+ return super.visitClassVarAsgnNode(iVisited);
+ }
+
+ @Override
+ public Instruction visitInstAsgnNode(InstAsgnNode iVisited) {
+ match(iVisited);
+ return super.visitInstAsgnNode(iVisited);
+ }
+
+ private void match(Node iVisited) {
+ int accuracy = getAccuracy(((INameNode)iVisited).getName());
+ if (accuracy != IMPOSSIBLE_MATCH) {
+ try {
+ IRubyElement element = script.getElementAt(iVisited.getPosition().getStartOffset());
+ if (locator.encloses(element)) {
+ IRubyElement binding = resolve(element, ((INameNode)iVisited).getName());
+ locator.report(locator.newFieldReferenceMatch(element, binding, accuracy,
+ iVisited.getPosition().getStartOffset(), iVisited.getPosition().getEndOffset(), iVisited));
+ }
+ } catch (CoreException e) {
+ RubyCore.log(e);
+ }
+ }
+ }
+
+ private IRubyElement resolve(IRubyElement element, String name) {
+ if (element instanceof IMember) {
+ IMember member = (IMember) element;
+ IType type = member.getDeclaringType();
+ return type.getField(name);
+ }
+ return null;
+ }
+
+
+ }.acceptNode(ast);
+ } catch(RubyModelException e) {
+ RubyCore.log(e);
+ }
+ }
+
private void reportMatches(IParent parent, MatchLocator locator) {
try {
IRubyElement[] children = parent.getChildren();
@@ -33,15 +131,14 @@
child.isType(IRubyElement.CONSTANT) ||
child.isType(IRubyElement.CLASS_VAR) ||
child.isType(IRubyElement.INSTANCE_VAR)) {
- int accuracy = getAccuracy((IField) child);
+ int accuracy = getAccuracy(child.getElementName());
if (accuracy != IMPOSSIBLE_MATCH) {
IMember member = (IMember) child;
ISourceRange range = member.getSourceRange();
try {
locator.report(locator.newDeclarationMatch(child, accuracy, range.getOffset(), range.getLength()));
} catch (CoreException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ RubyCore.log(e);
}
}
}
@@ -51,20 +148,19 @@
}
}
} catch (RubyModelException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ RubyCore.log(e);
}
}
- private int getAccuracy(IField field) {
+ private int getAccuracy(String name) {
if (this.pattern.findReferences)
// must be a write only access with an initializer
if (this.pattern.writeAccess)
- if (matchesName(this.pattern.name, field.getElementName().toCharArray()))
+ if (matchesName(this.pattern.name, name.toCharArray()))
return ACCURATE_MATCH;
if (this.pattern.findDeclarations) {
- if (matchesName(this.pattern.name, field.getElementName().toCharArray()))
+ if (matchesName(this.pattern.name, name.toCharArray()))
return ACCURATE_MATCH;
}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchLocator.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchLocator.java 2007-05-23 16:00:37 UTC (rev 2525)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchLocator.java 2007-05-23 16:01:12 UTC (rev 2526)
@@ -10,11 +10,16 @@
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
+import org.jruby.ast.ClassVarAsgnNode;
+import org.jruby.ast.GlobalAsgnNode;
+import org.jruby.ast.InstAsgnNode;
+import org.jruby.ast.Node;
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.IRubyProject;
import org.rubypeople.rdt.core.IRubyScript;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.core.search.FieldDeclarationMatch;
+import org.rubypeople.rdt.core.search.FieldReferenceMatch;
import org.rubypeople.rdt.core.search.IRubySearchScope;
import org.rubypeople.rdt.core.search.MethodDeclarationMatch;
import org.rubypeople.rdt.core.search.SearchDocument;
@@ -335,6 +340,10 @@
}
}
+ protected boolean encloses(IRubyElement element) {
+ return element != null && this.scope.encloses(element);
+ }
+
protected void report(SearchMatch match) throws CoreException {
long start = -1;
if (BasicSearchEngine.VERBOSE) {
@@ -499,4 +508,23 @@
return new TypeReferenceMatch(enclosingElement, accuracy, offset, length, participant, resource);
}
+ public SearchMatch newFieldReferenceMatch(
+ IRubyElement enclosingElement,
+ IRubyElement binding, int accuracy,
+ int offset,
+ int length,
+ Node reference) {
+ boolean isReadAccess = false;
+ boolean isWriteAccess = false;
+ if ((reference instanceof GlobalAsgnNode) || (reference instanceof ClassVarAsgnNode) ||
+ (reference instanceof InstAsgnNode)) {
+ isWriteAccess = true;
+ } else {
+ isReadAccess = true;
+ }
+ SearchParticipant participant = getParticipant();
+ IResource resource = this.currentPossibleMatch.resource;
+ return new FieldReferenceMatch(enclosingElement, binding, accuracy, offset, length, isReadAccess, isWriteAccess, false, participant, resource);
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|