You can subscribe to this list here.
| 2005 |
Jan
|
Feb
|
Mar
(41) |
Apr
(9) |
May
|
Jun
|
Jul
(39) |
Aug
(38) |
Sep
(135) |
Oct
(220) |
Nov
(75) |
Dec
(74) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2006 |
Jan
(44) |
Feb
(160) |
Mar
(49) |
Apr
(69) |
May
(40) |
Jun
(52) |
Jul
(47) |
Aug
(51) |
Sep
(19) |
Oct
(22) |
Nov
(36) |
Dec
(76) |
| 2007 |
Jan
(154) |
Feb
(165) |
Mar
(186) |
Apr
(143) |
May
(175) |
Jun
(133) |
Jul
(203) |
Aug
(177) |
Sep
(136) |
Oct
|
Nov
|
Dec
|
|
From: <caw...@us...> - 2007-05-17 15:56:06
|
Revision: 2497
http://svn.sourceforge.net/rubyeclipse/?rev=2497&view=rev
Author: cawilliams
Date: 2007-05-17 08:55:56 -0700 (Thu, 17 May 2007)
Log Message:
-----------
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchPattern.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchPattern.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchPattern.java 2007-05-17 14:37:56 UTC (rev 2496)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchPattern.java 2007-05-17 15:55:56 UTC (rev 2497)
@@ -390,7 +390,8 @@
* - '?' is treated as a wildcard when it is inside <> (ie. it must be put on first position of the type argument)
*/
private static SearchPattern createTypePattern(String patternString, int limitTo, int matchRule, char indexSuffix) {
- char[] typePart = patternString.toCharArray();
+ char[] typePart = null;
+ if (patternString != null) typePart = patternString.toCharArray();
char[] typeChars = null;
char[] qualificationChars = null;
// get qualification name
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-17 14:37:57
|
Revision: 2496
http://svn.sourceforge.net/rubyeclipse/?rev=2496&view=rev
Author: cawilliams
Date: 2007-05-17 07:37:56 -0700 (Thu, 17 May 2007)
Log Message:
-----------
when we try to resolve a call node and we can't infer the type, fall back to grabbing all types with a defined method matching the call node's name.
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/SelectionEngine.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/SelectionEngine.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/SelectionEngine.java 2007-05-17 14:37:23 UTC (rev 2495)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/SelectionEngine.java 2007-05-17 14:37:56 UTC (rev 2496)
@@ -173,6 +173,28 @@
} else {
ITypeInferrer inferrer = new DefaultTypeInferrer();
List<ITypeGuess> guesses = inferrer.infer(source, start);
+ // TODO If guesses are empty, just do a global search for this method?
+ if (guesses.isEmpty()) {
+ String methodName = ASTUtil.getNameReflectively(selected);
+ IRubySearchScope scope = SearchEngine.createRubySearchScope(new IRubyElement[] { script.getRubyProject() });
+ CollectingSearchRequestor requestor = new CollectingSearchRequestor();
+ SearchPattern pattern = SearchPattern.createPattern(
+ IRubyElement.METHOD, methodName,
+ IRubySearchConstants.DECLARATIONS,
+ SearchPattern.R_EXACT_MATCH);
+ SearchParticipant[] participants = { BasicSearchEngine.getDefaultSearchParticipant() };
+ try {
+ new BasicSearchEngine().search(pattern, participants, scope, requestor, null);
+ } catch (CoreException e) {
+ RubyCore.log(e);
+ }
+ List<SearchMatch> matches = requestor.getResults();
+ if (matches == null || matches.isEmpty()) return new IType[0];
+ for (SearchMatch match : matches) {
+ IMethod method = (IMethod) match.getElement();
+ types.add(method.getDeclaringType());
+ }
+ } else {
RubyElementRequestor requestor = new RubyElementRequestor(
script);
for (ITypeGuess guess : guesses) {
@@ -182,6 +204,7 @@
types.add(tmpTypes[i]);
}
}
+ }
}
return types.toArray(new IType[types.size()]);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-17 14:37:24
|
Revision: 2495
http://svn.sourceforge.net/rubyeclipse/?rev=2495&view=rev
Author: cawilliams
Date: 2007-05-17 07:37:23 -0700 (Thu, 17 May 2007)
Log Message:
-----------
fix traversal of AndNode
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/parser/InOrderVisitor.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/parser/InOrderVisitor.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/parser/InOrderVisitor.java 2007-05-17 14:23:38 UTC (rev 2494)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/parser/InOrderVisitor.java 2007-05-17 14:37:23 UTC (rev 2495)
@@ -148,7 +148,7 @@
public Instruction visitAndNode(AndNode iVisited) {
handleNode(iVisited);
acceptNode(iVisited.getFirstNode());
- acceptNode(iVisited.getFirstNode());
+ acceptNode(iVisited.getSecondNode());
return null;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-17 14:23:39
|
Revision: 2494
http://svn.sourceforge.net/rubyeclipse/?rev=2494&view=rev
Author: cawilliams
Date: 2007-05-17 07:23:38 -0700 (Thu, 17 May 2007)
Log Message:
-----------
handle more cases
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/SelectionEngine.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/SelectionEngine.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/SelectionEngine.java 2007-05-16 20:38:09 UTC (rev 2493)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/SelectionEngine.java 2007-05-17 14:23:38 UTC (rev 2494)
@@ -124,68 +124,68 @@
if (isMethodCall(selected)) {
String methodName = getName(selected);
Set<IRubyElement> possible = new HashSet<IRubyElement>();
- // FIXME If VCallNode we know the method is in the enclosing scope
- // (usually the type or it's hierarchy)
- if (selected instanceof VCallNode) {
- Node enclosingTypeNode = ClosestSpanningNodeLocator.Instance()
- .findClosestSpanner(root, start, new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- return (node instanceof ClassNode || node instanceof ModuleNode);
- }
- });
- if (enclosingTypeNode == null) {
- // TODO Handle case we're in top-level - we need to find the method some other way!
- RubyCore.log("Was unable to grab the enclosing type for our VCallNode. Maybe we're in top-level?");
- return new IRubyElement[0];
- }
- String typeName = ASTUtil.getNameReflectively(enclosingTypeNode);
- IRubySearchScope scope = SearchEngine.createRubySearchScope(new IRubyElement[] { script });
- CollectingSearchRequestor requestor = new CollectingSearchRequestor();
- SearchPattern pattern = SearchPattern.createPattern(
- IRubyElement.TYPE, typeName,
- IRubySearchConstants.DECLARATIONS,
- SearchPattern.R_EXACT_MATCH);
- SearchParticipant[] participants = { BasicSearchEngine.getDefaultSearchParticipant() };
- try {
- new BasicSearchEngine().search(pattern, participants, scope, requestor, null);
- } catch (CoreException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- List<SearchMatch> matches = requestor.getResults();
- if (matches == null || matches.isEmpty()) return new IRubyElement[0];
- SearchMatch match = matches.get(0);
- IType type = (IType) match.getElement();
+ IType[] types = getReceiver(script, source, selected, root, start);
+ for (int i = 0; i < types.length; i++) {
+ IType type = types[i];
Collection<IMethod> methods = suggestMethods(type);
for (IMethod method : methods) {
if (method.getElementName().equals(methodName))
possible.add(method);
}
- } else {
+ }
+ return possible.toArray(new IRubyElement[possible.size()]);
+ }
+ return new IRubyElement[0];
+ }
+
+ private IType[] getReceiver(IRubyScript script, String source, Node selected, Node root, int start) {
+ List<IType> types = new ArrayList<IType>();
+ if ((selected instanceof FCallNode) || (selected instanceof VCallNode)) {
+ Node receiver = null;
+ IRubySearchScope scope = null;
- ITypeInferrer inferrer = new DefaultTypeInferrer();
- List<ITypeGuess> guesses = inferrer.infer(source, start);
- RubyElementRequestor requestor = new RubyElementRequestor(
- script);
- for (ITypeGuess guess : guesses) {
- String name = guess.getType();
- IType[] types = requestor.findType(name);
- for (int i = 0; i < types.length; i++) {
- IType type = types[i];
- Collection<IMethod> methods = suggestMethods(type);
- for (IMethod method : methods) {
- if (method.getElementName().equals(methodName))
- possible.add(method);
- }
+ receiver = ClosestSpanningNodeLocator.Instance()
+ .findClosestSpanner(root, start, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ return (node instanceof ClassNode || node instanceof ModuleNode);
}
+ });
+ scope = SearchEngine.createRubySearchScope(new IRubyElement[] { script });
+
+
+ String typeName = ASTUtil.getNameReflectively(receiver);
+ CollectingSearchRequestor requestor = new CollectingSearchRequestor();
+ SearchPattern pattern = SearchPattern.createPattern(
+ IRubyElement.TYPE, typeName,
+ IRubySearchConstants.DECLARATIONS,
+ SearchPattern.R_EXACT_MATCH);
+ SearchParticipant[] participants = { BasicSearchEngine.getDefaultSearchParticipant() };
+ try {
+ new BasicSearchEngine().search(pattern, participants, scope, requestor, null);
+ } catch (CoreException e) {
+ RubyCore.log(e);
+ }
+ List<SearchMatch> matches = requestor.getResults();
+ if (matches == null || matches.isEmpty()) return new IType[0]; // TODO Check up the type hierarchy!
+ for (SearchMatch match : matches) {
+ types.add((IType) match.getElement());
+ }
+ } else {
+ ITypeInferrer inferrer = new DefaultTypeInferrer();
+ List<ITypeGuess> guesses = inferrer.infer(source, start);
+ RubyElementRequestor requestor = new RubyElementRequestor(
+ script);
+ for (ITypeGuess guess : guesses) {
+ String name = guess.getType();
+ IType[] tmpTypes = requestor.findType(name);
+ for (int i = 0; i < tmpTypes.length; i++) {
+ types.add(tmpTypes[i]);
}
-
}
- return possible.toArray(new IRubyElement[possible.size()]);
}
- return new IRubyElement[0];
+ return types.toArray(new IType[types.size()]);
}
-
+
// TODO This is all copy-pasted and modified from CompletionEngine. Move this out into a util class and call it from both.
private Collection<IMethod> suggestMethods(IType type) throws RubyModelException {
List<IMethod> proposals = new ArrayList<IMethod>();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-16 20:38:11
|
Revision: 2493
http://svn.sourceforge.net/rubyeclipse/?rev=2493&view=rev
Author: cawilliams
Date: 2007-05-16 13:38:09 -0700 (Wed, 16 May 2007)
Log Message:
-----------
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DataFlowTypeInferrer.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DataFlowTypeInferrer.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DataFlowTypeInferrer.java 2007-05-16 20:33:50 UTC (rev 2492)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DataFlowTypeInferrer.java 2007-05-16 20:38:09 UTC (rev 2493)
@@ -570,10 +570,8 @@
possibleTypes.add( getTypeDefinitionNodeType( enclosingTypeNode ) );
}
if ( node instanceof VCallNode ) {
- System.err.println("//TODO: Why doesn't VCallNode support getReceiverNode() ???");
- //TODO: Why doesn't VCallNode support getReceiverNode() ???
-// Node receiverNode = ((VCallNode)node).getReceiverNode();
-// return inferNodeType( receiverNode );
+ Node enclosingTypeNode = findEnclosingTypeNode(node);
+ possibleTypes.add( getTypeDefinitionNodeType( enclosingTypeNode ) );
}
return possibleTypes;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-16 20:33:51
|
Revision: 2492
http://svn.sourceforge.net/rubyeclipse/?rev=2492&view=rev
Author: cawilliams
Date: 2007-05-16 13:33:50 -0700 (Wed, 16 May 2007)
Log Message:
-----------
fix one case where we could fall into infinite loop doing type inferrencing
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DefaultTypeInferrer.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/DataFlowTypeInferrerTest.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TypeInferrerTest.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TypeInferrerTestCase.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DefaultTypeInferrer.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DefaultTypeInferrer.java 2007-05-16 18:44:05 UTC (rev 2491)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/ti/DefaultTypeInferrer.java 2007-05-16 20:33:50 UTC (rev 2492)
@@ -1,9 +1,11 @@
package org.rubypeople.rdt.internal.ti;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
import org.jruby.ast.ArgsNode;
import org.jruby.ast.ArgumentNode;
@@ -27,6 +29,7 @@
import org.rubypeople.rdt.internal.core.util.ASTUtil;
import org.rubypeople.rdt.internal.ti.data.LiteralNodeTypeNames;
import org.rubypeople.rdt.internal.ti.data.TypicalMethodReturnNames;
+import org.rubypeople.rdt.internal.ti.util.ClosestSpanningNodeLocator;
import org.rubypeople.rdt.internal.ti.util.FirstPrecursorNodeLocator;
import org.rubypeople.rdt.internal.ti.util.INodeAcceptor;
import org.rubypeople.rdt.internal.ti.util.OffsetNodeLocator;
@@ -36,6 +39,7 @@
private static final String CONSTRUCTOR_INVOKE_NAME = "new";
private RootNode rootNode;
+ private Set<Node> dontVisitNodes;
/**
* Infers type inside the source at given offset.
@@ -43,6 +47,7 @@
* @return List of ITypeGuess objects.
*/
public List<ITypeGuess> infer(String source, int offset) {
+ dontVisitNodes = new HashSet<Node>();
try {
RubyParser parser = new RubyParser();
rootNode = (RootNode) parser.parse(source);
@@ -154,13 +159,22 @@
// Or scopingNode. Still not sure whether IterNodes count or not...
// silly block-local-var ambiguity ;)
- // CHRIS - Changed to just grab all assignments to this instance variable, not just first assignment
+ // try and grab the assignment node if this reference is in an assignment, so we can "blacklist" it from being grabbed in next step where we grab all assignments to the instance variable
+ final Node assignmentNode = ClosestSpanningNodeLocator.Instance().findClosestSpanner(rootNode, instVarNode.getPosition().getStartOffset(), new INodeAcceptor() {
+
+ public boolean doesAccept(Node node) {
+ return node instanceof InstAsgnNode;
+ }
+
+ });
+ if (assignmentNode != null) dontVisitNodes.add(assignmentNode);
List<Node> assignments = new ArrayList<Node>();
assignments.addAll(ScopedNodeLocator.Instance().findNodesInScope(rootNode, new INodeAcceptor() {
public boolean doesAccept(Node node) {
- return (node instanceof InstAsgnNode) && (((InstAsgnNode)node).getName().equals(instVarNode.getName()));
+ return (node instanceof InstAsgnNode) && (((InstAsgnNode)node).getName().equals(instVarNode.getName())) && !dontVisitNodes.contains(node);
}
}));
+
for (Node assignNode : assignments) {
tryAsgnNode(assignNode, guesses);
}
Modified: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/DataFlowTypeInferrerTest.java
===================================================================
--- trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/DataFlowTypeInferrerTest.java 2007-05-16 18:44:05 UTC (rev 2491)
+++ trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/DataFlowTypeInferrerTest.java 2007-05-16 20:33:50 UTC (rev 2492)
@@ -1,49 +1,12 @@
package org.rubypeople.rdt.internal.ti;
-import java.util.List;
-import junit.framework.TestCase;
-
/**
* @author Jason
*
*/
-public class DataFlowTypeInferrerTest extends TestCase {
+public class DataFlowTypeInferrerTest extends TypeInferrerTestCase {
- private ITypeInferrer inferrer;
- public void setUp() {
- inferrer = createTypeInferrer();
- }
-
- /**
- * Shortcut for testing that a particular type is the only one inferred,
- * and is inferred with 100% confidence
- * @param guesses
- * @param type
- */
- private void assertInfersTypeWithoutDoubt(List<ITypeGuess> guesses, String type) {
- assertEquals(1, guesses.size());
- ITypeGuess guess = guesses.get(0);
- assertEquals(type, guess.getType());
- assertEquals(100, guess.getConfidence());
- }
-
- /**
- * Shortcut for testing that two types are inferred, each with 50% confidence
- * @param guesses
- * @param type
- * @param type2
- */
-
- private void assertInfersTypeFiftyFifty( List<ITypeGuess> guesses, String type1, String type2 ) {
- assertEquals(2, guesses.size());
- assertEquals( guesses.get(0).getType(), type1 );
- assertEquals( guesses.get(1).getType(), type2 );
- assertEquals( guesses.get(0).getConfidence(), 50 );
- assertEquals( guesses.get(1).getConfidence(), 50 );
- }
-
-
public void testFixnum() throws Exception {
assertInfersTypeWithoutDoubt(inferrer.infer("5", 0), "Fixnum");
}
Modified: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TypeInferrerTest.java
===================================================================
--- trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TypeInferrerTest.java 2007-05-16 18:44:05 UTC (rev 2491)
+++ trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TypeInferrerTest.java 2007-05-16 20:33:50 UTC (rev 2492)
@@ -1,37 +1,16 @@
package org.rubypeople.rdt.internal.ti;
-import java.util.List;
-import junit.framework.TestCase;
-
/**
* @author Jason
*
*/
-/**
- * @author Jason
- *
- */
-public class TypeInferrerTest extends TestCase {
+public class TypeInferrerTest extends TypeInferrerTestCase {
- private ITypeInferrer inferrer;
- public void setUp() {
- inferrer = createTypeInferrer();
+ protected ITypeInferrer createTypeInferrer() {
+ return new DefaultTypeInferrer();
}
- /**
- * Shortcut for testing that a particular type is the only one inferred,
- * and is inferred with 100% confidence
- * @param guesses
- * @param type
- */
- private void assertInfersTypeWithoutDoubt(List<ITypeGuess> guesses, String type) {
- assertEquals(1, guesses.size());
- ITypeGuess guess = guesses.get(0);
- assertEquals(type, guess.getType());
- assertEquals(100, guess.getConfidence());
- }
-
public void testFixnum() throws Exception {
assertInfersTypeWithoutDoubt(inferrer.infer("5", 0), "Fixnum");
}
@@ -77,52 +56,9 @@
assertInfersTypeWithoutDoubt(inferrer.infer("x=Regexp.new;x", 13), "Regexp");
}
-
-
-
-
-
-//todo: at a later date, make sure this is handled:
-/*
- * def foo
- * x = 5
- * puts x
- * end
- *
- * def bar(x)
- * do_stuff_with(x)
- * end
- *
- * param to do_stuff_with should not be affected by the assignment to x in foo.
- */
-// public void testLocalVariableAssignmentWithSameNameAsInAnotherScope() throws Exception {
-// System.out.println("booga");
-// // Note that the N::x may be preceded by another operations that affect its type, such as
-// // x.to_s!. Or it may be a parameter. The search for a preceding LocalAsgnNode should
-// // respect scopes and not override these, say, with the assignment to local x in M.
-// String script = "module M;x=5;x;end;module N;x=6;x;end";
-//
-// // Test first scope
-// List<ITypeGuess> guesses = inferrer.infer(script, 13);
-// assertEquals(1, guesses.size());
-// ITypeGuess guess = guesses.get(0);
-// assertEquals("Fixnum", guess.getType());
-//
-// System.out.println("wooga");
-// // Test second scope
-// guesses = inferrer.infer(script, 32);
-// assertEquals(0, guesses.size());
-//// guess = guesses.get(0);
-//// assertEquals("String", guess.getType());
-// }
-
- /**
- * Override this method in subclasses so that we can test any
- * implementation of ITypeInferrer the same way.
- * @return an implementation of ITypeInferrer
- */
- protected ITypeInferrer createTypeInferrer() {
- return new DefaultTypeInferrer();
+ public void testInfiniteLoop() throws Exception {
+ inferrer.infer("@inst = 1;@inst = @inst.blah", 15);
+ assertTrue(true);
}
}
Added: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TypeInferrerTestCase.java
===================================================================
--- trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TypeInferrerTestCase.java (rev 0)
+++ trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/ti/TypeInferrerTestCase.java 2007-05-16 20:33:50 UTC (rev 2492)
@@ -0,0 +1,54 @@
+package org.rubypeople.rdt.internal.ti;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public abstract class TypeInferrerTestCase extends TestCase {
+
+ protected ITypeInferrer inferrer;
+
+ public TypeInferrerTestCase() {
+ super();
+ }
+
+ public void setUp() {
+ inferrer = createTypeInferrer();
+ }
+
+ /**
+ * Shortcut for testing that a particular type is the only one inferred,
+ * and is inferred with 100% confidence
+ * @param guesses
+ * @param type
+ */
+ protected void assertInfersTypeWithoutDoubt(List<ITypeGuess> guesses, String type) {
+ assertEquals(1, guesses.size());
+ ITypeGuess guess = guesses.get(0);
+ assertEquals(type, guess.getType());
+ assertEquals(100, guess.getConfidence());
+ }
+
+ /**
+ * Shortcut for testing that two types are inferred, each with 50% confidence
+ * @param guesses
+ * @param type
+ * @param type2
+ */
+
+ protected void assertInfersTypeFiftyFifty( List<ITypeGuess> guesses, String type1, String type2 ) {
+ assertEquals(2, guesses.size());
+ assertEquals( guesses.get(0).getType(), type1 );
+ assertEquals( guesses.get(1).getType(), type2 );
+ assertEquals( guesses.get(0).getConfidence(), 50 );
+ assertEquals( guesses.get(1).getConfidence(), 50 );
+ }
+
+ /**
+ * Override this method in subclasses so that we can test any
+ * implementation of ITypeInferrer the same way.
+ * @return an implementation of ITypeInferrer
+ */
+ protected abstract ITypeInferrer createTypeInferrer();
+
+}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-16 18:44:08
|
Revision: 2491
http://svn.sourceforge.net/rubyeclipse/?rev=2491&view=rev
Author: cawilliams
Date: 2007-05-16 11:44:05 -0700 (Wed, 16 May 2007)
Log Message:
-----------
comment out "if __FILE__ == $0" around the startup code because that won't always work out to be true if we're launching the test under the debugger. This fixes ticket #4340
Modified Paths:
--------------
trunk/org.rubypeople.rdt.testunit/ruby/RemoteTestRunner.rb
Modified: trunk/org.rubypeople.rdt.testunit/ruby/RemoteTestRunner.rb
===================================================================
--- trunk/org.rubypeople.rdt.testunit/ruby/RemoteTestRunner.rb 2007-05-16 16:58:11 UTC (rev 2490)
+++ trunk/org.rubypeople.rdt.testunit/ruby/RemoteTestRunner.rb 2007-05-16 18:44:05 UTC (rev 2491)
@@ -256,7 +256,7 @@
end
end
-if __FILE__ == $0
+#if __FILE__ == $0
require 'socket'
if ARGV.empty?
puts "You should supply the name of a test suite file and the port to the runner"
@@ -277,7 +277,6 @@
# 4. test class name (optional)
# 5. test name (optional)
#
-
filename = ARGV[0].slice(0, ARGV[0].rindex('.'))
port = ARGV[1].to_i
keepAliveString = ARGV[2]
@@ -299,4 +298,4 @@
remoteTestRunner.start
session.close
exit
-end
+#end
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-16 16:58:34
|
Revision: 2490
http://svn.sourceforge.net/rubyeclipse/?rev=2490&view=rev
Author: cawilliams
Date: 2007-05-16 09:58:11 -0700 (Wed, 16 May 2007)
Log Message:
-----------
fix launching Test::Unit
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/SourceFolder.java
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardVMRunner.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchConfigurationDelegate.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/SourceFolder.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/SourceFolder.java 2007-05-16 16:37:33 UTC (rev 2489)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/SourceFolder.java 2007-05-16 16:58:11 UTC (rev 2490)
@@ -1,5 +1,6 @@
package org.rubypeople.rdt.internal.core;
+import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
@@ -98,7 +99,7 @@
@Override
public String getElementName() {
if (names.length == 0) return "";
- return names[names.length - 1];
+ return Util.concatWith(this.names, File.separatorChar);
}
public boolean containsRubyResources() throws RubyModelException {
Modified: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardVMRunner.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardVMRunner.java 2007-05-16 16:37:33 UTC (rev 2489)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardVMRunner.java 2007-05-16 16:58:11 UTC (rev 2490)
@@ -207,13 +207,6 @@
// options like '-client' & '-server' which are required to be the first option
String[] allVMArgs = combineVmArgs(config, fVMInstance);
addArguments(allVMArgs, arguments);
- // FIXME Find a way to set stderr and stdout to sync/auto-flush without messing up value of __FILE__ (becomes absolute which messes up the 'if __FILE__ == $0' idiom)
-// arguments.add("-e");
-// arguments.add("STDOUT.sync=true");
-// arguments.add("-e");
-// arguments.add("STDERR.sync=true");
-// arguments.add("-e");
-// arguments.add("load($0=ARGV.shift)");
String[] lp= config.getLoadPath();
if (lp.length > 0) {
Modified: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchConfigurationDelegate.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchConfigurationDelegate.java 2007-05-16 16:37:33 UTC (rev 2489)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchConfigurationDelegate.java 2007-05-16 16:58:11 UTC (rev 2490)
@@ -46,7 +46,7 @@
// setDefaultSourceLocator(launch, configuration);
launch.setAttribute(TestunitPlugin.TESTUNIT_PORT_ATTR, Integer.toString(getPort()));
- if (testTypes.length > 0) launch.setAttribute(TESTTYPE_ATTR, testTypes[0].getHandleIdentifier());
+ if (testTypes != null && testTypes.length > 0) launch.setAttribute(TESTTYPE_ATTR, testTypes[0].getHandleIdentifier());
super.launch(configuration, mode, launch, monitor);
@@ -65,7 +65,11 @@
if (containerHandle.length() > 0) {
IRubyElement element = RubyCore.create(containerHandle);
IRubyScript script = (IRubyScript) element;
- if (script != null) return new IType[] { script.findPrimaryType() };
+ if (script != null) {
+ IType type = script.findPrimaryType();
+ if (type != null)
+ return new IType[] { type };
+ }
}
String testTypeName= configuration.getAttribute(TESTTYPE_ATTR, (String) null);
if (testTypeName != null && testTypeName.length() > 0) {
@@ -143,8 +147,10 @@
String container = configuration.getAttribute(TestUnitLaunchConfigurationDelegate.LAUNCH_CONTAINER_ATTR, "");
IRubyElement element = (IRubyElement) RubyCore.create(container);
if (element != null)
- return element.getResource().getLocation().toFile().getAbsolutePath();
- // otherwise it may be an actual path!
+ container = element.getResource().getProjectRelativePath().toOSString();
+ if (!container.startsWith("\"") && container.indexOf(' ') != -1) {
+ container = '"' + container + '"';
+ }
return container;
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-16 16:37:46
|
Revision: 2489
http://svn.sourceforge.net/rubyeclipse/?rev=2489&view=rev
Author: cawilliams
Date: 2007-05-16 09:37:33 -0700 (Wed, 16 May 2007)
Log Message:
-----------
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TS_InternalUiText.java
Removed Paths:
-------------
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScannerTest.java
Deleted: trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScannerTest.java
===================================================================
--- trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScannerTest.java 2007-05-16 15:58:44 UTC (rev 2488)
+++ trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScannerTest.java 2007-05-16 16:37:33 UTC (rev 2489)
@@ -1,47 +0,0 @@
-package org.rubypeople.rdt.internal.ui.text;
-
-import junit.framework.TestCase;
-
-import org.eclipse.jface.text.Document;
-import org.eclipse.jface.text.IDocument;
-// FIXME Integrate this with already existing PartitionScanner tests
-public class RubyPartitionScannerTest extends TestCase {
-
- private RubyPartitionScanner scanner;
-
- protected void setUp() throws Exception {
- super.setUp();
- scanner = new RubyPartitionScanner();
- }
-
- private void setDocument(String text) {
- IDocument document = new Document(text);
- scanner.setRange(document, 0, document.getLength());
- }
-
- public void testSingleLineComment() {
- setDocument("# comment");
-// assertEquals(IRubyPartitions.RUBY_SINGLE_LINE_COMMENT, scanner
-// .nextToken().getData());
- assertNull(scanner.nextToken().getData()); // comments are default partition now
- }
-
- public void testMultiLineComment() {
- setDocument("=begin\nSome comment text\n=end\n");
- assertEquals(IRubyPartitions.RUBY_MULTI_LINE_COMMENT, scanner
- .nextToken().getData());
- }
-
- public void testMultiLineCommentMustStartAtFirstColumn() {
- setDocument(" =begin\nSome comment text\n=end\n");
- assertFalse(IRubyPartitions.RUBY_MULTI_LINE_COMMENT.equals(scanner
- .nextToken().getData()));
- assertNull(scanner.nextToken().getData());
- }
-
- public void testPoundCharacterIsntAComment() {
- setDocument("?#");
- assertNull(scanner.nextToken().getData());
- }
-
-}
Modified: trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java 2007-05-16 15:58:44 UTC (rev 2488)
+++ trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java 2007-05-16 16:37:33 UTC (rev 2489)
@@ -95,4 +95,17 @@
assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 2));
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 5));
}
+
+ public void testPoundCharacterIsntAComment() {
+ String source = "?#";
+ assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 1));
+ }
+
+ public void testSinglelineCommentJustAfterMultilineComment() {
+ String source = "=begin\nComment\n=end\n# this is a singleline comment\n";
+
+ assertEquals(RubyPartitionScanner.RUBY_MULTI_LINE_COMMENT, this.getContentType(source, 0));
+ assertEquals(RubyPartitionScanner.RUBY_MULTI_LINE_COMMENT, this.getContentType(source, 10));
+ assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, source.length() - 5));
+ }
}
Modified: trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TS_InternalUiText.java
===================================================================
--- trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TS_InternalUiText.java 2007-05-16 15:58:44 UTC (rev 2488)
+++ trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TS_InternalUiText.java 2007-05-16 16:37:33 UTC (rev 2489)
@@ -9,7 +9,6 @@
public static Test suite() {
TestSuite suite = new TestSuite("org.rubypeople.rdt.internal.ui.text");
suite.addTestSuite(TC_RubyPartitionScanner.class);
- suite.addTestSuite(RubyPartitionScannerTest.class);
suite.addTestSuite(TC_RubyWordFinder.class);
suite.addTestSuite(TC_RubyTokenScanner.class);
return suite;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-16 15:58:45
|
Revision: 2488
http://svn.sourceforge.net/rubyeclipse/?rev=2488&view=rev
Author: cawilliams
Date: 2007-05-16 08:58:44 -0700 (Wed, 16 May 2007)
Log Message:
-----------
simplify the scanner a little. Add a new queue to stick tokens into when we hit comments (where suddenly we've advanced past multiple tokens - the comments and the code token)
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java 2007-05-16 15:33:25 UTC (rev 2487)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java 2007-05-16 15:58:44 UTC (rev 2488)
@@ -2,6 +2,7 @@
import java.io.IOException;
import java.io.StringReader;
+import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.text.BadLocationException;
@@ -22,21 +23,43 @@
import org.rubypeople.rdt.internal.ui.RubyPlugin;
public class RubyPartitionScanner implements IPartitionTokenScanner {
+
+ private static class QueuedToken {
+ private IToken token;
+ private int length;
+ private int offset;
+ QueuedToken(IToken token, int offset, int length) {
+ this.token = token;
+ this.length = length;
+ this.offset = offset;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public IToken getToken() {
+ return token;
+ }
+ }
+
private RubyYaccLexer lexer;
private ParserSupport parserSupport;
private RubyParserResult result;
- private boolean lastWasComment;
- private int fSavedLength;
- private IToken fSavedToken;
- private int fSavedOffset;
private String contents;
private LexerSource lexerSource;
private int origOffset;
private int origLength;
private int tokenLength;
- private int oldOffset;
+ private int tokenOffset;
+ private List<QueuedToken> queue = new ArrayList<QueuedToken>();
+
// XXX Also do strings, regex partitions!
public final static String RUBY_MULTI_LINE_COMMENT = IRubyPartitions.RUBY_MULTI_LINE_COMMENT;
public final static String RUBY_SINGLE_LINE_COMMENT = IRubyPartitions.RUBY_SINGLE_LINE_COMMENT;
@@ -57,13 +80,7 @@
public void setPartialRange(IDocument document, int offset, int length,
String contentType, int partitionOffset) {
- lexer.reset();
- lexer.setState(LexState.EXPR_BEG);
- parserSupport.initTopLocalVariables();
- lastWasComment = false;
- fSavedLength = -1;
- fSavedToken = null;
- fSavedOffset = -1;
+ reset();
try {
contents = document.get(offset, length);
lexerSource = new LexerSource("filename", new StringReader(contents));
@@ -76,40 +93,29 @@
origLength = length;
}
+ private void reset() {
+ lexer.reset();
+ lexer.setState(LexState.EXPR_BEG);
+ parserSupport.initTopLocalVariables();
+ queue.clear();
+ }
+
public int getTokenLength() {
- if (lastWasComment) {
- return tokenLength;
- }
- if (fSavedLength != -1) {
- int length = fSavedLength;
- fSavedLength = -1;
- return length;
- }
return tokenLength;
}
public int getTokenOffset() {
- if (lastWasComment) {
- return oldOffset;
- }
- if (fSavedOffset != -1) {
- int offset = fSavedOffset;
- fSavedOffset = -1;
- return offset;
- }
- return oldOffset;
+ return tokenOffset;
}
public IToken nextToken() {
- if (lastWasComment) {
- lastWasComment = false;
+ if (!queue.isEmpty()) {
+ QueuedToken token = queue.remove(0);
+ tokenOffset = token.getOffset();
+ tokenLength = token.getLength();
+ return token.getToken();
}
- if (fSavedToken != null) {
- IToken returnToken = fSavedToken;
- fSavedToken = null;
- return returnToken;
- }
- oldOffset = getOffset();
+ tokenOffset = getOffset();
tokenLength = 0;
IToken returnValue = new Token(null);
boolean isEOF = false;
@@ -117,8 +123,6 @@
isEOF = !lexer.advance();
if (isEOF) {
returnValue = Token.EOF;
- } else {
- returnValue = token(lexer.token());
}
List comments = result.getCommentNodes();
if (comments != null && !comments.isEmpty()) {
@@ -132,21 +136,20 @@
String src = ASTUtil.getSource(contents, comment);
if (src != null && src.startsWith("=begin")) multiline = true;
firstComment = false;
- oldOffset = origOffset + comment.getPosition().getStartOffset(); // correct start offset, since when a line with nothing but spaces on it appears before comment, we get messed up positions
+ tokenOffset = origOffset + comment.getPosition().getStartOffset(); // correct start offset, since when a line with nothing but spaces on it appears before comment, we get messed up positions
}
endOffset = origOffset + comment.getPosition().getEndOffset();
}
- tokenLength = endOffset - oldOffset;
- fSavedToken = returnValue;
- fSavedOffset = oldOffset + tokenLength;
+ tokenLength = endOffset - tokenOffset;
+ int queuedOffset = tokenOffset + tokenLength;
+ int queuedLength = 0;
if (!isEOF) {
- fSavedLength = getOffset() - fSavedOffset;
+ queuedLength = getOffset() - queuedOffset;
} else {
- fSavedOffset--;
- fSavedLength = 0;
+ queuedOffset--;
}
- lastWasComment = true;
- // FIXME What about multiline comments?!
+ // Throw saved token onto queue
+ queue.add(new QueuedToken(returnValue, queuedOffset, queuedLength));
String contentType = RUBY_SINGLE_LINE_COMMENT;
if (multiline) contentType = RUBY_MULTI_LINE_COMMENT;
return new Token(contentType);
@@ -156,19 +159,15 @@
return Token.EOF; // return eof if we hit a problem found at
// end of parsing
else
- tokenLength = getOffset() - oldOffset;
+ tokenLength = getOffset() - tokenOffset;
return new Token(null);
} catch (IOException e) {
RubyPlugin.log(e);
}
if (!isEOF)
- tokenLength = getOffset() - oldOffset;
+ tokenLength = getOffset() - tokenOffset;
return returnValue;
}
-
- private IToken token(int i) {
- return new Token(null);
- }
private int getOffset() {
return lexerSource.getOffset() + origOffset;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-16 15:33:27
|
Revision: 2487
http://svn.sourceforge.net/rubyeclipse/?rev=2487&view=rev
Author: cawilliams
Date: 2007-05-16 08:33:25 -0700 (Wed, 16 May 2007)
Log Message:
-----------
change the partitionscanner to rip off the work I did on rubyTokenScanner. We pass it through the lexer to get the major partitions in the partition scanner now. This also lets us ignore comments in the RubyTokenScanner because it only deals with code (since the partition scanner breaks those into distinct partitions). Add some tests to make sure the partition scanner works.
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyTokenScanner.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java 2007-05-16 15:21:22 UTC (rev 2486)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java 2007-05-16 15:33:25 UTC (rev 2487)
@@ -1,114 +1,181 @@
package org.rubypeople.rdt.internal.ui.text;
-import java.util.ArrayList;
+import java.io.IOException;
+import java.io.StringReader;
import java.util.List;
+import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
import org.eclipse.jface.text.rules.IPartitionTokenScanner;
-import org.eclipse.jface.text.rules.IPredicateRule;
-import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.Token;
+import org.jruby.ast.CommentNode;
+import org.jruby.common.NullWarnings;
+import org.jruby.lexer.yacc.LexState;
+import org.jruby.lexer.yacc.LexerSource;
+import org.jruby.lexer.yacc.RubyYaccLexer;
+import org.jruby.lexer.yacc.SyntaxException;
+import org.jruby.parser.ParserSupport;
+import org.jruby.parser.RubyParserConfiguration;
+import org.jruby.parser.RubyParserResult;
+import org.rubypeople.rdt.internal.core.util.ASTUtil;
+import org.rubypeople.rdt.internal.ui.RubyPlugin;
-public class RubyPartitionScanner extends BufferedRuleBasedScanner implements
- IPartitionTokenScanner {
+public class RubyPartitionScanner implements IPartitionTokenScanner {
- /** The content type of the partition in which to resume scanning. */
- protected String fContentType;
-
- /** The offset of the partition inside which to resume. */
- protected int fPartitionOffset;
-
+ private RubyYaccLexer lexer;
+ private ParserSupport parserSupport;
+ private RubyParserResult result;
+ private boolean lastWasComment;
+ private int fSavedLength;
+ private IToken fSavedToken;
+ private int fSavedOffset;
+ private String contents;
+ private LexerSource lexerSource;
+ private int origOffset;
+ private int origLength;
+ private int tokenLength;
+ private int oldOffset;
+
+ // XXX Also do strings, regex partitions!
public final static String RUBY_MULTI_LINE_COMMENT = IRubyPartitions.RUBY_MULTI_LINE_COMMENT;
+ public final static String RUBY_SINGLE_LINE_COMMENT = IRubyPartitions.RUBY_SINGLE_LINE_COMMENT;
public static final String[] LEGAL_CONTENT_TYPES = {
- RUBY_MULTI_LINE_COMMENT
+ RUBY_MULTI_LINE_COMMENT, RUBY_SINGLE_LINE_COMMENT
};
public RubyPartitionScanner() {
- super();
- initialize();
+ lexer = new RubyYaccLexer();
+ parserSupport = new ParserSupport();
+ parserSupport.setConfiguration(new RubyParserConfiguration());
+ result = new RubyParserResult();
+ parserSupport.setResult(result);
+ lexer.setParserSupport(parserSupport);
+ lexer.setWarnings(new NullWarnings());
}
- protected void initialize() {
- IToken multiLineComment = new Token(RUBY_MULTI_LINE_COMMENT);
-
- List rules = new ArrayList();
- rules.add(new DocumentationCommentRule(multiLineComment));
- IRule[] result = new IRule[rules.size()];
- rules.toArray(result);
- setRules(result);
+ public void setPartialRange(IDocument document, int offset, int length,
+ String contentType, int partitionOffset) {
+ lexer.reset();
+ lexer.setState(LexState.EXPR_BEG);
+ parserSupport.initTopLocalVariables();
+ lastWasComment = false;
+ fSavedLength = -1;
+ fSavedToken = null;
+ fSavedOffset = -1;
+ try {
+ contents = document.get(offset, length);
+ lexerSource = new LexerSource("filename", new StringReader(contents));
+ lexer.setSource(lexerSource);
+ } catch (BadLocationException e) {
+ lexerSource = new LexerSource("filename", new StringReader(""));
+ lexer.setSource(lexerSource);
+ }
+ origOffset = offset;
+ origLength = length;
}
- /*
- * @see ITokenScanner#setRange(IDocument, int, int)
- */
- public void setRange(IDocument document, int offset, int length) {
- setPartialRange(document, offset, length, null, -1);
+ public int getTokenLength() {
+ if (lastWasComment) {
+ return tokenLength;
+ }
+ if (fSavedLength != -1) {
+ int length = fSavedLength;
+ fSavedLength = -1;
+ return length;
+ }
+ return tokenLength;
}
- /*
- * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String,
- * int)
- */
- public void setPartialRange(IDocument document, int offset, int length,
- String contentType, int partitionOffset) {
- fContentType = contentType;
- fPartitionOffset = partitionOffset;
- if (partitionOffset > -1) {
- int delta = offset - partitionOffset;
- if (delta > 0) {
- super.setRange(document, partitionOffset, length + delta);
- fOffset = offset;
- return;
- }
+ public int getTokenOffset() {
+ if (lastWasComment) {
+ return oldOffset;
}
- super.setRange(document, offset, length);
+ if (fSavedOffset != -1) {
+ int offset = fSavedOffset;
+ fSavedOffset = -1;
+ return offset;
+ }
+ return oldOffset;
}
- /*
- * @see ITokenScanner#nextToken()
- */
public IToken nextToken() {
-
- if (fContentType == null || fRules == null) {
- // don't try to resume
- return super.nextToken();
+ if (lastWasComment) {
+ lastWasComment = false;
}
-
- // inside a partition
-
- fColumn = UNDEFINED;
- boolean resume = (fPartitionOffset > -1 && fPartitionOffset < fOffset);
- fTokenOffset = resume ? fPartitionOffset : fOffset;
-
- IRule rule;
- IToken token;
-
- for (int i = 0; i < fRules.length; i++) {
- rule = (IRule) fRules[i];
- if (rule instanceof IPredicateRule) {
- IPredicateRule predRule = (IPredicateRule) rule;
- token = predRule.getSuccessToken();
- if (fContentType.equals(token.getData())) {
- token = predRule.evaluate(this, resume);
- if (!token.isUndefined()) {
- fContentType = null;
- return token;
+ if (fSavedToken != null) {
+ IToken returnToken = fSavedToken;
+ fSavedToken = null;
+ return returnToken;
+ }
+ oldOffset = getOffset();
+ tokenLength = 0;
+ IToken returnValue = new Token(null);
+ boolean isEOF = false;
+ try {
+ isEOF = !lexer.advance();
+ if (isEOF) {
+ returnValue = Token.EOF;
+ } else {
+ returnValue = token(lexer.token());
+ }
+ List comments = result.getCommentNodes();
+ if (comments != null && !comments.isEmpty()) {
+ CommentNode comment;
+ boolean firstComment = true;
+ int endOffset = 0;
+ boolean multiline = false;
+ while (!comments.isEmpty()) {
+ comment = (CommentNode) comments.remove(0);
+ if (firstComment) {
+ String src = ASTUtil.getSource(contents, comment);
+ if (src != null && src.startsWith("=begin")) multiline = true;
+ firstComment = false;
+ oldOffset = origOffset + comment.getPosition().getStartOffset(); // correct start offset, since when a line with nothing but spaces on it appears before comment, we get messed up positions
}
+ endOffset = origOffset + comment.getPosition().getEndOffset();
}
- } else {
- token= rule.evaluate(this);
- if (!token.isUndefined())
- return token;
+ tokenLength = endOffset - oldOffset;
+ fSavedToken = returnValue;
+ fSavedOffset = oldOffset + tokenLength;
+ if (!isEOF) {
+ fSavedLength = getOffset() - fSavedOffset;
+ } else {
+ fSavedOffset--;
+ fSavedLength = 0;
+ }
+ lastWasComment = true;
+ // FIXME What about multiline comments?!
+ String contentType = RUBY_SINGLE_LINE_COMMENT;
+ if (multiline) contentType = RUBY_MULTI_LINE_COMMENT;
+ return new Token(contentType);
}
+ } catch (SyntaxException se) {
+ if (lexerSource.getOffset() - origLength == 0)
+ return Token.EOF; // return eof if we hit a problem found at
+ // end of parsing
+ else
+ tokenLength = getOffset() - oldOffset;
+ return new Token(null);
+ } catch (IOException e) {
+ RubyPlugin.log(e);
}
+ if (!isEOF)
+ tokenLength = getOffset() - oldOffset;
+ return returnValue;
+ }
+
+ private IToken token(int i) {
+ return new Token(null);
+ }
- // haven't found any rule for this type of partition
- fContentType = null;
- if (resume)
- fOffset = fPartitionOffset;
- return super.nextToken();
+ private int getOffset() {
+ return lexerSource.getOffset() + origOffset;
}
-}
\ No newline at end of file
+
+ public void setRange(IDocument document, int offset, int length) {
+ setPartialRange(document, offset, length, null, 0);
+ }
+
+}
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyTokenScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyTokenScanner.java 2007-05-16 15:21:22 UTC (rev 2486)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyTokenScanner.java 2007-05-16 15:33:25 UTC (rev 2487)
@@ -2,14 +2,12 @@
import java.io.IOException;
import java.io.StringReader;
-import java.util.List;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.Token;
-import org.jruby.ast.CommentNode;
import org.jruby.common.NullWarnings;
import org.jruby.lexer.yacc.LexState;
import org.jruby.lexer.yacc.LexerSource;
@@ -51,17 +49,12 @@
private boolean isInRegexp;
private boolean isInString;
private boolean isInSymbol;
+ private boolean inAlias;
private RubyParserResult result;
private int origOffset;
private int origLength;
- private String contents;
+ private String contents;
- private IToken fSavedToken = null;
- private int fSavedLength = -1;
- private int fSavedOffset = -1;
- private boolean lastWasComment;
- private boolean inAlias;
-
public RubyTokenScanner(IColorManager manager, IPreferenceStore store) {
super(manager, store);
lexer = new RubyYaccLexer();
@@ -75,38 +68,14 @@
}
public int getTokenLength() {
- if (lastWasComment) {
- return tokenLength;
- }
- if (fSavedLength != -1) {
- int length = fSavedLength;
- fSavedLength = -1;
- return length;
- }
return tokenLength;
}
public int getTokenOffset() {
- if (lastWasComment) {
- return oldOffset;
- }
- if (fSavedOffset != -1) {
- int offset = fSavedOffset;
- fSavedOffset = -1;
- return offset;
- }
return oldOffset;
}
public IToken nextToken() {
- if (lastWasComment) {
- lastWasComment = false;
- }
- if (fSavedToken != null) {
- IToken returnToken = fSavedToken;
- fSavedToken = null;
- return returnToken;
- }
oldOffset = getOffset();
tokenLength = 0;
IToken returnValue = getToken(IRubyColorConstants.RUBY_DEFAULT);
@@ -118,31 +87,6 @@
} else {
returnValue = token(lexer.token());
}
- List comments = result.getCommentNodes();
- if (comments != null && !comments.isEmpty()) {
- CommentNode comment;
- boolean firstComment = true;
- int endOffset = 0;
- while (!comments.isEmpty()) {
- comment = (CommentNode) comments.remove(0);
- if (firstComment) {
- firstComment = false;
- oldOffset = origOffset + comment.getPosition().getStartOffset(); // correct start offset, since when a line with nothing but spaces on it appears before comment, we get messed up positions
- }
- endOffset = origOffset + comment.getPosition().getEndOffset();
- }
- tokenLength = endOffset - oldOffset;
- fSavedToken = returnValue;
- fSavedOffset = oldOffset + tokenLength;
- if (!isEOF) {
- fSavedLength = getOffset() - fSavedOffset;
- } else {
- fSavedOffset--;
- fSavedLength = 0;
- }
- lastWasComment = true;
- return getToken(IRubyColorConstants.RUBY_SINGLE_LINE_COMMENT);
- }
} catch (SyntaxException se) {
if (lexerSource.getOffset() - origLength == 0)
return Token.EOF; // return eof if we hit a problem found at
@@ -283,10 +227,6 @@
lexer.reset();
lexer.setState(LexState.EXPR_BEG);
parserSupport.initTopLocalVariables();
- lastWasComment = false;
- fSavedLength = -1;
- fSavedToken = null;
- fSavedOffset = -1;
isInSymbol = false;
if (offset == 0) {
isInRegexp = false;
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java 2007-05-16 15:21:22 UTC (rev 2486)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java 2007-05-16 15:33:25 UTC (rev 2487)
@@ -29,10 +29,8 @@
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
-import org.eclipse.ui.texteditor.ChainedPreferenceStore;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.rubypeople.rdt.core.IRubyElement;
@@ -47,7 +45,6 @@
import org.rubypeople.rdt.internal.ui.text.HTMLTextPresenter;
import org.rubypeople.rdt.internal.ui.text.IRubyColorConstants;
import org.rubypeople.rdt.internal.ui.text.IRubyPartitions;
-import org.rubypeople.rdt.internal.ui.text.PreferencesAdapter;
import org.rubypeople.rdt.internal.ui.text.RubyAnnotationHover;
import org.rubypeople.rdt.internal.ui.text.RubyCommentScanner;
import org.rubypeople.rdt.internal.ui.text.RubyDoubleClickSelector;
@@ -88,7 +85,7 @@
protected AbstractRubyTokenScanner fCodeScanner;
- protected AbstractRubyScanner fMultilineCommentScanner;
+ protected AbstractRubyScanner fMultilineCommentScanner, fSinglelineCommentScanner;
private RubyDoubleClickSelector fRubyDoubleClickSelector;
private RubyCompletionProcessor fRubyCp;
@@ -166,7 +163,7 @@
* @since 0.8.0
*/
public boolean affectsTextPresentation(PropertyChangeEvent event) {
- return fCodeScanner.affectsBehavior(event) || fMultilineCommentScanner.affectsBehavior(event);
+ return fCodeScanner.affectsBehavior(event) || fMultilineCommentScanner.affectsBehavior(event) || fSinglelineCommentScanner.affectsBehavior(event);
}
/**
@@ -189,27 +186,11 @@
fCodeScanner.adaptToPreferenceChange(event);
if (fMultilineCommentScanner.affectsBehavior(event))
fMultilineCommentScanner.adaptToPreferenceChange(event);
+ if (fSinglelineCommentScanner.affectsBehavior(event))
+ fSinglelineCommentScanner.adaptToPreferenceChange(event);
}
/**
- * Creates and returns a preference store which combines the preference
- * stores from the text tools and which is read-only.
- *
- * @param rubyTextTools
- * the Ruby text tools
- * @return the combined read-only preference store
- * @since 0.8.0
- */
- private static final IPreferenceStore createPreferenceStore(RubyTextTools rubyTextTools) {
- Assert.isNotNull(rubyTextTools);
- IPreferenceStore generalTextStore = EditorsUI.getPreferenceStore();
- if (rubyTextTools.getCorePreferenceStore() == null)
- return new ChainedPreferenceStore(new IPreferenceStore[] { rubyTextTools.getPreferenceStore(), generalTextStore });
-
- return new ChainedPreferenceStore(new IPreferenceStore[] { rubyTextTools.getPreferenceStore(), new PreferencesAdapter(rubyTextTools.getCorePreferenceStore()), generalTextStore });
- }
-
- /**
* Initializes the scanners.
*
* @since 3.0
@@ -218,6 +199,7 @@
Assert.isTrue(isNewSetup());
fCodeScanner = new RubyTokenScanner(getColorManager(), fPreferenceStore);
fMultilineCommentScanner = new RubyCommentScanner(getColorManager(), fPreferenceStore, IRubyColorConstants.RUBY_MULTI_LINE_COMMENT);
+ fSinglelineCommentScanner = new RubyCommentScanner(getColorManager(), fPreferenceStore, IRubyColorConstants.RUBY_SINGLE_LINE_COMMENT);
}
/**
@@ -250,6 +232,10 @@
dr = new DefaultDamagerRepairer(getMultilineCommentScanner());
reconciler.setDamager(dr, RubyPartitionScanner.RUBY_MULTI_LINE_COMMENT);
reconciler.setRepairer(dr, RubyPartitionScanner.RUBY_MULTI_LINE_COMMENT);
+
+ dr = new DefaultDamagerRepairer(getSinglelineCommentScanner());
+ reconciler.setDamager(dr, RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT);
+ reconciler.setRepairer(dr, RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT);
return reconciler;
}
@@ -260,9 +246,13 @@
protected ITokenScanner getMultilineCommentScanner() {
return fMultilineCommentScanner;
}
+
+ protected ITokenScanner getSinglelineCommentScanner() {
+ return fSinglelineCommentScanner;
+ }
public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
- return new String[] { IDocument.DEFAULT_CONTENT_TYPE, RubyPartitionScanner.RUBY_MULTI_LINE_COMMENT };
+ return new String[] { IDocument.DEFAULT_CONTENT_TYPE, RubyPartitionScanner.RUBY_MULTI_LINE_COMMENT, RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT };
}
/*
Modified: trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java 2007-05-16 15:21:22 UTC (rev 2486)
+++ trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java 2007-05-16 15:33:25 UTC (rev 2487)
@@ -29,6 +29,14 @@
assert(true);
}
+ public void testPartitioningOfSingleLineComment() {
+ String source = "# This is a comment\n";
+
+ assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 0));
+ assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 1));
+ assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 18));
+ }
+
public void testRecognizeSpecialCase() {
String source = "a,b=?#,'This is not a comment!'\n";
@@ -48,7 +56,7 @@
"=end";
assertEquals(RubyPartitionScanner.RUBY_MULTI_LINE_COMMENT, this.getContentType(source, 0));
assertEquals(RubyPartitionScanner.RUBY_MULTI_LINE_COMMENT, this.getContentType(source, source.length() / 2));
- assertEquals(RubyPartitionScanner.RUBY_MULTI_LINE_COMMENT, this.getContentType(source, source.length() - 1));
+ assertEquals(RubyPartitionScanner.RUBY_MULTI_LINE_COMMENT, this.getContentType(source, source.length() - 2));
}
public void testMultilineCommentNotOnFirstColumn() {
@@ -60,4 +68,31 @@
assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 10));
}
+ public void testRecognizeDivision() {
+ String source = "1/3 #This is a comment\n";
+
+ assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 0));
+ assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 3));
+ assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 5));
+ }
+
+ public void testRecognizeOddballCharacters() {
+ String source = "?\" #comment\n";
+
+ assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 0));
+ assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 2));
+ assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 5));
+
+ source = "?' #comment\n";
+
+ assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 0));
+ assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 2));
+ assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 5));
+
+ source = "?/ #comment\n";
+
+ assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 0));
+ assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 2));
+ assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 5));
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-16 15:21:25
|
Revision: 2486
http://svn.sourceforge.net/rubyeclipse/?rev=2486&view=rev
Author: cawilliams
Date: 2007-05-16 08:21:22 -0700 (Wed, 16 May 2007)
Log Message:
-----------
move dependency on jruby above dependency on rdt.core
Modified Paths:
--------------
trunk/org.rubypeople.rdt.refactoring.tests/META-INF/MANIFEST.MF
Modified: trunk/org.rubypeople.rdt.refactoring.tests/META-INF/MANIFEST.MF
===================================================================
--- trunk/org.rubypeople.rdt.refactoring.tests/META-INF/MANIFEST.MF 2007-05-16 00:48:52 UTC (rev 2485)
+++ trunk/org.rubypeople.rdt.refactoring.tests/META-INF/MANIFEST.MF 2007-05-16 15:21:22 UTC (rev 2486)
@@ -12,7 +12,7 @@
org.rubypeople.rdt.refactoring,
org.eclipse.core.resources,
org.eclipse.text,
- org.rubypeople.rdt.core,
- org.jruby
+ org.jruby,
+ org.rubypeople.rdt.core
Eclipse-LazyStart: true
Bundle-ClassPath: refactoringtests.jar
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-16 00:48:54
|
Revision: 2485
http://svn.sourceforge.net/rubyeclipse/?rev=2485&view=rev
Author: cawilliams
Date: 2007-05-15 17:48:52 -0700 (Tue, 15 May 2007)
Log Message:
-----------
ignore syntax exceptions
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/hyperlinks/RubyHyperLinkDetector.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/hyperlinks/RubyHyperLinkDetector.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/hyperlinks/RubyHyperLinkDetector.java 2007-05-16 00:24:04 UTC (rev 2484)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/hyperlinks/RubyHyperLinkDetector.java 2007-05-16 00:48:52 UTC (rev 2485)
@@ -16,6 +16,7 @@
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.ui.IEditorInput;
import org.jruby.ast.Node;
+import org.jruby.lexer.yacc.SyntaxException;
import org.rubypeople.rdt.core.IRubyScript;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.internal.codeassist.SelectionEngine;
@@ -99,6 +100,8 @@
return new IHyperlink[] { link };
}
}
+ } catch (SyntaxException se) {
+ // ignore
} catch (RubyModelException e) {
//ignore
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-16 00:24:06
|
Revision: 2484
http://svn.sourceforge.net/rubyeclipse/?rev=2484&view=rev
Author: cawilliams
Date: 2007-05-15 17:24:04 -0700 (Tue, 15 May 2007)
Log Message:
-----------
change to hit the zlib compressed url for the list of remote gems. Speeds up downloading of remote gems by an order of magnitude (i.e. 6 seconds compared to 50 seconds)
Modified Paths:
--------------
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java 2007-05-15 20:25:39 UTC (rev 2483)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java 2007-05-16 00:24:04 UTC (rev 2484)
@@ -7,7 +7,6 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
@@ -22,6 +21,8 @@
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.zip.DataFormatException;
+import java.util.zip.Inflater;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
@@ -72,7 +73,7 @@
private static final String REMOTE_GEMS_CACHE_FILE = "remote_gems.xml";
private static final String LOCAL_GEMS_CACHE_FILE = "local_gems.xml";
- private static final String GEM_INDEX_URL = "http://gems.rubyforge.org/yaml";
+ private static final String GEM_INDEX_URL = "http://gems.rubyforge.org/yaml.Z";
private static GemManager fgInstance;
@@ -109,8 +110,10 @@
gems = loadLocalGems();
storeGemCache(gems, getConfigFile(LOCAL_GEMS_CACHE_FILE));
}
- for (GemListener listener : listeners) {
- listener.gemsRefreshed();
+ synchronized (listeners) {
+ for (GemListener listener : listeners) {
+ listener.gemsRefreshed();
+ }
}
return Status.OK_STATUS;
}
@@ -195,7 +198,13 @@
private Set<Gem> loadRemoteGems() {
try {
- List<String> lines = getContents();
+ List<String> lines = new ArrayList<String>();
+ try {
+ lines = getContents();
+ } catch (DataFormatException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
return convertToGems(lines);
} catch (MalformedURLException e) {
AptanaRDTPlugin.log(e);
@@ -249,18 +258,42 @@
return gems;
}
- private List<String> getContents() throws MalformedURLException, IOException {
+ private List<String> getContents() throws MalformedURLException, IOException, DataFormatException {
+ // XXX Make sure this algorithm is returning same number of gems!!!!!
List<String> lines = new ArrayList<String>();
URL url = new URL(GEM_INDEX_URL);
URLConnection con = url.openConnection();
InputStream content = (InputStream) con.getContent();
- BufferedReader reader = new BufferedReader(new InputStreamReader(
- content));
- String line = null;
- while ((line = reader.readLine()) != null) {
- lines.add(line);
- }
- return lines;
+ byte[] input = new byte[1024];
+ int index = 0;
+ while (true) {
+ int bytesToRead = content.available();
+ byte[] tmp = new byte[bytesToRead];
+ int length = content.read(tmp);
+ if (length == -1) break;
+ while ((index + length) > input.length) { // if we'll overflow the array, we need to expand it
+ byte[] newInput = new byte[input.length * 2];
+ System.arraycopy(input, 0, newInput, 0, input.length);
+ input = newInput;
+ }
+ System.arraycopy(tmp, 0, input, index, length);
+ index += length;
+ }
+
+// Decompress the bytes
+ Inflater decompresser = new Inflater();
+ decompresser.setInput(input);
+ byte[] result = new byte[input.length * 20]; // XXX This is a hack. I have no idea what the length should be here
+ int resultLength = decompresser.inflate(result);
+ decompresser.end();
+
+ // Decode the bytes into a String
+ String outputString = new String(result, 0, resultLength);
+ String[] lineArray = outputString.split("\n");
+ for (int i = 0; i < lineArray.length; i++) {
+ lines.add(lineArray[i]);
+ }
+ return lines;
}
private Set<Gem> loadLocalGems() {
@@ -542,7 +575,7 @@
return false;
}
- public void addGemListener(GemListener listener) {
+ public synchronized void addGemListener(GemListener listener) {
listeners.add(listener);
}
@@ -576,7 +609,7 @@
return false;
}
- public void removeGemListener(GemListener listener) {
+ public synchronized void removeGemListener(GemListener listener) {
listeners.remove(listener);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-15 20:25:41
|
Revision: 2483
http://svn.sourceforge.net/rubyeclipse/?rev=2483&view=rev
Author: cawilliams
Date: 2007-05-15 13:25:39 -0700 (Tue, 15 May 2007)
Log Message:
-----------
do some refactorings to pave way for us to use the zlib compressed listing of remote gems (to hopefully speed up grabbing remote gem list)
Modified Paths:
--------------
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java 2007-05-15 20:11:08 UTC (rev 2482)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java 2007-05-15 20:25:39 UTC (rev 2483)
@@ -193,65 +193,76 @@
}
private Set<Gem> loadRemoteGems() {
- Set<Gem> gems = new HashSet<Gem>();
+
try {
- URL url = new URL(GEM_INDEX_URL);
- URLConnection con = url.openConnection();
- InputStream content = (InputStream) con.getContent();
- BufferedReader reader = new BufferedReader(new InputStreamReader(
- content));
- String line = null;
- String name = null;
- String version = null;
- String description = null;
- String platform = null;
- boolean nextIsRealVersion = false;
- while ((line = reader.readLine()) != null) {
- if (nextIsRealVersion && line.trim().startsWith("version: ")) {
- version = line.trim().substring(9);
- if (version.charAt(0) == '"')
- version = version.substring(1);
- if (version.charAt(version.length() - 1) == '"')
- version = version.substring(0, version.length() - 1);
- nextIsRealVersion = false;
- } else if (line.trim().equals(
- "version: !ruby/object:Gem::Version")) {
- nextIsRealVersion = true;
- }
- // if (line.trim().endsWith(":
- // !ruby/object:Gem::Specification")) {
- // // new gem
- // }
- if (line.trim().startsWith("name:")) {
- name = line.trim().substring(6);
- }
- if (line.trim().startsWith("platform:")) {
- if (line.trim().length() == 9) {
- platform = Gem.RUBY_PLATFORM;
- } else {
- platform = line.trim().substring(10);
- }
- }
- if (line.trim().startsWith("summary:")) {
- description = line.trim().substring(9);
- }
- if (description != null && name != null && version != null
- && platform != null) {
- gems.add(new Gem(name, version, description, platform));
- description = null;
- version = null;
- name = null;
- platform = null;
- }
- }
+ List<String> lines = getContents();
+ return convertToGems(lines);
} catch (MalformedURLException e) {
AptanaRDTPlugin.log(e);
} catch (IOException e) {
AptanaRDTPlugin.log(e);
}
+ return new HashSet<Gem>();
+ }
+
+ private Set<Gem> convertToGems(List<String> lines) {
+ Set<Gem> gems = new HashSet<Gem>();
+ String name = null;
+ String version = null;
+ String description = null;
+ String platform = null;
+ boolean nextIsRealVersion = false;
+ for (String line : lines) {
+ if (nextIsRealVersion && line.trim().startsWith("version: ")) {
+ version = line.trim().substring(9);
+ if (version.charAt(0) == '"')
+ version = version.substring(1);
+ if (version.charAt(version.length() - 1) == '"')
+ version = version.substring(0, version.length() - 1);
+ nextIsRealVersion = false;
+ } else if (line.trim().equals(
+ "version: !ruby/object:Gem::Version")) {
+ nextIsRealVersion = true;
+ }
+ if (line.trim().startsWith("name:")) {
+ name = line.trim().substring(6);
+ }
+ if (line.trim().startsWith("platform:")) {
+ if (line.trim().length() == 9) {
+ platform = Gem.RUBY_PLATFORM;
+ } else {
+ platform = line.trim().substring(10);
+ }
+ }
+ if (line.trim().startsWith("summary:")) {
+ description = line.trim().substring(9);
+ }
+ if (description != null && name != null && version != null
+ && platform != null) {
+ gems.add(new Gem(name, version, description, platform));
+ description = null;
+ version = null;
+ name = null;
+ platform = null;
+ }
+ }
return gems;
}
+ private List<String> getContents() throws MalformedURLException, IOException {
+ List<String> lines = new ArrayList<String>();
+ URL url = new URL(GEM_INDEX_URL);
+ URLConnection con = url.openConnection();
+ InputStream content = (InputStream) con.getContent();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ content));
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ lines.add(line);
+ }
+ return lines;
+ }
+
private Set<Gem> loadLocalGems() {
List<String> lines = launchAndRead(LIST_COMMAND + " " + LOCAL_SWITCH);
if (lines.size() > 2) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-15 20:11:09
|
Revision: 2482
http://svn.sourceforge.net/rubyeclipse/?rev=2482&view=rev
Author: cawilliams
Date: 2007-05-15 13:11:08 -0700 (Tue, 15 May 2007)
Log Message:
-----------
disable install a gem until the remote gem list has been loaded
Modified Paths:
--------------
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/actions/InstallGemActionDelegate.java
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/actions/InstallGemActionDelegate.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/actions/InstallGemActionDelegate.java 2007-05-15 17:37:49 UTC (rev 2481)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/actions/InstallGemActionDelegate.java 2007-05-15 20:11:08 UTC (rev 2482)
@@ -56,6 +56,7 @@
* org.eclipse.jface.viewers.ISelection)
*/
public void selectionChanged(IAction action, ISelection selection) {
+ action.setEnabled(!GemManager.getInstance().getRemoteGems().isEmpty());
}
/**
@@ -63,5 +64,7 @@
*/
public void init(IViewPart view) {
}
+
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-15 17:37:52
|
Revision: 2481
http://svn.sourceforge.net/rubyeclipse/?rev=2481&view=rev
Author: cawilliams
Date: 2007-05-15 10:37:49 -0700 (Tue, 15 May 2007)
Log Message:
-----------
a first stab at replacing the portions of things that were hooked into the old symbol index
Modified Paths:
--------------
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTab.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestHierarchyTab.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitMessages.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitMessages.properties
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitView.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestunitPlugin.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchConfigurationDelegate.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchShortcut.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenEditorAction.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenTestAction.java
Removed Paths:
-------------
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenLocationAction.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenSymbolAction.java
Modified: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTab.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTab.java 2007-05-15 17:36:41 UTC (rev 2480)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTab.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -37,8 +37,6 @@
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
-import org.rubypeople.rdt.core.RubyCore;
-import org.rubypeople.rdt.internal.core.symbols.ISymbolFinder;
import org.rubypeople.rdt.testunit.ITestRunListener;
/**
@@ -152,7 +150,7 @@
String methodName = getMethodName();
if (className != null) {
System.err.println("MethodName: " + methodName);
- manager.add(OpenSymbolAction.forMethod(className, methodName, getSymbolFinder(), getShell()));
+ manager.add(new OpenTestAction(fRunnerViewPart, className, methodName, true));
manager.add(new Separator());
manager.add(new RerunAction(fRunnerViewPart, getSelectedTestId(),
className, methodName, ILaunchManager.RUN_MODE));
@@ -166,10 +164,6 @@
}
}
- private ISymbolFinder getSymbolFinder() {
- return RubyCore.getPlugin().getSymbolFinder();
- }
-
private TableItem getSelectedItem() {
int index = fTable.getSelectionIndex();
if (index == -1) return null;
@@ -276,7 +270,7 @@
void handleDoubleClick(MouseEvent e) {
if (fTable.getSelectionCount() > 0)
- OpenSymbolAction.forMethod(getClassName(), getMethodName(), getSymbolFinder(), getShell()).run();
+ new OpenTestAction(fRunnerViewPart, getClassName(), getMethodName(), true).run();
}
private Shell getShell() {
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenEditorAction.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenEditorAction.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenEditorAction.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * 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.testunit.ui;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyModel;
+import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.internal.ui.rubyeditor.EditorUtility;
+
+/**
+ * Abstract Action for opening a Ruby editor.
+ */
+public abstract class OpenEditorAction extends Action {
+ protected String fClassName;
+ protected TestUnitView fTestRunner;
+ private final boolean fActivate;
+
+ protected OpenEditorAction(TestUnitView testRunner, String testClassName) {
+ this(testRunner, testClassName, true);
+ }
+
+ public OpenEditorAction(TestUnitView testRunner, String className, boolean activate) {
+ super(TestUnitMessages.OpenEditorAction_action_label);
+ fClassName= className;
+ fTestRunner= testRunner;
+ fActivate= activate;
+ }
+
+ /*
+ * @see IAction#run()
+ */
+ public void run() {
+ ITextEditor textEditor= null;
+ try {
+ IRubyElement element= findElement(getLaunchedProject(), fClassName);
+ if (element == null) {
+ MessageDialog.openError(getShell(),
+ TestUnitMessages.OpenEditorAction_error_cannotopen_title, TestUnitMessages.OpenEditorAction_error_cannotopen_message);
+ return;
+ }
+ textEditor= (ITextEditor)EditorUtility.openInEditor(element, fActivate);
+ } catch (CoreException e) {
+ ErrorDialog.openError(getShell(), TestUnitMessages.OpenEditorAction_error_dialog_title, TestUnitMessages.OpenEditorAction_error_dialog_message, e.getStatus());
+ return;
+ }
+ if (textEditor == null) {
+ fTestRunner.setInfoMessage(TestUnitMessages.OpenEditorAction_message_cannotopen);
+ return;
+ }
+ reveal(textEditor);
+ }
+
+ protected Shell getShell() {
+ return fTestRunner.getSite().getShell();
+ }
+
+ protected IRubyProject getLaunchedProject() {
+ return fTestRunner.getLaunchedProject();
+ }
+
+ protected String getClassName() {
+ return fClassName;
+ }
+
+ protected abstract IRubyElement findElement(IRubyProject project, String className) throws CoreException;
+
+ protected abstract void reveal(ITextEditor editor);
+
+ protected IType findType(IRubyProject project, String className) throws RubyModelException {
+ return internalFindType(project, className, new HashSet());
+ }
+
+ private IType internalFindType(IRubyProject project, String className, Set/*<IRubyProject>*/ visitedProjects) throws RubyModelException {
+ if (visitedProjects.contains(project))
+ return null;
+
+ IType type= project.findType(className, (IProgressMonitor) null);
+ if (type != null)
+ return type;
+
+ //fix for bug 87492: visit required projects explicitly to also find not exported types
+ visitedProjects.add(project);
+ IRubyModel javaModel= project.getRubyModel();
+ String[] requiredProjectNames= project.getRequiredProjectNames();
+ for (int i= 0; i < requiredProjectNames.length; i++) {
+ IRubyProject requiredProject= javaModel.getRubyProject(requiredProjectNames[i]);
+ if (requiredProject.exists()) {
+ type= internalFindType(requiredProject, className, visitedProjects);
+ if (type != null)
+ return type;
+ }
+ }
+ return null;
+ }
+
+}
Deleted: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenLocationAction.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenLocationAction.java 2007-05-15 17:36:41 UTC (rev 2480)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenLocationAction.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -1,23 +0,0 @@
-package org.rubypeople.rdt.internal.testunit.ui;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.rubypeople.rdt.internal.core.symbols.Location;
-import org.rubypeople.rdt.internal.ui.util.PositionBasedEditorOpener;
-
-
-public class OpenLocationAction extends Action implements IAction {
-
- private final Location location;
-
- public OpenLocationAction(Location location) {
- super(location.getFilename());
- this.location = location;
- }
-
- public void run() {
- new PositionBasedEditorOpener(location.getFilename(), location.getPosition()).open();
- }
-
-
-}
Deleted: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenSymbolAction.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenSymbolAction.java 2007-05-15 17:36:41 UTC (rev 2480)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenSymbolAction.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -1,99 +0,0 @@
-package org.rubypeople.rdt.internal.testunit.ui;
-
-import java.util.Set;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Shell;
-import org.rubypeople.rdt.internal.core.symbols.ClassSymbol;
-import org.rubypeople.rdt.internal.core.symbols.ISymbolFinder;
-import org.rubypeople.rdt.internal.core.symbols.Location;
-import org.rubypeople.rdt.internal.core.symbols.MethodSymbol;
-import org.rubypeople.rdt.internal.core.symbols.Symbol;
-import org.rubypeople.rdt.internal.ui.RubyPluginImages;
-import org.rubypeople.rdt.internal.ui.dialogs.ElementListSelectionDialog;
-import org.rubypeople.rdt.internal.ui.util.PositionBasedEditorOpener;
-
-public class OpenSymbolAction extends Action implements IAction {
-
- private final Symbol symbol;
- private final ISymbolFinder finder;
- private final Shell shell;
- private String dialogTitle;
-
- public static IAction forClass(String className, ISymbolFinder finder, Shell shell) {
- return new OpenSymbolAction(new ClassSymbol(className), finder, shell, "Open Class");
- }
-
- public static IAction forMethod(String className, String testMethod,
- ISymbolFinder finder, Shell shell) {
- return new OpenSymbolAction(new MethodSymbol(className, testMethod), finder, shell, "Open Method");
- }
-
- public OpenSymbolAction(Symbol symbol, ISymbolFinder finder, Shell shell, String title) {
- super(TestUnitMessages.OpenEditor_action_label);
- this.shell = shell;
- this.symbol = symbol;
- this.finder = finder;
- this.dialogTitle = title;
- }
-
-
- public void run() {
- Set locations = finder.find(symbol);
- if (locations.size() == 0)
- return;
-
- Location location;
- if (locations.size() == 1) {
- location = (Location) locations.iterator().next();
- } else {
- ElementListSelectionDialog selectionDialog
- = new ElementListSelectionDialog(shell, new LocationLabel());
- selectionDialog.setElements(locations.toArray());
- selectionDialog.setMessage("Select a location");
- selectionDialog.setTitle(dialogTitle);
- selectionDialog.open();
- if (selectionDialog.getReturnCode() == SWT.CANCEL)
- return;
- location= (Location) selectionDialog.getResult()[0];
- }
- PositionBasedEditorOpener editorOpener
- = new PositionBasedEditorOpener(location.getFilename(),
- location.getPosition());
- editorOpener.open();
- }
-
-
- private final class LocationLabel implements ILabelProvider {
- public Image getImage(Object element) {
- return RubyPluginImages.get(RubyPluginImages.IMG_CTOOLS_RUBY_PAGE);
- }
-
- public String getText(Object element) {
- Location location = (Location) element;
- IFile sourceFile = location.getSourceFile();
- return sourceFile.getName() + ":" + location.getPosition().getStartLine() + " - " + sourceFile.getFullPath().removeLastSegments(1);
- }
-
- public void addListener(ILabelProviderListener listener) {
- }
-
- public void dispose() {
- }
-
- public boolean isLabelProperty(Object element, String property) {
- return false;
- }
-
- public void removeListener(ILabelProviderListener listener) {
- }
- }
-
-
-}
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenTestAction.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenTestAction.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenTestAction.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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.testunit.ui;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.rubypeople.rdt.core.IMethod;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.core.ISourceRange;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyConventions;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.internal.core.util.Messages;
+
+/**
+ * Open a class on a Test method.
+ */
+public class OpenTestAction extends OpenEditorAction {
+
+ private String fMethodName;
+ private ISourceRange fRange;
+
+ public OpenTestAction(TestUnitView testRunner, String className, String method) {
+ this(testRunner, className, method, true);
+ }
+
+ public OpenTestAction(TestUnitView testRunner, String className) {
+ this(testRunner, className, null);
+ }
+
+ public OpenTestAction(TestUnitView testRunner, String className, String method, boolean activate) {
+ super(testRunner, className, activate);
+// PlatformUI.getWorkbench().getHelpSystem().setHelp(this, ITestUnitHelpContextIds.OPENTEST_ACTION);
+ fMethodName= method;
+ }
+
+ protected IRubyElement findElement(IRubyProject project, String className) throws RubyModelException {
+ IType type= findType(project, className);
+ if (type == null)
+ return null;
+
+ if (fMethodName == null)
+ return type;
+
+ IMethod method= findMethod(type);
+// if (method == null) { FIXME When we have type hierarchies implemented, uncomment this!
+// ITypeHierarchy typeHierarchy= type.newSupertypeHierarchy(null);
+// IType[] types= typeHierarchy.getAllSuperclasses(type);
+// for (int i= 0; i < types.length; i++) {
+// method= findMethod(types[i]);
+// if (method != null)
+// break;
+// }
+// }
+ if (method == null) {
+ String title= TestUnitMessages.OpenTestAction_error_title;
+ String message= Messages.format(TestUnitMessages.OpenTestAction_error_methodNoFound, fMethodName);
+ MessageDialog.openInformation(getShell(), title, message);
+ return type;
+ }
+ fRange= method.getNameRange();
+ return method;
+ }
+
+ IMethod findMethod(IType type) {
+ IStatus status= RubyConventions.validateMethodName(fMethodName);
+ if (! status.isOK())
+ return null;
+ IMethod method= type.getMethod(fMethodName, new String[0]);
+ if (method != null && method.exists())
+ return method;
+ return null;
+ }
+
+ protected void reveal(ITextEditor textEditor) {
+ if (fRange != null)
+ textEditor.selectAndReveal(fRange.getOffset(), fRange.getLength());
+ }
+
+ public boolean isEnabled() {
+ try {
+ return findType(getLaunchedProject(), getClassName()) != null;
+ } catch (RubyModelException e) {
+ }
+ return false;
+ }
+}
Modified: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestHierarchyTab.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestHierarchyTab.java 2007-05-15 17:36:41 UTC (rev 2480)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestHierarchyTab.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -41,12 +41,8 @@
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
-import org.rubypeople.rdt.core.RubyCore;
-import org.rubypeople.rdt.internal.core.symbols.ClassSymbol;
-import org.rubypeople.rdt.internal.core.symbols.ISymbolFinder;
import org.rubypeople.rdt.testunit.ITestRunListener;
/*
@@ -412,13 +408,11 @@
return;
IAction action = null;
-
- Shell shell = fTree.getShell();
- ISymbolFinder finder = RubyCore.getPlugin().getSymbolFinder();
+
if (isSuiteSelected())
- action= OpenSymbolAction.forClass(getClassName(), finder, shell);
+ action= new OpenTestAction(fTestRunnerPart, getClassName());
else
- action= OpenSymbolAction.forMethod(getClassName(), getTestMethod(), finder, shell);
+ action= new OpenTestAction(fTestRunnerPart, getClassName(), getTestMethod());
if (action != null && action.isEnabled())
action.run();
@@ -426,18 +420,15 @@
public void menuAboutToShow(IMenuManager manager) {
if (fTree.getSelectionCount() > 0) {
- Shell shell = fTree.getShell();
- ISymbolFinder symbolFinder = RubyCore.getPlugin().getSymbolFinder();
if (isSuiteSelected()) {
- manager.add(OpenSymbolAction.forClass(getClassName(), symbolFinder, shell));
+ manager.add(new OpenTestAction(fTestRunnerPart, getClassName()));
manager.add(new Separator());
if (testClassExists(getClassName()) && !fTestRunnerPart.lastLaunchIsKeptAlive()) {
manager.add(new RerunAction(fTestRunnerPart, getSelectedTestId(), getClassName(), null, ILaunchManager.RUN_MODE));
manager.add(new RerunAction(fTestRunnerPart, getSelectedTestId(), getClassName(), null, ILaunchManager.DEBUG_MODE));
}
} else {
- manager.add(OpenSymbolAction.forMethod(getClassName(),
- getTestMethod(), symbolFinder, shell));
+ manager.add(new OpenTestAction(fTestRunnerPart, getClassName(), getTestMethod(), true));
manager.add(new Separator());
manager.add(new RerunAction(fTestRunnerPart, getSelectedTestId(), getClassName(), getTestMethod(), ILaunchManager.RUN_MODE));
manager.add(new RerunAction(fTestRunnerPart, getSelectedTestId(), getClassName(), getTestMethod(), ILaunchManager.DEBUG_MODE));
@@ -448,7 +439,7 @@
}
private boolean testClassExists(String className) {
- return RubyCore.getPlugin().getSymbolFinder().find(new ClassSymbol(className)).size() > 0;
+ return true; // FIXME We need to re-implement this!
}
public void newTreeEntry(String treeEntry) {
Modified: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitMessages.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitMessages.java 2007-05-15 17:36:41 UTC (rev 2480)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitMessages.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -71,6 +71,15 @@
public static String TestRunnerViewPart_toggle_vertical_label;
public static String TestRunnerViewPart_toggle_automatic_label;
public static String TestRunnerViewPart_layout_menu;
+ public static String OpenEditorAction_error_cannotopen_title;
+ public static String OpenEditorAction_error_cannotopen_message;
+ public static String OpenEditorAction_error_dialog_title;
+ public static String OpenEditorAction_error_dialog_message;
+ public static String OpenEditorAction_message_cannotopen;
+ public static String OpenTestAction_error_title;
+ public static String OpenTestAction_error_methodNoFound;
+ public static String TestUnitBaseLaunchConfiguration_error_invalidproject;
+ public static String JUnitBaseLaunchConfiguration_dialog_title;
static {
NLS.initializeMessages(BUNDLE_NAME, TestUnitMessages.class);
Modified: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitMessages.properties
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitMessages.properties 2007-05-15 17:36:41 UTC (rev 2480)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitMessages.properties 2007-05-15 17:37:49 UTC (rev 2481)
@@ -17,7 +17,15 @@
HierarchyRunView_tab_title=Hierarchy
OpenEditorAction_action_label=&Go to File
+OpenEditorAction_error_cannotopen_title=Cannot Open Editor
+OpenEditorAction_error_cannotopen_message=Test class not found in selected project
+OpenEditorAction_error_dialog_title=Error
+OpenEditorAction_error_dialog_message=Cannot open editor
+OpenEditorAction_message_cannotopen=Cannot open editor
+OpenTestAction_error_title=Go To Test
+OpenTestAction_error_methodNoFound=Method ''{0}'' not found. Opening the test class.
+
TestRunnerViewPart_jobName=Update JUnit
TestRunnerViewPart_rerunaction_label=Rerun Last Test
TestRunnerViewPart_rerunaction_tooltip=Rerun Last Test
Modified: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitView.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitView.java 2007-05-15 17:36:41 UTC (rev 2480)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitView.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -63,6 +63,8 @@
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.IRubyProject;
import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.internal.core.RubyModelManager;
+import org.rubypeople.rdt.launching.IRubyLaunchConfigurationConstants;
import org.rubypeople.rdt.testunit.ITestRunListener;
import org.rubypeople.rdt.testunit.launcher.TestUnitLaunchConfigurationDelegate;
@@ -474,6 +476,14 @@
public void startTestRunListening(int port, IType type, ILaunch launch) {
if(type != null) fTestProject= type.getRubyProject();
+ else {
+ try {
+ String projectName = launch.getLaunchConfiguration().getAttribute(IRubyLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null);
+ fTestProject = RubyModelManager.getRubyModelManager().getRubyModel().getRubyProject(projectName);
+ } catch (CoreException e) {
+ TestunitPlugin.log(e);
+ }
+ }
fLaunchMode = launch.getLaunchMode();
aboutToLaunch();
@@ -488,12 +498,11 @@
fTestRunnerClient.startListening(listenerArray, port);
fLastLaunch = launch;
- // TODO Uncomment now that we have the type object!
- // setViewPartTitle(type);
- // if (type instanceof IType)
- // setTitleToolTip(((IType)type).getFullyQualifiedName());
- // else
- // setTitleToolTip(type.getElementName());
+ setViewPartTitle(type);
+ if (type instanceof IType)
+ setTitleToolTip(((IType)type).getFullyQualifiedName());
+// else
+// setTitleToolTip(type.getElementName());
}
protected void aboutToLaunch() {
Modified: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestunitPlugin.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestunitPlugin.java 2007-05-15 17:36:41 UTC (rev 2480)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestunitPlugin.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -246,20 +246,15 @@
if (config != null) {
String typeStr = launch.getAttribute(TestUnitLaunchConfigurationDelegate.TESTTYPE_ATTR);
- // String fileName= launch.getAttribute(TestUnitLaunchConfigurationDelegate.LAUNCH_CONTAINER_ATTR);
if (typeStr != null) {
- // FIXME Get the handle on the test type from the model somehow!
- // IFile script = RubyCore.find(fileName);
- // if (element instanceof IRubyType)
- // launchedType= (IRubyType) element;
+ launchedType = (IType) RubyCore.create(typeStr);
}
-
}
fTrackedLaunches.remove(launch);
final IType finalType= launchedType;
- final int finalPort = Integer.parseInt(launch.getAttribute(TESTUNIT_PORT_ATTR)) ;
+ final int finalPort = Integer.parseInt(launch.getAttribute(TESTUNIT_PORT_ATTR));
getDisplay().asyncExec(new Runnable() {
public void run() {
connectTestRunner(launch, finalType, finalPort);
Modified: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchConfigurationDelegate.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchConfigurationDelegate.java 2007-05-15 17:36:41 UTC (rev 2480)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchConfigurationDelegate.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -4,11 +4,22 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.core.IRubyScript;
+import org.rubypeople.rdt.core.IType;
import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.core.SocketUtil;
+import org.rubypeople.rdt.internal.testunit.ui.TestUnitMessages;
import org.rubypeople.rdt.internal.testunit.ui.TestunitPlugin;
+import org.rubypeople.rdt.launching.IRubyLaunchConfigurationConstants;
import org.rubypeople.rdt.launching.RubyLaunchDelegate;
public class TestUnitLaunchConfigurationDelegate extends RubyLaunchDelegate {
@@ -30,11 +41,72 @@
private int port = -1;
@Override
- public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
+ public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
+ IType[] testTypes = findTestTypes(configuration, monitor);
+
+// setDefaultSourceLocator(launch, configuration);
launch.setAttribute(TestunitPlugin.TESTUNIT_PORT_ATTR, Integer.toString(getPort()));
+ if (testTypes.length > 0) launch.setAttribute(TESTTYPE_ATTR, testTypes[0].getHandleIdentifier());
+
+
super.launch(configuration, mode, launch, monitor);
}
+ protected IType[] findTestTypes(ILaunchConfiguration configuration, IProgressMonitor pm) throws CoreException {
+ IRubyProject javaProject= getRubyProject(configuration);
+ if ((javaProject == null) || !javaProject.exists()) {
+ informAndAbort(TestUnitMessages.TestUnitBaseLaunchConfiguration_error_invalidproject, null, IRubyLaunchConfigurationConstants.ERR_NOT_A_RUBY_PROJECT);
+ }
+// if (!TestSearchEngine.hasTestCaseType(javaProject)) {
+// informAndAbort(TestUnitMessages.JUnitBaseLaunchConfiguration_error_junitnotonpath, null, ITestUnitStatusConstants.ERR_JUNIT_NOT_ON_PATH);
+// }
+
+ String containerHandle = configuration.getAttribute(LAUNCH_CONTAINER_ATTR, ""); //$NON-NLS-1$
+ if (containerHandle.length() > 0) {
+ IRubyElement element = RubyCore.create(containerHandle);
+ IRubyScript script = (IRubyScript) element;
+ if (script != null) return new IType[] { script.findPrimaryType() };
+ }
+ String testTypeName= configuration.getAttribute(TESTTYPE_ATTR, (String) null);
+ if (testTypeName != null && testTypeName.length() > 0) {
+ return new IType[] {javaProject.findType(testTypeName, pm)};
+ }
+ return new IType[0];
+ }
+
+ protected void informAndAbort(String message, Throwable exception, int code) throws CoreException {
+ IStatus status= new Status(IStatus.INFO, TestunitPlugin.PLUGIN_ID, code, message, exception);
+ if (showStatusMessage(status))
+ throw new CoreException(status);
+ abort(message, exception, code);
+ }
+
+ private boolean showStatusMessage(final IStatus status) {
+ final boolean[] success= new boolean[] { false };
+ getDisplay().syncExec(
+ new Runnable() {
+ public void run() {
+ Shell shell= TestunitPlugin.getActiveWorkbenchShell();
+ if (shell == null)
+ shell= getDisplay().getActiveShell();
+ if (shell != null) {
+ MessageDialog.openInformation(shell, TestUnitMessages.JUnitBaseLaunchConfiguration_dialog_title, status.getMessage());
+ success[0]= true;
+ }
+ }
+ }
+ );
+ return success[0];
+ }
+
+ private Display getDisplay() {
+ Display display;
+ display= Display.getCurrent();
+ if (display == null)
+ display= Display.getDefault();
+ return display;
+ }
+
public static String getTestRunnerPath() {
String directory = RubyCore.getOSDirectory(TestunitPlugin.getDefault());
File pluginDirFile = new File(directory, "ruby");
@@ -55,7 +127,7 @@
@Override
public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException {
StringBuffer buffer = new StringBuffer();
- buffer.append(configuration.getAttribute(TestUnitLaunchConfigurationDelegate.LAUNCH_CONTAINER_ATTR, ""));
+ buffer.append(getLaunchContainerPath(configuration));
buffer.append(' ');
buffer.append(Integer.toString(getPort()));
buffer.append(' ');
@@ -66,4 +138,13 @@
buffer.append(configuration.getAttribute(TestUnitLaunchConfigurationDelegate.TESTNAME_ATTR, ""));
return buffer.toString();
}
+
+ private String getLaunchContainerPath(ILaunchConfiguration configuration) throws CoreException {
+ String container = configuration.getAttribute(TestUnitLaunchConfigurationDelegate.LAUNCH_CONTAINER_ATTR, "");
+ IRubyElement element = (IRubyElement) RubyCore.create(container);
+ if (element != null)
+ return element.getResource().getLocation().toFile().getAbsolutePath();
+ // otherwise it may be an actual path!
+ return container;
+ }
}
\ No newline at end of file
Modified: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchShortcut.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchShortcut.java 2007-05-15 17:36:41 UTC (rev 2480)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/testunit/launcher/TestUnitLaunchShortcut.java 2007-05-15 17:37:49 UTC (rev 2481)
@@ -29,11 +29,9 @@
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.rubypeople.rdt.core.IRubyElement;
-import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.internal.debug.ui.launcher.RubyApplicationShortcut;
import org.rubypeople.rdt.internal.testunit.ui.TestUnitMessages;
import org.rubypeople.rdt.internal.testunit.ui.TestunitPlugin;
-import org.rubypeople.rdt.internal.ui.RubyPlugin;
import org.rubypeople.rdt.launching.IRubyLaunchConfigurationConstants;
import org.rubypeople.rdt.launching.RubyRuntime;
@@ -116,13 +114,15 @@
* @return
*/
private String getContainer(IRubyElement rubyElement) {
- try {
- IFile rubyFile = (IFile) rubyElement.getUnderlyingResource();
- return rubyFile.getProjectRelativePath().toString();
- } catch (RubyModelException e) {
- RubyPlugin.log(e);
- return rubyElement.getElementName();
- }
+ return rubyElement.getHandleIdentifier(); // XXX We always held the absolute file path here before (and RadRails relies on this!) Now what do we do?!
+//
+// try {
+// IFile rubyFile = (IFile) rubyElement.getUnderlyingResource();
+// return rubyFile.getProjectRelativePath().toString();
+// } catch (RubyModelException e) {
+// RubyPlugin.log(e);
+// return rubyElement.getElementName();
+// }
}
protected ILaunchConfiguration createConfiguration(IFile rubyFile, String container, String testName) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-15 17:36:43
|
Revision: 2480
http://svn.sourceforge.net/rubyeclipse/?rev=2480&view=rev
Author: cawilliams
Date: 2007-05-15 10:36:41 -0700 (Tue, 15 May 2007)
Log Message:
-----------
Added Paths:
-----------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/dnd/DelegatingDragAdapter.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/dnd/RdtViewerDragAdapter.java
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/dnd/DelegatingDragAdapter.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/dnd/DelegatingDragAdapter.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/dnd/DelegatingDragAdapter.java 2007-05-15 17:36:41 UTC (rev 2480)
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.dnd;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.swt.dnd.DragSource;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.DragSourceListener;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.dnd.TransferData;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.util.TransferDragSourceListener;
+
+/**
+ * A delegating drag adapter negotiates between a set of <code>TransferDragSourceListener</code>s
+ * On <code>dragStart</code> the adapter determines the listener to be used for any further
+ * <code>drag*</code> callback.
+ */
+public class DelegatingDragAdapter implements DragSourceListener {
+
+ private TransferDragSourceListener[] fPossibleListeners;
+ private List fActiveListeners;
+ private TransferDragSourceListener fFinishListener;
+
+ public DelegatingDragAdapter(TransferDragSourceListener[] listeners) {
+ setPossibleListeners(listeners);
+ }
+
+ protected void setPossibleListeners(TransferDragSourceListener[] listeners) {
+ Assert.isNotNull(listeners);
+ Assert.isTrue(fActiveListeners == null, "Can only set possible listeners before drag operation has started"); //$NON-NLS-1$
+ fPossibleListeners= listeners;
+ }
+
+ /* non Java-doc
+ * @see DragSourceListener
+ */
+ public void dragStart(DragSourceEvent event) {
+ fFinishListener= null;
+ boolean saveDoit= event.doit;
+ Object saveData= event.data;
+ boolean doIt= false;
+ List transfers= new ArrayList(fPossibleListeners.length);
+ fActiveListeners= new ArrayList(fPossibleListeners.length);
+
+ for (int i= 0; i < fPossibleListeners.length; i++) {
+ TransferDragSourceListener listener= fPossibleListeners[i];
+ event.doit= saveDoit;
+ listener.dragStart(event);
+ if (event.doit) {
+ transfers.add(listener.getTransfer());
+ fActiveListeners.add(listener);
+ }
+ doIt= doIt || event.doit;
+ }
+ if (doIt) {
+ ((DragSource)event.widget).setTransfer((Transfer[])transfers.toArray(new Transfer[transfers.size()]));
+ }
+ event.data= saveData;
+ event.doit= doIt;
+ }
+
+ /* non Java-doc
+ * @see DragSourceListener
+ */
+ public void dragSetData(DragSourceEvent event) {
+ fFinishListener= getListener(event.dataType);
+ if (fFinishListener != null)
+ fFinishListener.dragSetData(event);
+ }
+
+ /* non Java-doc
+ * @see DragSourceListener
+ */
+ public void dragFinished(DragSourceEvent event) {
+ try{
+ if (fFinishListener != null) {
+ fFinishListener.dragFinished(event);
+ } else {
+ // If the user presses Escape then we get a dragFinished without
+ // getting a dragSetData before.
+ fFinishListener= getListener(event.dataType);
+ if (fFinishListener != null)
+ fFinishListener.dragFinished(event);
+ }
+ } finally{
+ fFinishListener= null;
+ fActiveListeners= null;
+ }
+ }
+
+ private TransferDragSourceListener getListener(TransferData type) {
+ if (type == null)
+ return null;
+
+ for (Iterator iter= fActiveListeners.iterator(); iter.hasNext();) {
+ TransferDragSourceListener listener= (TransferDragSourceListener)iter.next();
+ if (listener.getTransfer().isSupportedType(type)) {
+ return listener;
+ }
+ }
+ return null;
+ }
+}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/dnd/RdtViewerDragAdapter.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/dnd/RdtViewerDragAdapter.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/dnd/RdtViewerDragAdapter.java 2007-05-15 17:36:41 UTC (rev 2480)
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.dnd;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.util.TransferDragSourceListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.dnd.DragSourceEvent;
+
+public class RdtViewerDragAdapter extends DelegatingDragAdapter {
+
+ private StructuredViewer fViewer;
+
+ public RdtViewerDragAdapter(StructuredViewer viewer, TransferDragSourceListener[] listeners) {
+ super(listeners);
+ Assert.isNotNull(viewer);
+ fViewer= viewer;
+ }
+
+ public void dragStart(DragSourceEvent event) {
+ IStructuredSelection selection= (IStructuredSelection)fViewer.getSelection();
+ if (selection.isEmpty()) {
+ event.doit= false;
+ return;
+ }
+ super.dragStart(event);
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-15 17:36:20
|
Revision: 2479
http://svn.sourceforge.net/rubyeclipse/?rev=2479&view=rev
Author: cawilliams
Date: 2007-05-15 10:36:12 -0700 (Tue, 15 May 2007)
Log Message:
-----------
new Ruby Search UI for our brand spanking-new search engine
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/META-INF/MANIFEST.MF
trunk/org.rubypeople.rdt.ui/plugin.xml
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/corext/util/SearchUtils.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/IRubyHelpContextIds.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPlugin.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPluginImages.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/IRubyConstants.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/RubyUI.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/TS_InternalUi.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/search/TS_InternalUiRubySearch.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/ui/tests/TS_Ui.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.ui/icons/full/dlcl16/prj_mode.gif
trunk/org.rubypeople.rdt.ui/icons/full/dlcl16/type_mode.gif
trunk/org.rubypeople.rdt.ui/icons/full/elcl16/prj_mode.gif
trunk/org.rubypeople.rdt.ui/icons/full/elcl16/type_mode.gif
trunk/org.rubypeople.rdt.ui/icons/full/obj16/rsearch_obj.gif
trunk/org.rubypeople.rdt.ui/icons/full/obj16/search_decl_obj.gif
trunk/org.rubypeople.rdt.ui/icons/full/obj16/search_ref_obj.gif
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/dnd/
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/ColorDecoratingLabelProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FilterAction.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FiltersDialog.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FiltersDialogAction.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupAction.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/IOccurrencesFinder.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/LRUWorkingSetsList.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/LevelTreeContentProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/MatchFilter.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/NewSearchResultCollector.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/NewSearchViewActionGroup.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/PatternStrings.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/PostfixLabelProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubyElementMatch.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchContentProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchEditorOpener.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchPage.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchQuery.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchResult.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchResultPage.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchScopeFactory.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchTableContentProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/SearchLabelProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/SearchMessages.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/SearchMessages.properties
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/SearchParticipantDescriptor.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/SearchParticipantRecord.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/SearchParticipantsExtensionPoint.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/SearchUtil.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/SortAction.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/SortingLabelProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/WorkingSetComparator.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/WorkingSetsComparator.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/viewsupport/IProblemChangedListener.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/viewsupport/ProblemMarkerManager.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/viewsupport/ProblemTableViewer.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/viewsupport/ProblemTreeViewer.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/viewsupport/ResourceToItemsMapper.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/IWorkingCopyProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/ProblemsLabelDecorator.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/actions/NavigateActionGroup.java
Removed Paths:
-------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByAction.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByPathStrategy.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByScopeStrategy.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/IGroupByStrategy.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchLabelProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchPage.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchQuery.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchResult.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchResultPage.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/RubySearchTreeContentProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/Scope.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/symbols/BlockingSymbolFinder.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/search/TC_GroupByScopeStrategy.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/search/TC_RubySearchTreeContentProvider.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/search/TC_Scope.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/symbols/TC_BlockingSymbolFinder.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/symbols/TS_UiSymbols.java
Modified: trunk/org.rubypeople.rdt.ui/META-INF/MANIFEST.MF
===================================================================
--- trunk/org.rubypeople.rdt.ui/META-INF/MANIFEST.MF 2007-05-15 17:34:21 UTC (rev 2478)
+++ trunk/org.rubypeople.rdt.ui/META-INF/MANIFEST.MF 2007-05-15 17:36:12 UTC (rev 2479)
@@ -21,7 +21,6 @@
org.rubypeople.rdt.internal.ui.resourcesview,
org.rubypeople.rdt.internal.ui.rubyeditor,
org.rubypeople.rdt.internal.ui.search,
- org.rubypeople.rdt.internal.ui.symbols,
org.rubypeople.rdt.internal.ui.text,
org.rubypeople.rdt.internal.ui.text.folding,
org.rubypeople.rdt.internal.ui.text.ruby,
Added: trunk/org.rubypeople.rdt.ui/icons/full/dlcl16/prj_mode.gif
===================================================================
(Binary files differ)
Property changes on: trunk/org.rubypeople.rdt.ui/icons/full/dlcl16/prj_mode.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.rubypeople.rdt.ui/icons/full/dlcl16/type_mode.gif
===================================================================
(Binary files differ)
Property changes on: trunk/org.rubypeople.rdt.ui/icons/full/dlcl16/type_mode.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.rubypeople.rdt.ui/icons/full/elcl16/prj_mode.gif
===================================================================
(Binary files differ)
Property changes on: trunk/org.rubypeople.rdt.ui/icons/full/elcl16/prj_mode.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.rubypeople.rdt.ui/icons/full/elcl16/type_mode.gif
===================================================================
(Binary files differ)
Property changes on: trunk/org.rubypeople.rdt.ui/icons/full/elcl16/type_mode.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.rubypeople.rdt.ui/icons/full/obj16/rsearch_obj.gif
===================================================================
(Binary files differ)
Property changes on: trunk/org.rubypeople.rdt.ui/icons/full/obj16/rsearch_obj.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.rubypeople.rdt.ui/icons/full/obj16/search_decl_obj.gif
===================================================================
(Binary files differ)
Property changes on: trunk/org.rubypeople.rdt.ui/icons/full/obj16/search_decl_obj.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.rubypeople.rdt.ui/icons/full/obj16/search_ref_obj.gif
===================================================================
(Binary files differ)
Property changes on: trunk/org.rubypeople.rdt.ui/icons/full/obj16/search_ref_obj.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/org.rubypeople.rdt.ui/plugin.xml
===================================================================
--- trunk/org.rubypeople.rdt.ui/plugin.xml 2007-05-15 17:34:21 UTC (rev 2478)
+++ trunk/org.rubypeople.rdt.ui/plugin.xml 2007-05-15 17:36:12 UTC (rev 2479)
@@ -908,20 +908,6 @@
fileNames="%EditorRubyFile.filenames">
</participant>
</extension>
- <extension
- point="org.eclipse.search.searchPages">
- <page
- class="org.rubypeople.rdt.internal.ui.search.RubySearchPage"
- id="org.rubypeople.rdt.ui.RubySearchPage"
- label="%RubySearchPage.label"/>
- </extension>
- <extension
- point="org.eclipse.search.searchResultViewPages">
- <viewPage
- class="org.rubypeople.rdt.internal.ui.search.RubySearchResultPage"
- id="org.rubypeople.rdt.ui.search.RubySearchResultPage"
- searchResultClass="org.rubypeople.rdt.internal.ui.search.RubySearchResult"/>
- </extension>
<extension point="org.rubypeople.rdt.ui.rubyEditorTextHovers">
<hover
@@ -1019,4 +1005,41 @@
class="org.rubypeople.rdt.internal.ui.text.hyperlinks.RubyElementsHyperlinkProvider">
</hyperlinkProvider>
</extension>
+
+<!-- =========================================================================== -->
+<!-- Ruby Search Page -->
+<!-- =========================================================================== -->
+ <extension
+ point="org.eclipse.search.searchPages">
+ <page
+ showScopeSection="true"
+ canSearchEnclosingProjects="true"
+ label="%RubySearchPage.label"
+ icon="$nl$/icons/full/obj16/rsearch_obj.gif"
+ extensions="rb:90,rbw:90"
+ class="org.rubypeople.rdt.internal.ui.search.RubySearchPage"
+ sizeHint="460,160"
+ id="org.rubypeople.rdt.ui.RubySearchPage">
+ </page>
+ </extension>
+
+ <extension
+ id="RubySearchResultPage"
+ point="org.eclipse.search.searchResultViewPages">
+ <viewPage
+ id="org.rubypeople.rdt.ui.RubySearchResultPage"
+ searchResultClass="org.rubypeople.rdt.internal.ui.search.RubySearchResult"
+ class="org.rubypeople.rdt.internal.ui.search.RubySearchResultPage">
+ </viewPage>
+ </extension>
+<!-- <extension
+ id="OccurrencesSearchResultPage"
+ point="org.eclipse.search.searchResultViewPages">
+ <viewPage
+ id="org.rubypeople.rdt.internal.ui.search.OccurrencesSearchResultPage"
+ searchResultClass="org.rubypeople.rdt.internal.ui.search.OccurrencesSearchResult"
+ class="org.rubypeople.rdt.internal.ui.search.OccurrencesSearchResultPage">
+ </viewPage>
+ </extension>
+ -->
</plugin>
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/corext/util/SearchUtils.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/corext/util/SearchUtils.java 2007-05-15 17:34:21 UTC (rev 2478)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/corext/util/SearchUtils.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -1,10 +1,18 @@
package org.rubypeople.rdt.internal.corext.util;
+import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.search.SearchPattern;
public class SearchUtils {
/**
+ * Constant for use as matchRule in {@link SearchPattern#createPattern(IRubyElement, int, int)}
+ * to get search behavior as of 3.1M3 (all generic instantiations are found).
+ */
+ public final static int GENERICS_AGNOSTIC_MATCH_RULE= SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH;
+
+
+ /**
* Returns whether the given pattern is a camel case pattern or not.
*
* @param pattern the pattern to inspect
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/IRubyHelpContextIds.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/IRubyHelpContextIds.java 2007-05-15 17:34:21 UTC (rev 2478)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/IRubyHelpContextIds.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -224,7 +224,7 @@
public static final String EXCLUSION_PATTERN_DIALOG= PREFIX + "exclusion_pattern_dialog_context"; //$NON-NLS-1$
public static final String OUTPUT_LOCATION_DIALOG= PREFIX + "output_location_dialog_context"; //$NON-NLS-1$
public static final String VARIABLE_CREATION_DIALOG= PREFIX + "variable_creation_dialog_context"; //$NON-NLS-1$
- public static final String JAVA_SEARCH_PAGE= PREFIX + "java_search_page_context"; //$NON-NLS-1$
+ public static final String RUBY_SEARCH_PAGE= PREFIX + "java_search_page_context"; //$NON-NLS-1$
public static final String NLS_SEARCH_PAGE= PREFIX + "nls_search_page_context"; //$NON-NLS-1$
public static final String JAVA_EDITOR= PREFIX + "java_editor_context"; //$NON-NLS-1$
public static final String GOTO_RESOURCE_DIALOG= PREFIX + "goto_resource_dialog"; //$NON-NLS-1$
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPlugin.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPlugin.java 2007-05-15 17:34:21 UTC (rev 2478)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPlugin.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -54,7 +54,6 @@
import org.rubypeople.rdt.core.IRubyScript;
import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.core.WorkingCopyOwner;
-import org.rubypeople.rdt.internal.core.util.EclipseJobScheduler;
import org.rubypeople.rdt.internal.corext.util.TypeFilter;
import org.rubypeople.rdt.internal.formatter.OldCodeFormatter;
import org.rubypeople.rdt.internal.ui.preferences.MembersOrderPreferenceCache;
@@ -64,12 +63,12 @@
import org.rubypeople.rdt.internal.ui.rubyeditor.RubyDocumentProvider;
import org.rubypeople.rdt.internal.ui.rubyeditor.RubyScriptDocumentProvider;
import org.rubypeople.rdt.internal.ui.rubyeditor.WorkingCopyManager;
-import org.rubypeople.rdt.internal.ui.symbols.BlockingSymbolFinder;
import org.rubypeople.rdt.internal.ui.text.IRubyColorConstants;
import org.rubypeople.rdt.internal.ui.text.PreferencesAdapter;
import org.rubypeople.rdt.internal.ui.text.folding.RubyFoldingStructureProviderRegistry;
import org.rubypeople.rdt.internal.ui.text.ruby.hover.RubyEditorTextHoverDescriptor;
import org.rubypeople.rdt.internal.ui.text.template.contentassist.RubyTemplateAccess;
+import org.rubypeople.rdt.internal.ui.viewsupport.ProblemMarkerManager;
import org.rubypeople.rdt.ui.PreferenceConstants;
import org.rubypeople.rdt.ui.text.RubyTextTools;
@@ -115,6 +114,7 @@
* @since 1.0
*/
private TypeFilter fTypeFilter;
+ private ProblemMarkerManager fProblemMarkerManager;
public RubyPlugin() {
super();
@@ -167,10 +167,6 @@
fMembersOrderPreferenceCache = new MembersOrderPreferenceCache();
fMembersOrderPreferenceCache.install(store);
- RubyCore rubyCore = RubyCore.getPlugin();
- BlockingSymbolFinder symbolFinder = new BlockingSymbolFinder(rubyCore.getSymbolFinder(), new EclipseJobScheduler());
- rubyCore.setSymbolFinder(symbolFinder);
-
listenForNewProjects();
upgradeOldProjects();
String generateRdocOption = Platform.getDebugOption(RubyPlugin.PLUGIN_ID + "/generaterdoc");
@@ -622,5 +618,11 @@
}
return fRubyEditorTextHoverDescriptors;
- }
+ }
+
+ public synchronized ProblemMarkerManager getProblemMarkerManager() {
+ if (fProblemMarkerManager == null)
+ fProblemMarkerManager= new ProblemMarkerManager();
+ return fProblemMarkerManager;
+ }
}
\ No newline at end of file
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPluginImages.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPluginImages.java 2007-05-15 17:34:21 UTC (rev 2478)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPluginImages.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -43,6 +43,8 @@
public static final String IMG_OBJS_INFO = NAME_PREFIX + "info_obj.gif";
public static final String IMG_OBJS_HELP= NAME_PREFIX + "help.gif"; //$NON-NLS-1$
private static final String IMG_OBJS_GHOST= NAME_PREFIX + "ghost.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_SEARCH_DECL= NAME_PREFIX + "search_decl_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_SEARCH_REF= NAME_PREFIX + "search_ref_obj.gif"; //$NON-NLS-1$
public static final String IMG_OBJS_CLASS= NAME_PREFIX + "class_obj.gif"; //$NON-NLS-1$
private static final String IMG_OBJS_INNER_CLASS= NAME_PREFIX + "innerclass_obj.gif"; //$NON-NLS-1$
@@ -103,6 +105,8 @@
public static final ImageDescriptor DESC_OBJS_EXTJAR= createManagedFromKey(T_OBJ, IMG_OBJS_EXTJAR);
public static final ImageDescriptor DESC_OBJS_EXTJAR_WSRC= createManagedFromKey(T_OBJ, IMG_OBJS_EXTJAR_WSRC);
public static final ImageDescriptor DESC_OBJS_ENV_VAR= createManagedFromKey(T_OBJ, IMG_OBJS_ENV_VAR);
+ public static final ImageDescriptor DESC_OBJS_SEARCH_DECL= createManagedFromKey(T_OBJ, IMG_OBJS_SEARCH_DECL);
+ public static final ImageDescriptor DESC_OBJS_SEARCH_REF= createManagedFromKey(T_OBJ, IMG_OBJS_SEARCH_REF);
public static final ImageDescriptor DESC_OBJS_EXCLUSION_FILTER_ATTRIB= createUnManaged(T_OBJ, "exclusion_filter_attrib.gif"); //$NON-NLS-1$
public static final ImageDescriptor DESC_OBJS_INCLUSION_FILTER_ATTRIB= createUnManaged(T_OBJ, "inclusion_filter_attrib.gif"); //$NON-NLS-1$
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/ColorDecoratingLabelProvider.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/ColorDecoratingLabelProvider.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/ColorDecoratingLabelProvider.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.search;
+
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.graphics.Color;
+
+public class ColorDecoratingLabelProvider extends DecoratingLabelProvider implements IColorProvider {
+
+ public ColorDecoratingLabelProvider(ILabelProvider provider, ILabelDecorator decorator) {
+ super(provider, decorator);
+ }
+
+ public Color getForeground(Object element) {
+ ILabelProvider labelProvider = getLabelProvider();
+ if (labelProvider instanceof IColorProvider)
+ return ((IColorProvider)labelProvider).getForeground(element);
+ return null;
+ }
+
+ public Color getBackground(Object element) {
+ ILabelProvider labelProvider = getLabelProvider();
+ if (labelProvider instanceof IColorProvider)
+ return ((IColorProvider)labelProvider).getBackground(element);
+ return null;
+ }
+}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FilterAction.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FilterAction.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FilterAction.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.search;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+
+
+public class FilterAction extends Action {
+ private MatchFilter fFilter;
+ private RubySearchResultPage fPage;
+
+ public FilterAction(RubySearchResultPage page, MatchFilter filter) {
+ super(filter.getActionLabel(), IAction.AS_CHECK_BOX);
+ fPage= page;
+ fFilter= filter;
+ }
+
+ public void run() {
+ if (fPage.hasMatchFilter(getFilter())) {
+ fPage.removeMatchFilter(fFilter);
+ } else {
+ fPage.addMatchFilter(fFilter);
+ }
+ }
+
+ public MatchFilter getFilter() {
+ return fFilter;
+ }
+
+ public void updateCheckState() {
+ setChecked(fPage.hasMatchFilter(getFilter()));
+ }
+}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FiltersDialog.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FiltersDialog.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FiltersDialog.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * 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.ui.search;
+
+import java.util.Arrays;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.SelectionStatusDialog;
+import org.rubypeople.rdt.internal.ui.RubyPlugin;
+
+public class FiltersDialog extends SelectionStatusDialog {
+
+ private CheckboxTableViewer fListViewer;
+ private RubySearchResultPage fPage;
+ private Button fLimitElementsCheckbox;
+ private Text fLimitElementsField;
+
+ private int fLimitElementCount= 1000;
+ private boolean fLimitElements= false;
+
+ public FiltersDialog(RubySearchResultPage page) {
+ super(page.getSite().getShell());
+ setTitle(org.rubypeople.rdt.internal.ui.search.SearchMessages.FiltersDialog_title);
+ setStatusLineAboveButtons(true);
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ fPage = page;
+ }
+
+ public MatchFilter[] getEnabledFilters() {
+ Object[] result = getResult();
+ MatchFilter[] filters = new MatchFilter[result.length];
+ System.arraycopy(result, 0, filters, 0, filters.length);
+ return filters;
+ }
+
+ public boolean isLimitEnabled() {
+ return fLimitElements;
+ }
+
+ /**
+ * @return returns the number of entries to limit the filters entry to
+ */
+ public int getElementLimit() {
+ return fLimitElementCount;
+ }
+
+ /*
+ * (non-Rubydoc) Method declared on Dialog.
+ */
+ protected Control createDialogArea(Composite composite) {
+ Composite parent = (Composite) super.createDialogArea(composite);
+ initializeDialogUnits(composite);
+
+ createTableLimit(parent);
+ // Create list viewer
+ Label l= new Label(parent, SWT.NONE);
+ l.setFont(parent.getFont());
+ l.setText(org.rubypeople.rdt.internal.ui.search.SearchMessages.FiltersDialog_filters_label);
+
+ Table table = new Table(parent, SWT.CHECK | SWT.BORDER);
+ table.setFont(parent.getFont());
+ fListViewer = new CheckboxTableViewer(table);
+
+
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.minimumHeight= convertHeightInCharsToPixels(8);
+ table.setLayoutData(data);
+
+ fListViewer.setLabelProvider(new LabelProvider() {
+ public String getText(Object element) {
+ // Return the features's label.
+ return ((MatchFilter) element).getName();
+ }
+ });
+
+ // Set the content provider
+ ArrayContentProvider cp = new ArrayContentProvider();
+ fListViewer.setContentProvider(cp);
+ fListViewer.setInput(MatchFilter.allFilters());
+ fListViewer.setCheckedElements(fPage.getMatchFilters());
+
+ l= new Label(parent, SWT.NONE);
+ l.setFont(parent.getFont());
+ l.setText(org.rubypeople.rdt.internal.ui.search.SearchMessages.FiltersDialog_description_label);
+ final Text description = new Text(parent, SWT.LEFT | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL);
+ description.setFont(parent.getFont());
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.heightHint = convertHeightInCharsToPixels(3);
+ description.setLayoutData(data);
+ fListViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ Object selectedElement = ((IStructuredSelection) event.getSelection()).getFirstElement();
+ if (selectedElement != null)
+ description.setText(((MatchFilter) selectedElement).getDescription());
+ else
+ description.setText(""); //$NON-NLS-1$
+ }
+ });
+ return parent;
+ }
+
+
+ private void createTableLimit(Composite ancestor) {
+ Composite parent = new Composite(ancestor, SWT.NONE);
+ GridLayout gl = new GridLayout();
+ gl.numColumns = 2;
+ gl.marginWidth = 0;
+ gl.marginHeight = 0;
+ parent.setLayout(gl);
+ GridData gd = new GridData();
+ gd.horizontalSpan = 2;
+ parent.setLayoutData(gd);
+
+ fLimitElementsCheckbox = new Button(parent, SWT.CHECK);
+ fLimitElementsCheckbox.setText(org.rubypeople.rdt.internal.ui.search.SearchMessages.FiltersDialog_limit_label);
+ fLimitElementsCheckbox.setLayoutData(new GridData());
+
+ fLimitElementsField = new Text(parent, SWT.BORDER);
+ gd = new GridData();
+ gd.widthHint = convertWidthInCharsToPixels(6);
+ fLimitElementsField.setLayoutData(gd);
+
+ applyDialogFont(parent);
+
+ fLimitElementsCheckbox.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ updateLimitValueEnablement();
+ }
+
+ });
+
+ fLimitElementsField.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent e) {
+ validateText();
+ }
+ });
+ initLimit();
+ }
+
+ private void initLimit() {
+ boolean limit = fPage.limitElements();
+ int count = fPage.getElementLimit();
+ fLimitElementsCheckbox.setSelection(limit);
+ fLimitElementsField.setText(String.valueOf(count));
+
+ updateLimitValueEnablement();
+ }
+
+ private void updateLimitValueEnablement() {
+ fLimitElementsField.setEnabled(fLimitElementsCheckbox.getSelection());
+ }
+
+ protected void validateText() {
+ String text = fLimitElementsField.getText();
+ int value = -1;
+ try {
+ value = Integer.valueOf(text).intValue();
+ } catch (NumberFormatException e) {
+
+ }
+ if (fLimitElementsCheckbox.getSelection() && value <= 0)
+ updateStatus(new Status(IStatus.ERROR, RubyPlugin.getPluginId(), 0, org.rubypeople.rdt.internal.ui.search.SearchMessages.FiltersDialog_limit_error, null));
+ else
+ updateStatus(new Status(IStatus.OK, RubyPlugin.getPluginId(), 0, "", null)); //$NON-NLS-1$
+ }
+
+ protected void computeResult() {
+ fLimitElementCount= Integer.valueOf(fLimitElementsField.getText()).intValue();
+ fLimitElements= fLimitElementsCheckbox.getSelection();
+
+ setResult(Arrays.asList(fListViewer.getCheckedElements()));
+ }
+}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FiltersDialogAction.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FiltersDialogAction.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/FiltersDialogAction.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.search;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.window.Window;
+
+
+public class FiltersDialogAction extends Action {
+ private RubySearchResultPage fPage;
+
+ public FiltersDialogAction(RubySearchResultPage page) {
+ super(SearchMessages.FiltersDialogAction_label);
+ fPage= page;
+ }
+
+ public void run() {
+ FiltersDialog dialog = new FiltersDialog(fPage);
+
+ if (dialog.open() == Window.OK) {
+ fPage.setFilters(dialog.getEnabledFilters());
+ fPage.enableLimit(dialog.isLimitEnabled());
+ fPage.setElementLimit(dialog.getElementLimit());
+ }
+ }
+
+}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupAction.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupAction.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupAction.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.search;
+
+import org.eclipse.jface.action.Action;
+
+
+public class GroupAction extends Action {
+ private int fGrouping;
+ private RubySearchResultPage fPage;
+
+ public GroupAction(String label, String tooltip, RubySearchResultPage page, int grouping) {
+ super(label);
+ setToolTipText(tooltip);
+ fPage= page;
+ fGrouping= grouping;
+ }
+
+ public void run() {
+ fPage.setGrouping(fGrouping);
+ }
+
+ public int getGrouping() {
+ return fGrouping;
+ }
+}
Deleted: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByAction.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByAction.java 2007-05-15 17:34:21 UTC (rev 2478)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByAction.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -1,14 +0,0 @@
-package org.rubypeople.rdt.internal.ui.search;
-
-import org.eclipse.jface.action.Action;
-import org.rubypeople.rdt.internal.ui.RubyPluginImages;
-
-
-public class GroupByAction extends Action {
-
- public GroupByAction(String label, String image) {
- super(label) ;
- this.setToolTipText(label) ;
- RubyPluginImages.setLocalImageDescriptors(this, image) ;
- }
-}
Deleted: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByPathStrategy.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByPathStrategy.java 2007-05-15 17:34:21 UTC (rev 2478)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByPathStrategy.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -1,12 +0,0 @@
-package org.rubypeople.rdt.internal.ui.search;
-
-import org.rubypeople.rdt.internal.core.symbols.SearchResult;
-
-public class GroupByPathStrategy implements IGroupByStrategy {
-
- public Object getParent(Object element) {
- if (!(element instanceof SearchResult)) { return null; }
- SearchResult result = (SearchResult) element;
- return result.getLocation().getSourceFile().getFullPath();
- }
-}
Deleted: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByScopeStrategy.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByScopeStrategy.java 2007-05-15 17:34:21 UTC (rev 2478)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/GroupByScopeStrategy.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -1,30 +0,0 @@
-package org.rubypeople.rdt.internal.ui.search;
-
-import org.rubypeople.rdt.internal.core.symbols.SearchResult;
-
-
-
-public class GroupByScopeStrategy implements IGroupByStrategy {
-
- private Scope createScope(String qualifiedName) {
- int index = qualifiedName.lastIndexOf("::") ;
- if (index == -1) {
- return null ;
- }
- String packageName = qualifiedName.substring(0, index) ;
- return new Scope(packageName);
- }
-
- public Object getParent(Object element) {
- if (element instanceof SearchResult) {
- SearchResult result = (SearchResult) element ;
- return this.createScope(result.getSymbol().getName()) ;
- }
- if (element instanceof Scope) {
- Scope scope = (Scope) element ;
- return this.createScope(scope.getQualifiedName()) ;
- }
- return null ;
- }
-
-}
Deleted: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/IGroupByStrategy.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/IGroupByStrategy.java 2007-05-15 17:34:21 UTC (rev 2478)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/IGroupByStrategy.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -1,6 +0,0 @@
-package org.rubypeople.rdt.internal.ui.search;
-
-
-public interface IGroupByStrategy {
- public Object getParent(Object element) ;
-}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/IOccurrencesFinder.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/IOccurrencesFinder.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/IOccurrencesFinder.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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.ui.search;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.internal.core.RubyScript;
+
+public interface IOccurrencesFinder {
+
+ public String initialize(RubyScript root, int offset, int length);
+
+ public List 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);
+}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/LRUWorkingSetsList.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/LRUWorkingSetsList.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/LRUWorkingSetsList.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.search;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.PlatformUI;
+
+public class LRUWorkingSetsList {
+
+ private final ArrayList fLRUList;
+ private final int fSize;
+ private final WorkingSetsComparator fComparator= new WorkingSetsComparator();
+
+ public LRUWorkingSetsList(int size) {
+ fSize= size;
+ fLRUList= new ArrayList(size);
+ }
+
+ public void add(IWorkingSet[] workingSets) {
+ removeDeletedWorkingSets();
+ IWorkingSet[] existingWorkingSets= find(fLRUList, workingSets);
+ if (existingWorkingSets != null)
+ fLRUList.remove(existingWorkingSets);
+ else if (fLRUList.size() == fSize)
+ fLRUList.remove(fSize - 1);
+ fLRUList.add(0, workingSets);
+
+ }
+
+ public Iterator iterator() {
+ removeDeletedWorkingSets();
+ return fLRUList.iterator();
+ }
+
+ public Iterator sortedIterator() {
+ removeDeletedWorkingSets();
+ ArrayList sortedList= new ArrayList(fLRUList);
+ Collections.sort(sortedList, fComparator);
+ return sortedList.iterator();
+ }
+
+ private void removeDeletedWorkingSets() {
+ Iterator iter= new ArrayList(fLRUList).iterator();
+ while (iter.hasNext()) {
+ IWorkingSet[] workingSets= (IWorkingSet[])iter.next();
+ for (int i= 0; i < workingSets.length; i++) {
+ if (PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(workingSets[i].getName()) == null) {
+ fLRUList.remove(workingSets);
+ break;
+ }
+ }
+ }
+ }
+
+ private IWorkingSet[] find(ArrayList list, IWorkingSet[] workingSets) {
+ Set workingSetList= new HashSet(Arrays.asList(workingSets));
+ Iterator iter= list.iterator();
+ while (iter.hasNext()) {
+ IWorkingSet[] lruWorkingSets= (IWorkingSet[])iter.next();
+ Set lruWorkingSetList= new HashSet(Arrays.asList(lruWorkingSets));
+ if (lruWorkingSetList.equals(workingSetList))
+ return lruWorkingSets;
+ }
+ return null;
+ }
+}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/LevelTreeContentProvider.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/LevelTreeContentProvider.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/LevelTreeContentProvider.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -0,0 +1,241 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.search;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyScript;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.ui.StandardRubyElementContentProvider;
+
+public class LevelTreeContentProvider extends RubySearchContentProvider implements ITreeContentProvider {
+ private Map fChildrenMap;
+ private StandardRubyElementContentProvider fContentProvider;
+
+ public static final int LEVEL_TYPE= 1;
+ public static final int LEVEL_FILE= 2;
+ public static final int LEVEL_PACKAGE= 3;
+ public static final int LEVEL_PROJECT= 4;
+
+ private static int[][] JAVA_ELEMENT_TYPES= {{IRubyElement.TYPE},
+ {IRubyElement.SCRIPT},
+ {IRubyElement.SOURCE_FOLDER},
+ {IRubyElement.RUBY_PROJECT, IRubyElement.SOURCE_FOLDER_ROOT},
+ {IRubyElement.RUBY_MODEL}};
+ private static int[][] RESOURCE_TYPES= {
+ {},
+ {IResource.FILE},
+ {IResource.FOLDER},
+ {IResource.PROJECT},
+ {IResource.ROOT}};
+
+ private static final int MAX_LEVEL= JAVA_ELEMENT_TYPES.length - 1;
+ private int fCurrentLevel;
+ static class FastRubyElementProvider extends StandardRubyElementContentProvider {
+ public Object getParent(Object element) {
+ return internalGetParent(element);
+ }
+ }
+
+ public LevelTreeContentProvider(RubySearchResultPage page, int level) {
+ super(page);
+ fCurrentLevel= level;
+ fContentProvider= new FastRubyElementProvider();
+ }
+
+ public Object getParent(Object child) {
+ Object possibleParent= internalGetParent(child);
+ if (possibleParent instanceof IRubyElement) {
+ IRubyElement javaElement= (IRubyElement) possibleParent;
+ for (int j= fCurrentLevel; j < MAX_LEVEL + 1; j++) {
+ for (int i= 0; i < JAVA_ELEMENT_TYPES[j].length; i++) {
+ if (javaElement.getElementType() == JAVA_ELEMENT_TYPES[j][i]) {
+ return null;
+ }
+ }
+ }
+ } else if (possibleParent instanceof IResource) {
+ IResource resource= (IResource) possibleParent;
+ for (int j= fCurrentLevel; j < MAX_LEVEL + 1; j++) {
+ for (int i= 0; i < RESOURCE_TYPES[j].length; i++) {
+ if (resource.getType() == RESOURCE_TYPES[j][i]) {
+ return null;
+ }
+ }
+ }
+ }
+ if (fCurrentLevel != LEVEL_FILE && child instanceof IType) {
+ IType type= (IType) child;
+ if (possibleParent instanceof IRubyScript)
+ possibleParent= type.getSourceFolder();
+ }
+ return possibleParent;
+ }
+
+ private Object internalGetParent(Object child) {
+ return fContentProvider.getParent(child);
+ }
+
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ protected synchronized void initialize(RubySearchResult result) {
+ super.initialize(result);
+ fChildrenMap= new HashMap();
+ if (result != null) {
+ Object[] elements= result.getElements();
+ for (int i= 0; i < elements.length; i++) {
+ if (getPage().getDisplayedMatchCount(elements[i]) > 0) {
+ insert(null, null, elements[i]);
+ }
+ }
+ }
+ }
+
+ protected void insert(Map toAdd, Set toUpdate, Object child) {
+ Object parent= getParent(child);
+ while (parent != null) {
+ if (insertChild(parent, child)) {
+ if (toAdd != null)
+ insertInto(parent, child, toAdd);
+ } else {
+ if (toUpdate != null)
+ toUpdate.add(parent);
+ return;
+ }
+ child= parent;
+ parent= getParent(child);
+ }
+ if (insertChild(fResult, child)) {
+ if (toAdd != null)
+ insertInto(fResult, child, toAdd);
+ }
+ }
+
+ private boolean insertChild(Object parent, Object child) {
+ return insertInto(parent, child, fChildrenMap);
+ }
+
+ private boolean insertInto(Object parent, Object child, Map map) {
+ Set children= (Set) map.get(parent);
+ if (children == null) {
+ children= new HashSet();
+ map.put(parent, children);
+ }
+ return children.add(child);
+ }
+
+ protected void remove(Set toRemove, Set toUpdate, Object element) {
+ // precondition here: fResult.getMatchCount(child) <= 0
+
+ if (hasChildren(element)) {
+ if (toUpdate != null)
+ toUpdate.add(element);
+ } else {
+ if (getPage().getDisplayedMatchCount(element) == 0) {
+ fChildrenMap.remove(element);
+ Object parent= getParent(element);
+ if (parent != null) {
+ if (removeFromSiblings(element, parent)) {
+ remove(toRemove, toUpdate, parent);
+ }
+ } else {
+ if (removeFromSiblings(element, fResult)) {
+ if (toRemove != null)
+ toRemove.add(element);
+ }
+ }
+ } else {
+ if (toUpdate != null) {
+ toUpdate.add(element);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param element
+ * @param parent
+ * @return returns true if it really was a remove (i.e. element was a child of parent).
+ */
+ private boolean removeFromSiblings(Object element, Object parent) {
+ Set siblings= (Set) fChildrenMap.get(parent);
+ if (siblings != null) {
+ return siblings.remove(element);
+ } else {
+ return false;
+ }
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ Set children= (Set) fChildrenMap.get(parentElement);
+ if (children == null)
+ return EMPTY_ARR;
+ return children.toArray();
+ }
+
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+
+ public synchronized void elementsChanged(Object[] updatedElements) {
+ AbstractTreeViewer viewer= (AbstractTreeViewer) getPage().getViewer();
+ if (fResult == null)
+ return;
+ Set toRemove= new HashSet();
+ Set toUpdate= new HashSet();
+ Map toAdd= new HashMap();
+ for (int i= 0; i < updatedElements.length; i++) {
+ if (getPage().getDisplayedMatchCount(updatedElements[i]) > 0)
+ insert(toAdd, toUpdate, updatedElements[i]);
+ else
+ remove(toRemove, toUpdate, updatedElements[i]);
+ }
+
+ viewer.remove(toRemove.toArray());
+ for (Iterator iter= toAdd.keySet().iterator(); iter.hasNext();) {
+ Object parent= iter.next();
+ HashSet children= (HashSet) toAdd.get(parent);
+ viewer.add(parent, children.toArray());
+ }
+ for (Iterator elementsToUpdate= toUpdate.iterator(); elementsToUpdate.hasNext();) {
+ viewer.refresh(elementsToUpdate.next());
+ }
+
+ }
+
+ public void clear() {
+ initialize(fResult);
+ getPage().getViewer().refresh();
+ }
+
+ public void setLevel(int level) {
+ fCurrentLevel= level;
+ initialize(fResult);
+ getPage().getViewer().refresh();
+ }
+
+ public void filtersChanged(MatchFilter[] filters) {
+ super.filtersChanged(filters);
+ initialize(fResult);
+ getPage().getViewer().refresh();
+ }
+}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/MatchFilter.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/MatchFilter.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/MatchFilter.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * 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.ui.search;
+
+import java.util.StringTokenizer;
+
+import org.rubypeople.rdt.core.IField;
+import org.rubypeople.rdt.core.IImportDeclaration;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.search.IRubySearchConstants;
+import org.rubypeople.rdt.core.search.SearchMatch;
+import org.rubypeople.rdt.internal.ui.RubyPlugin;
+import org.rubypeople.rdt.ui.search.ElementQuerySpecification;
+import org.rubypeople.rdt.ui.search.PatternQuerySpecification;
+import org.rubypeople.rdt.ui.search.QuerySpecification;
+
+abstract class MatchFilter {
+
+ private static final String SETTINGS_LAST_USED_FILTERS= "filters_last_used"; //$NON-NLS-1$
+
+ public static MatchFilter[] getLastUsedFilters() {
+ String string= RubyPlugin.getDefault().getDialogSettings().get(SETTINGS_LAST_USED_FILTERS);
+ if (string != null && string.length() > 0) {
+ return decodeFiltersString(string);
+ }
+ return getDefaultFilters();
+ }
+
+ public static void setLastUsedFilters(MatchFilter[] filters) {
+ String encoded= encodeFilters(filters);
+ RubyPlugin.getDefault().getDialogSettings().put(SETTINGS_LAST_USED_FILTERS, encoded);
+ }
+
+ public static MatchFilter[] getDefaultFilters() {
+ return new MatchFilter[] { IMPORT_FILTER };
+ }
+
+ private static String encodeFilters(MatchFilter[] enabledFilters) {
+ StringBuffer buf= new StringBuffer();
+ buf.append(enabledFilters.length);
+ for (int i= 0; i < enabledFilters.length; i++) {
+ buf.append(';');
+ buf.append(enabledFilters[i].getID());
+ }
+ return buf.toString();
+ }
+
+ private static MatchFilter[] decodeFiltersString(String encodedString) {
+ StringTokenizer tokenizer= new StringTokenizer(encodedString, String.valueOf(';'));
+ MatchFilter[] res;
+ try {
+ int count= Integer.valueOf(tokenizer.nextToken()).intValue();
+ res= new MatchFilter[count];
+ for (int i= 0; i < count; i++) {
+ res[i]= findMatchFilter(tokenizer.nextToken());
+ }
+ } catch (NumberFormatException e) {
+ res= getDefaultFilters();
+ }
+ return res;
+ }
+
+
+ public abstract boolean isApplicable(RubySearchQuery query);
+
+ public abstract boolean filters(RubyElementMatch match);
+
+ public abstract String getName();
+ public abstract String getActionLabel();
+
+ public abstract String getDescription();
+
+ public abstract String getID();
+
+ private static final MatchFilter POTENTIAL_FILTER= new PotentialFilter();
+ private static final MatchFilter IMPORT_FILTER= new ImportFilter();
+ private static final MatchFilter JAVADOC_FILTER= new RubydocFilter();
+ private static final MatchFilter READ_FILTER= new ReadFilter();
+ private static final MatchFilter WRITE_FILTER= new WriteFilter();
+
+ private static final MatchFilter[] ALL_FILTERS= new MatchFilter[] {
+ POTENTIAL_FILTER,
+ IMPORT_FILTER,
+ JAVADOC_FILTER,
+ READ_FILTER,
+ WRITE_FILTER
+ };
+
+ public static MatchFilter[] allFilters() {
+ return ALL_FILTERS;
+ }
+
+ private static MatchFilter findMatchFilter(String id) {
+ for (int i= 0; i < ALL_FILTERS.length; i++) {
+ if (ALL_FILTERS[i].getID().equals(id))
+ return ALL_FILTERS[i];
+ }
+ return IMPORT_FILTER; // just return something, should not happen
+ }
+
+
+}
+
+class PotentialFilter extends MatchFilter {
+ public boolean filters(RubyElementMatch match) {
+ return match.getAccuracy() == SearchMatch.A_INACCURATE;
+ }
+
+ public String getName() {
+ return SearchMessages.MatchFilter_PotentialFilter_name;
+ }
+
+ public String getActionLabel() {
+ return SearchMessages.MatchFilter_PotentialFilter_actionLabel;
+ }
+
+ public String getDescription() {
+ return SearchMessages.MatchFilter_PotentialFilter_description;
+ }
+
+ public boolean isApplicable(RubySearchQuery query) {
+ return true;
+ }
+
+ public String getID() {
+ return "filter_potential"; //$NON-NLS-1$
+ }
+}
+
+class ImportFilter extends MatchFilter {
+ public boolean filters(RubyElementMatch match) {
+ return match.getElement() instanceof IImportDeclaration;
+ }
+
+ public String getName() {
+ return SearchMessages.MatchFilter_ImportFilter_name;
+ }
+
+ public String getActionLabel() {
+ return SearchMessages.MatchFilter_ImportFilter_actionLabel;
+ }
+
+ public String getDescription() {
+ return SearchMessages.MatchFilter_ImportFilter_description;
+ }
+
+ public boolean isApplicable(RubySearchQuery query) {
+ QuerySpecification spec= query.getSpecification();
+ if (spec instanceof ElementQuerySpecification) {
+ ElementQuerySpecification elementSpec= (ElementQuerySpecification) spec;
+ return elementSpec.getElement() instanceof IType;
+ } else if (spec instanceof PatternQuerySpecification) {
+ PatternQuerySpecification patternSpec= (PatternQuerySpecification) spec;
+ return patternSpec.getSearchFor() == IRubySearchConstants.TYPE;
+ }
+ return false;
+ }
+
+ public String getID() {
+ return "filter_imports"; //$NON-NLS-1$
+ }
+}
+
+abstract class FieldFilter extends MatchFilter {
+ public boolean isApplicable(RubySearchQuery query) {
+ QuerySpecification spec= query.getSpecification();
+ if (spec instanceof ElementQuerySpecification) {
+ ElementQuerySpecification elementSpec= (ElementQuerySpecification) spec;
+ return elementSpec.getElement() instanceof IField;
+ } else if (spec instanceof PatternQuerySpecification) {
+ PatternQuerySpecification patternSpec= (PatternQuerySpecification) spec;
+ return patternSpec.getSearchFor() == IRubySearchConstants.FIELD;
+ }
+ return false;
+ }
+
+}
+
+class WriteFilter extends FieldFilter {
+ public boolean filters(RubyElementMatch match) {
+ return match.isWriteAccess() && !match.isReadAccess();
+ }
+ public String getName() {
+ return SearchMessages.MatchFilter_WriteFilter_name;
+ }
+ public String getActionLabel() {
+ return SearchMessages.MatchFilter_WriteFilter_actionLabel;
+ }
+ public String getDescription() {
+ return SearchMessages.MatchFilter_WriteFilter_description;
+ }
+ public String getID() {
+ return "filter_writes"; //$NON-NLS-1$
+ }
+}
+
+class ReadFilter extends FieldFilter {
+ public boolean filters(RubyElementMatch match) {
+ return match.isReadAccess() && !match.isWriteAccess();
+ }
+ public String getName() {
+ return SearchMessages.MatchFilter_ReadFilter_name;
+ }
+ public String getActionLabel() {
+ return SearchMessages.MatchFilter_ReadFilter_actionLabel;
+ }
+ public String getDescription() {
+ return SearchMessages.MatchFilter_ReadFilter_description;
+ }
+ public String getID() {
+ return "filter_reads"; //$NON-NLS-1$
+ }
+}
+
+class RubydocFilter extends MatchFilter {
+ public boolean filters(RubyElementMatch match) {
+ return match.isRubydoc();
+ }
+ public String getName() {
+ return SearchMessages.MatchFilter_RubydocFilter_name;
+ }
+ public String getActionLabel() {
+ return SearchMessages.MatchFilter_RubydocFilter_actionLabel;
+ }
+ public String getDescription() {
+ return SearchMessages.MatchFilter_RubydocFilter_description;
+ }
+ public boolean isApplicable(RubySearchQuery query) {
+ return true;
+ }
+ public String getID() {
+ return "filter_javadoc"; //$NON-NLS-1$
+ }
+}
+
+
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/NewSearchResultCollector.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/NewSearchResultCollector.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/search/NewSearchResultCollector.java 2007-05-15 17:36:12 UTC (rev 2479)
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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 - ini...
[truncated message content] |
|
From: <caw...@us...> - 2007-05-15 17:34:22
|
Revision: 2478
http://svn.sourceforge.net/rubyeclipse/?rev=2478&view=rev
Author: cawilliams
Date: 2007-05-15 10:34:21 -0700 (Tue, 15 May 2007)
Log Message:
-----------
replace our existing symbol index stuff with a first cut at a fully fledged search engine
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/META-INF/MANIFEST.MF
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/IRubySearchConstants.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchEngine.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchPattern.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/builder/AbstractRdtCompiler.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/builder/CleanRdtCompiler.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/builder/IncrementalRdtCompiler.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/builder/RubyBuilder.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/builder/RubyCodeAnalyzer.java
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/PatternLocator.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/TypeReferencePattern.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Messages.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Util.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/core/TS_Core.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/TS_InternalCore.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/builder/AbstractRdtTestCase.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/builder/TC_CleanRdtCompiler.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/builder/TC_IncrementalRdtCompiler.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/builder/TC_RubyCodeAnalyzer.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/builder/TS_InternalCoreBuilder.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/FieldReferenceMatch.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/TypeReferenceMatch.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/LocalVariableLocator.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/LocalVariablePattern.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/OrLocator.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/TypeReferenceLocator.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/VariableLocator.java
Removed Paths:
-------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/SymbolIndexResourceChangeListener.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/builder/IndexUpdater.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/builder/MassIndexUpdater.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/builder/MassIndexUpdaterJob.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/symbols/ClassSymbol.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/symbols/ISymbolFinder.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/symbols/ISymbolTypes.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/symbols/Location.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/symbols/MethodSymbol.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/symbols/SearchResult.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/symbols/Symbol.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/symbols/SymbolIndex.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/symbols/SymbolSchedulingRule.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/ShamMassIndexUpdater.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/TC_SymbolIndexResourceEventListener.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/builder/ShamIndexUpdater.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/builder/ShamSymbolIndex.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/builder/TC_IndexUpdater.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/builder/TC_MassIndexUpdater.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/builder/TC_MassIndexUpdaterJob.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/symbols/TC_ClassSymbol.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/symbols/TC_Location.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/symbols/TC_SymbolIndex.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/core/symbols/TS_CoreSymbols.java
Modified: trunk/org.rubypeople.rdt.core/META-INF/MANIFEST.MF
===================================================================
--- trunk/org.rubypeople.rdt.core/META-INF/MANIFEST.MF 2007-05-15 16:35:35 UTC (rev 2477)
+++ trunk/org.rubypeople.rdt.core/META-INF/MANIFEST.MF 2007-05-15 17:34:21 UTC (rev 2478)
@@ -19,7 +19,6 @@
org.rubypeople.rdt.internal.core.parser,
org.rubypeople.rdt.internal.core.parser.warnings,
org.rubypeople.rdt.internal.core.search,
- org.rubypeople.rdt.internal.core.symbols,
org.rubypeople.rdt.internal.core.util,
org.rubypeople.rdt.internal.formatter,
org.rubypeople.rdt.internal.ti,
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java 2007-05-15 16:35:35 UTC (rev 2477)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java 2007-05-15 17:34:21 UTC (rev 2478)
@@ -12,7 +12,6 @@
import java.io.File;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
@@ -57,13 +56,8 @@
import org.rubypeople.rdt.internal.core.RubyModelManager;
import org.rubypeople.rdt.internal.core.RubyProject;
import org.rubypeople.rdt.internal.core.SetLoadpathOperation;
-import org.rubypeople.rdt.internal.core.SymbolIndexResourceChangeListener;
-import org.rubypeople.rdt.internal.core.builder.IndexUpdater;
-import org.rubypeople.rdt.internal.core.builder.MassIndexUpdaterJob;
import org.rubypeople.rdt.internal.core.builder.RubyBuilder;
import org.rubypeople.rdt.internal.core.parser.RubyParser;
-import org.rubypeople.rdt.internal.core.symbols.ISymbolFinder;
-import org.rubypeople.rdt.internal.core.symbols.SymbolIndex;
import org.rubypeople.rdt.internal.core.util.MementoTokenizer;
import org.rubypeople.rdt.internal.core.util.Util;
@@ -75,7 +69,6 @@
private static final String RUBY_PARSER_DEBUG_OPTION = RubyCore.PLUGIN_ID + "/rubyparser";//$NON-NLS-1$
private static final String MODEL_MANAGER_VERBOSE_OPTION = RubyCore.PLUGIN_ID + "/modelmanager";//$NON-NLS-1$
- private static final String SYMBOL_INDEX_VERBOSE_OPTION = RubyCore.PLUGIN_ID + "/symbolIndex";//$NON-NLS-1$
private static final String BUILDER_VERBOSE_OPTION = RubyCore.PLUGIN_ID + "/rubyBuilder";//$NON-NLS-1$
public final static String NATURE_ID = PLUGIN_ID + ".rubynature";//$NON-NLS-1$
@@ -288,17 +281,12 @@
* @since 1.0.0
*/
public static final String USER_LIBRARY_CONTAINER_ID= "org.rubypeople.rdt.USER_LIBRARY"; //$NON-NLS-1$
-
-
+
private static final boolean VERBOSE = false;
- private SymbolIndex symbolIndex;
- private ISymbolFinder symbolFinder;
-
public RubyCore() {
super();
RUBY_CORE_PLUGIN = this;
- symbolFinder = symbolIndex = new SymbolIndex();
}
/**
@@ -325,16 +313,9 @@
RubyParser.setDebugging(isDebugOptionTrue(RUBY_PARSER_DEBUG_OPTION));
RubyModelManager.setVerbose(isDebugOptionTrue(MODEL_MANAGER_VERBOSE_OPTION));
- SymbolIndex.setVerbose(isDebugOptionTrue(SYMBOL_INDEX_VERBOSE_OPTION));
RubyBuilder.setVerbose(isDebugOptionTrue(BUILDER_VERBOSE_OPTION));
ResourcesPlugin.getWorkspace().addResourceChangeListener(new RubyProjectListener(), IResourceChangeEvent.POST_CHANGE);
-
- SymbolIndexResourceChangeListener.register(symbolIndex);
- IndexUpdater indexUpdater = new IndexUpdater(symbolIndex);
- List rubyProjects = Arrays.asList(getRubyProjects());
- MassIndexUpdaterJob massUpdater = new MassIndexUpdaterJob(indexUpdater, rubyProjects);
- massUpdater.schedule();
}
/*
@@ -540,18 +521,6 @@
}
}
- public SymbolIndex getSymbolIndex() {
- return symbolIndex;
- }
-
- public ISymbolFinder getSymbolFinder() {
- return symbolFinder;
- }
-
- public void setSymbolFinder(ISymbolFinder symbolFinder) {
- this.symbolFinder = symbolFinder;
- }
-
/**
* Helper method for returning one option value only. Equivalent to
* <code>(String)JavaCore.getOptions().get(optionName)</code> Note that it
Added: 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 (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/FieldReferenceMatch.java 2007-05-15 17:34:21 UTC (rev 2478)
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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 org.eclipse.core.resources.IResource;
+import org.rubypeople.rdt.core.IRubyElement;
+
+/**
+ * A Java search match that represents a field reference.
+ * The element is the inner-most enclosing member that references this field.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 1.0
+ */
+public class FieldReferenceMatch extends SearchMatch {
+
+ private boolean isReadAccess;
+ private boolean isWriteAccess;
+
+ /**
+ * Creates a new field reference match.
+ *
+ * @param enclosingElement the inner-most enclosing member that references this field
+ * @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
+ * @param isReadAccess whether the match represents a read access
+ * @param isWriteAccess whethre the match represents a write access
+ * @param insideDocComment <code>true</code> if this search match is inside a doc
+ * comment, and <code>false</code> otherwise
+ * @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) {
+ super(enclosingElement, accuracy, offset, length, participant, resource);
+ this.isReadAccess = isReadAccess;
+ this.isWriteAccess = isWriteAccess;
+ setInsideDocComment(insideDocComment);
+ }
+
+ /**
+ * Returns whether the field reference is a read access to the field.
+ * Note that a field reference can be read and written at once in case of compound assignments (e.g. i += 0;)
+ *
+ * @return whether the field reference is a read access to the field.
+ */
+ public final boolean isReadAccess() {
+ return this.isReadAccess;
+ }
+
+ /**
+ * Returns whether the field reference is a write access to the field.
+ * Note that a field reference can be read and written at once in case of compound assignments (e.g. i += 0;)
+ *
+ * @return whether the field reference is a write access to the field.
+ */
+ public final boolean isWriteAccess() {
+ return this.isWriteAccess;
+ }
+
+}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/IRubySearchConstants.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/IRubySearchConstants.java 2007-05-15 16:35:35 UTC (rev 2477)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/IRubySearchConstants.java 2007-05-15 17:34:21 UTC (rev 2478)
@@ -1,88 +1,95 @@
-package org.rubypeople.rdt.core.search;
-
-import org.rubypeople.rdt.internal.core.search.processing.IJob;
-
-public interface IRubySearchConstants {
- /**
- * The search operation waits for the underlying indexer to finish indexing
- * the workspace before starting the search.
- */
- int WAIT_UNTIL_READY_TO_SEARCH = IJob.WaitUntilReady;
-
- /**
- * The search result is a declaration.
- * Can be used in conjunction with any of the nature of searched elements
- * so as to better narrow down the search.
- */
- int DECLARATIONS= 0;
-
- /**
- * The search result is a reference.
- * Can be used in conjunction with any of the nature of searched elements
- * so as to better narrow down the search.
- * References can contain implementers since they are more generic kind
- * of matches.
- */
- int REFERENCES= 2;
-
- /**
- * The search result is a declaration, a reference, or an implementer
- * of an interface.
- * Can be used in conjunction with any of the nature of searched elements
- * so as to better narrow down the search.
- */
- int ALL_OCCURRENCES= 3;
-
- /**
- * When searching for field matches, it will exclusively find read accesses, as
- * opposed to write accesses. Note that some expressions are considered both
- * as field read/write accesses: for example, x++; x+= 1;
- *
- * @since 2.0
- */
- int READ_ACCESSES = 4;
-
- /**
- * When searching for field matches, it will exclusively find write accesses, as
- * opposed to read accesses. Note that some expressions are considered both
- * as field read/write accesses: for example, x++; x+= 1;
- *
- * @since 2.0
- */
- int WRITE_ACCESSES = 5;
-
-/* Nature of searched element */
-
- /**
- * The searched element is a type, which may include classes and modules.
- */
- int TYPE= 0;
-
- /**
- * The searched element is a method.
- */
- int METHOD= 1;
-
- /**
- * The searched element is a constructor.
- */
- int CONSTRUCTOR= 3;
-
- /**
- * The searched element is a field.
- */
- int FIELD= 4;
-
- /**
- * The searched element is a class.
- * More selective than using {@link #TYPE}.
- */
- int CLASS= 5;
-
- /**
- * The searched element is a module.
- * More selective than using {@link #TYPE}.
- */
- int MODULE= 6;
-
-}
+package org.rubypeople.rdt.core.search;
+
+import org.rubypeople.rdt.internal.core.search.processing.IJob;
+
+public interface IRubySearchConstants {
+ /**
+ * The search operation waits for the underlying indexer to finish indexing
+ * the workspace before starting the search.
+ */
+ int WAIT_UNTIL_READY_TO_SEARCH = IJob.WaitUntilReady;
+
+ /**
+ * The search result is a declaration.
+ * Can be used in conjunction with any of the nature of searched elements
+ * so as to better narrow down the search.
+ */
+ int DECLARATIONS= 0;
+
+ /**
+ * The search result is a reference.
+ * Can be used in conjunction with any of the nature of searched elements
+ * so as to better narrow down the search.
+ * References can contain implementers since they are more generic kind
+ * of matches.
+ */
+ int REFERENCES= 1;
+
+ /**
+ * The search result is a declaration, a reference, or an implementer
+ * of an interface.
+ * Can be used in conjunction with any of the nature of searched elements
+ * so as to better narrow down the search.
+ */
+ int ALL_OCCURRENCES= 2;
+
+ /**
+ * When searching for field matches, it will exclusively find read accesses, as
+ * opposed to write accesses. Note that some expressions are considered both
+ * as field read/write accesses: for example, x++; x+= 1;
+ *
+ * @since 2.0
+ */
+ int READ_ACCESSES = 3;
+
+ /**
+ * When searching for field matches, it will exclusively find write accesses, as
+ * opposed to read accesses. Note that some expressions are considered both
+ * as field read/write accesses: for example, x++; x+= 1;
+ *
+ * @since 2.0
+ */
+ int WRITE_ACCESSES = 4;
+
+ /**
+ * Ignore declaring type while searching result.
+ * Can be used in conjunction with any of the nature of match.
+ * @since 1.0
+ */
+ int IGNORE_DECLARING_TYPE = 0x10;
+
+/* Nature of searched element */
+
+ /**
+ * The searched element is a type, which may include classes and modules.
+ */
+ int TYPE= 0;
+
+ /**
+ * The searched element is a method.
+ */
+ int METHOD= 1;
+
+ /**
+ * The searched element is a constructor.
+ */
+ int CONSTRUCTOR= 2;
+
+ /**
+ * The searched element is a field.
+ */
+ int FIELD= 3;
+
+ /**
+ * The searched element is a class.
+ * More selective than using {@link #TYPE}.
+ */
+ int CLASS= 4;
+
+ /**
+ * The searched element is a module.
+ * More selective than using {@link #TYPE}.
+ */
+ int MODULE= 5;
+
+}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchEngine.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchEngine.java 2007-05-15 16:35:35 UTC (rev 2477)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchEngine.java 2007-05-15 17:34:21 UTC (rev 2478)
@@ -1,5 +1,6 @@
package org.rubypeople.rdt.core.search;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.RubyModelException;
@@ -100,4 +101,63 @@
return BasicSearchEngine.createRubySearchScope(elements);
}
+ /**
+ * Returns a Ruby search scope limited to the given Ruby elements.
+ * The Ruby elements resulting from a search with this scope will
+ * be children of the given elements.
+ *
+ * If an element is an IRubyProject, then it includes:
+ * - its source folders if IRubySearchScope.SOURCES is specified,
+ * - its application libraries (internal and external jars, class folders that are on the raw classpath,
+ * or the ones that are coming from a classpath path variable,
+ * or the ones that are coming from a classpath container with the K_APPLICATION kind)
+ * if IJavaSearchScope.APPLICATION_LIBRARIES is specified
+ * - its system libraries (internal and external jars, class folders that are coming from an
+ * IClasspathContainer with the K_SYSTEM kind)
+ * if IJavaSearchScope.APPLICATION_LIBRARIES is specified
+ * - its referenced projects (with their source folders and jars, recursively)
+ * if IJavaSearchScope.REFERENCED_PROJECTS is specified.
+ * If an element is an IPackageFragmentRoot, then only the package fragments of
+ * this package fragment root will be included.
+ * If an element is an IPackageFragment, then only the compilation unit and class
+ * files of this package fragment will be included. Subpackages will NOT be
+ * included.
+ *
+ * @param elements the Ruby elements the scope is limited to
+ * @param includeMask the bit-wise OR of all include types of interest
+ * @return a new Ruby search scope
+ * @see IRubySearchScope#SOURCES
+ * @see IRubySearchScope#APPLICATION_LIBRARIES
+ * @see IRubySearchScope#SYSTEM_LIBRARIES
+ * @see IRubySearchScope#REFERENCED_PROJECTS
+ * @since 1.0
+ */
+ public static IRubySearchScope createRubySearchScope(IRubyElement[] elements, int includeMask) {
+ return BasicSearchEngine.createRubySearchScope(elements, includeMask);
+ }
+
+ public static SearchParticipant getDefaultSearchParticipant() {
+ return BasicSearchEngine.getDefaultSearchParticipant();
+ }
+
+ /**
+ * Searches for matches of a given search pattern. Search patterns can be created using helper
+ * methods (from a String pattern or a Java element) and encapsulate the description of what is
+ * being searched (for example, search method declarations in a case sensitive way).
+ *
+ * @param pattern the pattern to search
+ * @param participants the particpants in the search
+ * @param scope the search scope
+ * @param requestor the requestor to report the matches to
+ * @param monitor the progress monitor used to report progress
+ * @exception CoreException if the search failed. Reasons include:
+ * <ul>
+ * <li>the classpath is incorrectly set</li>
+ * </ul>
+ *@since 1.0
+ */
+ public void search(SearchPattern pattern, SearchParticipant[] participants, IRubySearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException {
+ this.basicEngine.search(pattern, participants, scope, requestor, monitor);
+ }
+
}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchPattern.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchPattern.java 2007-05-15 16:35:35 UTC (rev 2477)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/SearchPattern.java 2007-05-15 17:34:21 UTC (rev 2478)
@@ -1,791 +1,1207 @@
-package org.rubypeople.rdt.core.search;
-
-import org.rubypeople.rdt.core.IRubyElement;
-import org.rubypeople.rdt.internal.compiler.parser.ScannerHelper;
-import org.rubypeople.rdt.internal.core.search.indexing.IIndexConstants;
-import org.rubypeople.rdt.internal.core.search.matching.ConstructorPattern;
-import org.rubypeople.rdt.internal.core.search.matching.FieldPattern;
-import org.rubypeople.rdt.internal.core.search.matching.InternalSearchPattern;
-import org.rubypeople.rdt.internal.core.search.matching.MethodPattern;
-import org.rubypeople.rdt.internal.core.search.matching.OrPattern;
-import org.rubypeople.rdt.internal.core.search.matching.QualifiedTypeDeclarationPattern;
-import org.rubypeople.rdt.internal.core.search.matching.TypeReferencePattern;
-import org.rubypeople.rdt.internal.core.util.CharOperation;
-
-public abstract class SearchPattern extends InternalSearchPattern {
-// Rules for pattern matching: (exact, prefix, pattern) [ | case sensitive]
- /**
- * Match rule: The search pattern matches exactly the search result,
- * that is, the source of the search result equals the search pattern.
- */
- public static final int R_EXACT_MATCH = 0;
-
- /**
- * Match rule: The search pattern is a prefix of the search result.
- */
- public static final int R_PREFIX_MATCH = 0x0001;
-
- /**
- * Match rule: The search pattern contains one or more wild cards ('*' or '?').
- * A '*' wild-card can replace 0 or more characters in the search result.
- * A '?' wild-card replaces exactly 1 character in the search result.
- */
- public static final int R_PATTERN_MATCH = 0x0002;
-
- /**
- * Match rule: The search pattern contains a regular expression.
- */
- public static final int R_REGEXP_MATCH = 0x0004;
-
- /**
- * Match rule: The search pattern matches the search result only if cases are the same.
- * Can be combined to previous rules, e.g. {@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE}
- */
- public static final int R_CASE_SENSITIVE = 0x0008;
-
- /**
- * Match rule: The search pattern matches search results as raw/parameterized types/methods with same erasure.
- * This mode has no effect on other java elements search.<br>
- * Type search example:
- * <ul>
- * <li>pattern: <code>List<Exception></code></li>
- * <li>match: <code>List<Object></code></li>
- * </ul>
- * Method search example:
- * <ul>
- * <li>declaration: <code><T>foo(T t)</code></li>
- * <li>pattern: <code><Exception>foo(new Exception())</code></li>
- * <li>match: <code><Object>foo(new Object())</code></li>
- * </ul>
- * Can be combined to all other match rules, e.g. {@link #R_CASE_SENSITIVE} | {@link #R_ERASURE_MATCH}
- * This rule is not activated by default, so raw types or parameterized types with same erasure will not be found
- * for pattern List<String>,
- * Note that with this pattern, the match selection will be only on the erasure even for parameterized types.
- * @since 3.1
- */
- public static final int R_ERASURE_MATCH = 0x0010;
-
- /**
- * Match rule: The search pattern matches search results as raw/parameterized types/methods with equivalent type parameters.
- * This mode has no effect on other java elements search.<br>
- * Type search example:
- * <ul>
- * <li>pattern: <code>List<Exception></code></li>
- * <li>match:
- * <ul>
- * <li><code>List<? extends Throwable></code></li>
- * <li><code>List<? super RuntimeException></code></li>
- * <li><code>List<?></code></li>
- * </ul>
- * </li>
- * </ul>
- * Method search example:
- * <ul>
- * <li>declaration: <code><T>foo(T t)</code></li>
- * <li>pattern: <code><Exception>foo(new Exception())</code></li>
- * <li>match:
- * <ul>
- * <li><code><? extends Throwable>foo(new Exception())</code></li>
- * <li><code><? super RuntimeException>foo(new Exception())</code></li>
- * <li><code>foo(new Exception())</code></li>
- * </ul>
- * </ul>
- * Can be combined to all other match rules, e.g. {@link #R_CASE_SENSITIVE} | {@link #R_EQUIVALENT_MATCH}
- * This rule is not activated by default, so raw types or equivalent parameterized types will not be found
- * for pattern List<String>,
- * This mode is overridden by {@link #R_ERASURE_MATCH} as erasure matches obviously include equivalent ones.
- * That means that pattern with rule set to {@link #R_EQUIVALENT_MATCH} | {@link #R_ERASURE_MATCH}
- * will return same results than rule only set with {@link #R_ERASURE_MATCH}.
- * @since 3.1
- */
- public static final int R_EQUIVALENT_MATCH = 0x0020;
-
- /**
- * Match rule: The search pattern matches exactly the search result,
- * that is, the source of the search result equals the search pattern.
- * @since 3.1
- */
- public static final int R_FULL_MATCH = 0x0040;
-
- /**
- * Match rule: The search pattern contains a Camel Case expression.
- * <br>
- * Examples:
- * <ul>
- * <li><code>NPE</code> type string pattern will match
- * <code>NullPointerException</code> and <code>NpPermissionException</code> types,</li>
- * <li><code>NuPoEx</code> type string pattern will only match
- * <code>NullPointerException</code> type.</li>
- * </ul>
- * @see CharOperation#camelCaseMatch(char[], char[]) for a detailed explanation
- * of Camel Case matching.
- *<br>
- * Can be combined to {@link #R_PREFIX_MATCH} match rule. For example,
- * when prefix match rule is combined with Camel Case match rule,
- * <code>"nPE"</code> pattern will match <code>nPException</code>.
- *<br>
- * Match rule {@link #R_PATTERN_MATCH} may also be combined but both rules
- * will not be used simultaneously as they are mutually exclusive.
- * Used match rule depends on whether string pattern contains specific pattern
- * characters (e.g. '*' or '?') or not. If it does, then only Pattern match rule
- * will be used, otherwise only Camel Case match will be used.
- * For example, with <code>"NPE"</code> string pattern, search will only use
- * Camel Case match rule, but with <code>N*P*E*</code> string pattern, it will
- * use only Pattern match rule.
- *
- * @since 3.2
- */
- public static final int R_CAMELCASE_MATCH = 0x0080;
-
- private static final int MODE_MASK = R_EXACT_MATCH | R_PREFIX_MATCH | R_PATTERN_MATCH | R_REGEXP_MATCH;
-
- private int matchRule;
-
- /**
- * Creates a search pattern with the rule to apply for matching index keys.
- * It can be exact match, prefix match, pattern match or regexp match.
- * Rule can also be combined with a case sensitivity flag.
- *
- * @param matchRule one of {@link #R_EXACT_MATCH}, {@link #R_PREFIX_MATCH}, {@link #R_PATTERN_MATCH},
- * {@link #R_REGEXP_MATCH}, {@link #R_CAMELCASE_MATCH} combined with one of following values:
- * {@link #R_CASE_SENSITIVE}, {@link #R_ERASURE_MATCH} or {@link #R_EQUIVALENT_MATCH}.
- * e.g. {@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
- * {@link #R_PREFIX_MATCH} if a prefix non case sensitive match is requested or {@link #R_EXACT_MATCH} | {@link #R_ERASURE_MATCH}
- * if a non case sensitive and erasure match is requested.<br>
- * Note that {@link #R_ERASURE_MATCH} or {@link #R_EQUIVALENT_MATCH} have no effect
- * on non-generic types/methods search.<br>
- * Note also that default behavior for generic types/methods search is to find exact matches.
- */
- public SearchPattern(int matchRule) {
- this.matchRule = matchRule;
- // Set full match implicit mode
- if ((matchRule & (R_EQUIVALENT_MATCH | R_ERASURE_MATCH )) == 0) {
- this.matchRule |= R_FULL_MATCH;
- }
- }
-
- /**
- * Returns a blank pattern that can be used as a record to decode an index key.
- * <p>
- * Implementors of this method should return a new search pattern that is going to be used
- * to decode index keys.
- * </p>
- *
- * @return a new blank pattern
- * @see #decodeIndexKey(char[])
- */
- public abstract SearchPattern getBlankPattern();
-
- /**
- * Decode the given index key in this pattern. The decoded index key is used by
- * {@link #matchesDecodedKey(SearchPattern)} to find out if the corresponding index entry
- * should be considered.
- * <p>
- * This method should be re-implemented in subclasses that need to decode an index key.
- * </p>
- *
- * @param key the given index key
- */
- public void decodeIndexKey(char[] key) {
- // called from findIndexMatches(), override as necessary
- }
-
- /**
- * Returns a key to find in relevant index categories, if null then all index entries are matched.
- * The key will be matched according to some match rule. These potential matches
- * will be further narrowed by the match locator, but precise match locating can be expensive,
- * and index query should be as accurate as possible so as to eliminate obvious false hits.
- * <p>
- * This method should be re-implemented in subclasses that need to narrow down the
- * index query.
- * </p>
- *
- * @return an index key from this pattern, or <code>null</code> if all index entries are matched.
- */
- public char[] getIndexKey() {
- return null; // called from queryIn(), override as necessary
- }
- /**
- * Returns an array of index categories to consider for this index query.
- * These potential matches will be further narrowed by the match locator, but precise
- * match locating can be expensive, and index query should be as accurate as possible
- * so as to eliminate obvious false hits.
- * <p>
- * This method should be re-implemented in subclasses that need to narrow down the
- * index query.
- * </p>
- *
- * @return an array of index categories
- */
- public char[][] getIndexCategories() {
- return CharOperation.NO_CHAR_CHAR; // called from queryIn(), override as necessary
- }
-
- /**
- * Returns the rule to apply for matching index keys. Can be exact match, prefix match, pattern match or regexp match.
- * Rule can also be combined with a case sensitivity flag.
- *
- * @return one of R_EXACT_MATCH, R_PREFIX_MATCH, R_PATTERN_MATCH, R_REGEXP_MATCH combined with R_CASE_SENSITIVE,
- * e.g. R_EXACT_MATCH | R_CASE_SENSITIVE if an exact and case sensitive match is requested,
- * or R_PREFIX_MATCH if a prefix non case sensitive match is requested.
- * [TODO (frederic) I hope R_ERASURE_MATCH doesn't need to be on this list. Because it would be a breaking API change.]
- */
- public final int getMatchRule() {
- return this.matchRule;
- }
- /**
- * Returns whether this pattern matches the given pattern (representing a decoded index key).
- * <p>
- * This method should be re-implemented in subclasses that need to narrow down the
- * index query.
- * </p>
- *
- * @param decodedPattern a pattern representing a decoded index key
- * @return whether this pattern matches the given pattern
- */
- public boolean matchesDecodedKey(SearchPattern decodedPattern) {
- return true; // called from findIndexMatches(), override as necessary if index key is encoded
- }
-
- public static SearchPattern createPattern(int elementType, String stringPattern, int limitTo, int matchRule) {
- switch (elementType) {
- case IRubyElement.TYPE:
- return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.TYPE_SUFFIX);
- case IRubyElement.METHOD:
- return createMethodOrConstructorPattern(stringPattern, limitTo, matchRule, false/*not a constructor*/);
- case IRubyElement.FIELD:
- case IRubyElement.CONSTANT:
- case IRubyElement.GLOBAL:
- case IRubyElement.CLASS_VAR:
- case IRubyElement.INSTANCE_VAR:
- return createFieldPattern(stringPattern, limitTo, matchRule);
- default:
- break;
- }
- return null;
- }
-
- /**
- * Field pattern are formed by [declaringType.]name[ type]
- * e.g. java.lang.String.serialVersionUID long
- * field*
- */
- private static SearchPattern createFieldPattern(String patternString, int limitTo, int matchRule) {
- String fieldName = patternString;
- if (fieldName == null) return null;
-
- char[] fieldNameChars = fieldName.toCharArray();
- if (fieldNameChars.length == 1 && fieldNameChars[0] == '*') fieldNameChars = null;
-
- char[] declaringTypeQualification = null, declaringTypeSimpleName = null;
- char[] typeQualification = null, typeSimpleName = null;
-
- // Create field pattern
- boolean findDeclarations = false;
- boolean readAccess = false;
- boolean writeAccess = false;
- switch (limitTo) {
- case IRubySearchConstants.DECLARATIONS :
- findDeclarations = true;
- break;
- case IRubySearchConstants.REFERENCES :
- readAccess = true;
- writeAccess = true;
- break;
- case IRubySearchConstants.READ_ACCESSES :
- readAccess = true;
- break;
- case IRubySearchConstants.WRITE_ACCESSES :
- writeAccess = true;
- break;
- case IRubySearchConstants.ALL_OCCURRENCES :
- findDeclarations = true;
- readAccess = true;
- writeAccess = true;
- break;
- }
- return new FieldPattern(
- findDeclarations,
- readAccess,
- writeAccess,
- fieldNameChars,
- declaringTypeQualification,
- declaringTypeSimpleName,
- matchRule);
- }
-
- /**
- * Returns whether the given name matches the given pattern.
- * <p>
- * This method should be re-implemented in subclasses that need to define how
- * a name matches a pattern.
- * </p>
- *
- * @param pattern the given pattern, or <code>null</code> to represent "*"
- * @param name the given name
- * @return whether the given name matches the given pattern
- */
- public boolean matchesName(char[] pattern, char[] name) {
- if (pattern == null) return true; // null is as if it was "*"
- if (name != null) {
- boolean isCaseSensitive = (this.matchRule & R_CASE_SENSITIVE) != 0;
- boolean isCamelCase = (this.matchRule & R_CAMELCASE_MATCH) != 0;
- int matchMode = this.matchRule & MODE_MASK;
- boolean sameLength = pattern.length == name.length;
- boolean canBePrefix = name.length >= pattern.length;
- boolean matchFirstChar = !isCaseSensitive || pattern.length == 0 || (name.length > 0 && pattern[0] == name[0]);
- if (isCamelCase && matchFirstChar && CharOperation.camelCaseMatch(pattern, name)) {
- return true;
- }
- switch (matchMode) {
- case R_EXACT_MATCH :
- case R_FULL_MATCH :
- if (!isCamelCase) {
- if (sameLength && matchFirstChar) {
- return CharOperation.equals(pattern, name, isCaseSensitive);
- }
- break;
- }
- // fall through next case to match as prefix if camel case failed
- case R_PREFIX_MATCH :
- if (canBePrefix && matchFirstChar) {
- return CharOperation.prefixEquals(pattern, name, isCaseSensitive);
- }
- break;
-
- case R_PATTERN_MATCH :
- if (!isCaseSensitive)
- pattern = CharOperation.toLowerCase(pattern);
- return CharOperation.match(pattern, name, isCaseSensitive);
-
- case R_REGEXP_MATCH :
- // TODO (frederic) implement regular expression match
- return true;
- }
- }
- return false;
- }
-
- /**
- * Type pattern are formed by [qualification '.']type [typeArguments].
- * e.g. java.lang.Object
- * Runnable
- * List<String>
- *
- * @since 3.1
- * Type arguments can be specified to search references to parameterized types.
- * and look as follow: '<' { [ '?' {'extends'|'super'} ] type ( ',' [ '?' {'extends'|'super'} ] type )* | '?' } '>'
- * Please note that:
- * - '*' is not valid inside type arguments definition <>
- * - '?' is treated as a wildcard when it is inside <> (ie. it must be put on first position of the type argument)
- */
- private static SearchPattern createTypePattern(String patternString, int limitTo, int matchRule, char indexSuffix) {
- char[] typePart = patternString.toCharArray();
- char[] typeChars = null;
- char[] qualificationChars = null;
- // get qualification name
- int lastDotPosition = CharOperation.lastIndexOf("::", typePart);
- if (lastDotPosition >= 0) {
- qualificationChars = CharOperation.subarray(typePart, 0, lastDotPosition);
- if (qualificationChars.length == 1 && qualificationChars[0] == '*')
- qualificationChars = null;
- typeChars = CharOperation.subarray(typePart, lastDotPosition+2, typePart.length);
- } else {
- typeChars = typePart;
- }
- if (typeChars.length == 1 && typeChars[0] == '*') {
- typeChars = null;
- }
- switch (limitTo) {
- case IRubySearchConstants.DECLARATIONS : // cannot search for explicit member types
- return new QualifiedTypeDeclarationPattern(qualificationChars, typeChars, indexSuffix, matchRule);
- case IRubySearchConstants.REFERENCES :
- return new TypeReferencePattern(qualificationChars, typeChars, matchRule);
-// case IRubySearchConstants.IMPLEMENTORS :
-// return new SuperTypeReferencePattern(qualificationChars, typeChars, SuperTypeReferencePattern.ONLY_SUPER_INTERFACES, indexSuffix, matchRule);
- case IRubySearchConstants.ALL_OCCURRENCES :
- return new OrPattern(
- new QualifiedTypeDeclarationPattern(qualificationChars, typeChars, indexSuffix, matchRule),// cannot search for explicit member types
- new TypeReferencePattern(qualificationChars, typeChars, matchRule));
- }
- return null;
- }
-
- /**
- * Method pattern are formed by:<br>
- * [declaringType '.'] selector ['(' parameterTypes ')']
- * <br>e.g.<ul>
- * <li>java.lang.Runnable.run() void</li>
- * <li>main(*)</li>
- * <li><String>toArray(String[])</li>
- * </ul>
- * Constructor pattern are formed by:<br>
- * [declaringQualification '.'] type ['(' parameterTypes ')']
- * <br>e.g.<ul>
- * <li>java.lang.Object()</li>
- * <li>Main(*)</li>
- * <li><Exception>Sample(Exception)</li>
- * </ul>
- * Type arguments have the same pattern that for type patterns
- * @see #createTypePattern(String,int,int,char)
- */
- private static SearchPattern createMethodOrConstructorPattern(String patternString, int limitTo, int matchRule, boolean isConstructor) {
- char[] selectorChars = patternString.toCharArray();
- // TODO Break up the patternString into declaring type, method name, etc
- char[][] parameterNames = new char[0][];
- char[] declaringTypeSimpleName = null;
- char[] declaringTypeQualification = null;
- // Create method/constructor pattern
- boolean findDeclarations = true;
- boolean findReferences = true;
- switch (limitTo) {
- case IRubySearchConstants.DECLARATIONS :
- findReferences = false;
- break;
- case IRubySearchConstants.REFERENCES :
- findDeclarations = false;
- break;
- case IRubySearchConstants.ALL_OCCURRENCES :
- break;
- }
- if (isConstructor) {
- return new ConstructorPattern(
- findDeclarations,
- findReferences,
- declaringTypeSimpleName,
- declaringTypeQualification,
- parameterNames,
- matchRule);
- } else {
- return new MethodPattern(
- findDeclarations,
- findReferences,
- selectorChars,
- declaringTypeQualification,
- declaringTypeSimpleName,
- parameterNames,
- matchRule);
- }
- }
-
- /**
- * Answers true if the pattern matches the given name using CamelCase rules, or false otherwise.
- * CamelCase matching does NOT accept explicit wild-cards '*' and '?' and is inherently case sensitive.
- * <br>
- * CamelCase denotes the convention of writing compound names without spaces, and capitalizing every term.
- * This function recognizes both upper and lower CamelCase, depending whether the leading character is capitalized
- * or not. The leading part of an upper CamelCase pattern is assumed to contain a sequence of capitals which are appearing
- * in the matching name; e.g. 'NPE' will match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
- * uses a lowercase first character. In Java, type names follow the upper CamelCase convention, whereas method or field
- * names follow the lower CamelCase convention.
- * <br>
- * The pattern may contain lowercase characters, which will be match in a case sensitive way. These characters must
- * appear in sequence in the name. For instance, 'NPExcep' will match 'NullPointerException', but not 'NullPointerExCEPTION'
- * or 'NuPoEx' will match 'NullPointerException', but not 'NoPointerException'.
- * <br><br>
- * Examples:
- * <ol>
- * <li><pre>
- * pattern = "NPE"
- * name = NullPointerException / NoPermissionException
- * result => true
- * </pre>
- * </li>
- * <li><pre>
- * pattern = "NuPoEx"
- * name = NullPointerException
- * result => true
- * </pre>
- * </li>
- * <li><pre>
- * pattern = "npe"
- * name = NullPointerException
- * result => false
- * </pre>
- * </li>
- * </ol>
- * @see CharOperation#camelCaseMatch(char[], char[])
- * Implementation has been entirely copied from this method except for array lengthes
- * which were obviously replaced with calls to {@link String#length()}.
- *
- * @param pattern the given pattern
- * @param name the given name
- * @return true if the pattern matches the given name, false otherwise
- * @since 3.2
- */
- public static final boolean camelCaseMatch(String pattern, String name) {
- if (pattern == null)
- return true; // null pattern is equivalent to '*'
- if (name == null)
- return false; // null name cannot match
-
- return camelCaseMatch(pattern, 0, pattern.length(), name, 0, name.length());
- }
-
- /**
- * Answers true if a sub-pattern matches the subpart of the given name using CamelCase rules, or false otherwise.
- * CamelCase matching does NOT accept explicit wild-cards '*' and '?' and is inherently case sensitive.
- * Can match only subset of name/pattern, considering end positions as non-inclusive.
- * The subpattern is defined by the patternStart and patternEnd positions.
- * <br>
- * CamelCase denotes the convention of writing compound names without spaces, and capitalizing every term.
- * This function recognizes both upper and lower CamelCase, depending whether the leading character is capitalized
- * or not. The leading part of an upper CamelCase pattern is assumed to contain a sequence of capitals which are appearing
- * in the matching name; e.g. 'NPE' will match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
- * uses a lowercase first character. In Java, type names follow the upper CamelCase convention, whereas method or field
- * names follow the lower CamelCase convention.
- * <br>
- * The pattern may contain lowercase characters, which will be match in a case sensitive way. These characters must
- * appear in sequence in the name. For instance, 'NPExcep' will match 'NullPointerException', but not 'NullPointerExCEPTION'
- * or 'NuPoEx' will match 'NullPointerException', but not 'NoPointerException'.
- * <br><br>
- * Examples:
- * <ol>
- * <li><pre>
- * pattern = "NPE"
- * patternStart = 0
- * patternEnd = 3
- * name = NullPointerException
- * nameStart = 0
- * nameEnd = 20
- * result => true
- * </pre>
- * </li>
- * <li><pre>
- * pattern = "NPE"
- * patternStart = 0
- * patternEnd = 3
- * name = NoPermissionException
- * nameStart = 0
- * nameEnd = 21
- * result => true
- * </pre>
- * </li>
- * <li><pre>
- * pattern = "NuPoEx"
- * patternStart = 0
- * patternEnd = 6
- * name = NullPointerException
- * nameStart = 0
- * nameEnd = 20
- * result => true
- * </pre>
- * </li>
- * <li><pre>
- * pattern = "NuPoEx"
- * patternStart = 0
- * patternEnd = 6
- * name = NoPermissionException
- * nameStart = 0
- * nameEnd = 21
- * result => false
- * </pre>
- * </li>
- * <li><pre>
- * pattern = "npe"
- * patternStart = 0
- * patternEnd = 3
- * name = NullPointerException
- * nameStart = 0
- * nameEnd = 20
- * result => false
- * </pre>
- * </li>
- * </ol>
- * @see CharOperation#camelCaseMatch(char[], int, int, char[], int, int)
- * Implementation has been entirely copied from this method except for array lengthes
- * which were obviously replaced with calls to {@link String#length()} and
- * for array direct access which were replaced with calls to {@link String#charAt(int)}.
- *
- * @param pattern the given pattern
- * @param patternStart the start index of the pattern, inclusive
- * @param patternEnd the end index of the pattern, exclusive
- * @param name the given name
- * @param nameStart the start index of the name, inclusive
- * @param nameEnd the end index of the name, exclusive
- * @return true if a sub-pattern matches the subpart of the given name, false otherwise
- * @since 3.2
- */
- public static final boolean camelCaseMatch(String pattern, int patternStart, int patternEnd, String name, int nameStart, int nameEnd) {
- if (name == null)
- return false; // null name cannot match
- if (pattern == null)
- return true; // null pattern is equivalent to '*'
- if (patternEnd < 0) patternEnd = pattern.length();
- if (nameEnd < 0) nameEnd = name.length();
-
- if (patternEnd <= patternStart) return nameEnd <= nameStart;
- if (nameEnd <= nameStart) return false;
- // check first pattern char
- if (name.charAt(nameStart) != pattern.charAt(patternStart)) {
- // first char must strictly match (upper/lower)
- return false;
- }
-
- char patternChar, nameChar;
- int iPattern = patternStart;
- int iName = nameStart;
-
- // Main loop is on pattern characters
- while (true) {
-
- iPattern++;
- iName++;
-
- if (iPattern == patternEnd) {
- // We have exhausted pattern, so it's a match
- return true;
- }
-
- if (iName == nameEnd){
- // We have exhausted name (and not pattern), so it's not a match
- return false;
- }
-
- // For as long as we're exactly matching, bring it on (even if it's a lower case character)
- if ((patternChar = pattern.charAt(iPattern)) == name.charAt(iName)) {
- continue;
- }
-
- // If characters are not equals, then it's not a match if patternChar is lowercase
- if (patternChar < ScannerHelper.MAX_OBVIOUS) {
- if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[patternChar] & ScannerHelper.C_UPPER_LETTER) == 0) {
- return false;
- }
- }
- else if (Character.isJavaIdentifierPart(patternChar) && !Character.isUpperCase(patternChar)) {
- return false;
- }
-
- // patternChar is uppercase, so let's find the next uppercase in name
- while (true) {
- if (iName == nameEnd){
- // We have exhausted name (and not pattern), so it's not a match
- return false;
- }
-
- nameChar = name.charAt(iName);
-
- if (nameChar < ScannerHelper.MAX_OBVIOUS) {
- if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar] & (ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_SPECIAL | ScannerHelper.C_DIGIT)) != 0) {
- // nameChar is lowercase
- iName++;
- // nameChar is uppercase...
- } else if (patternChar != nameChar) {
- //.. and it does not match patternChar, so it's not a match
- return false;
- } else {
- //.. and it matched patternChar. Back to the big loop
- break;
- }
- }
- else if (Character.isJavaIdentifierPart(nameChar) && !Character.isUpperCase(nameChar)) {
- // nameChar is lowercase
- iName++;
- // nameChar is uppercase...
- } else if (patternChar != nameChar) {
- //.. and it does not match patternChar, so it's not a match
- return false;
- } else {
- //.. and it matched patternChar. Back to the big loop
- break;
- }
- }
- // At this point, either name has been exhausted, or it is at an uppercase letter.
- // Since pattern is also at an uppercase letter
- }
- }
-
- /**
- * Validate compatibility between given string pattern and match rule.
- *<br>
- * Optimized (ie. returned match rule is modified) combinations are:
- * <ul>
- * <li>{@link #R_PATTERN_MATCH} without any '*' or '?' in string pattern:
- * pattern match bit is unset,
- * </li>
- * <li>{@link #R_PATTERN_MATCH} and {@link #R_PREFIX_MATCH} bits simultaneously set:
- * prefix match bit is unset,
- * </li>
- * <li>{@link #R_PATTERN_MATCH} and {@link #R_CAMELCASE_MATCH} bits simultaneously set:
- * camel case match bit is unset,
- * </li>
- * <li>{@link #R_CAMELCASE_MATCH} with invalid combination of uppercase and lowercase characters:
- * camel case match bit is unset and replaced with prefix match pattern,
- * </li>
- * <li>{@link #R_CAMELCASE_MATCH} combined with {@link #R_PREFIX_MATCH} and {@link #R_CASE_SENSITIVE}
- * bits is reduced to only {@link #R_CAMELCASE_MATCH} as Camel Case search is already prefix and case sensitive,
- * </li>
- * </ul>
- *<br>
- * Rejected (ie. returned match rule -1) combinations are:
- * <ul>
- * <li>{@link #R_REGEXP_MATCH} with any other match mode bit set,
- * </li>
- * </ul>
- *
- * @param stringPattern The string pattern
- * @param matchRule The match rule
- * @return Optimized valid match rule or -1 if an incompatibility was detected.
- * @since 3.2
- */
- public static int validateMatchRule(String stringPattern, int matchRule) {
-
- // Verify Regexp match rule
- if ((matchRule & R_REGEXP_MATCH) != 0) {
- if ((matchRule & R_PATTERN_MATCH) != 0 || (matchRule & R_PREFIX_MATCH) != 0 || (matchRule & R_CAMELCASE_MATCH) != 0) {
- return -1;
- }
- }
-
- // Verify Pattern match rule
- int starIndex = stringPattern.indexOf('*');
- int questionIndex = stringPattern.indexOf('?');
- if (starIndex < 0 && questionIndex < 0) {
- // reset pattern match bit if any
- matchRule &= ~R_PATTERN_MATCH;
- } else {
- // force Pattern rule
- matchRule |= R_PATTERN_MATCH;
- }
- if ((matchRule & R_PATTERN_MATCH) != 0) {
- // remove Camel Case and Prefix match bits if any
- matchRule &= ~R_CAMELCASE_MATCH;
- matchRule &= ~R_PREFIX_MATCH;
- }
-
- // Verify Camel Case match rule
- if ((matchRule & R_CAMELCASE_MATCH) != 0) {
- // Verify sting pattern validity
- int length = stringPattern.length();
- boolean validCamelCase = true;
- boolean uppercase = false;
- for (int i=0; i<length && validCamelCase; i++) {
- char ch = stringPattern.charAt(i);
- validCamelCase = ScannerHelper.isJavaIdentifierStart(ch);
- // at least one uppercase character is need in CamelCase pattern
- // (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=136313)
- if (!uppercase) uppercase = ScannerHelper.isUpperCase(ch);
- }
- validCamelCase = validCamelCase && uppercase;
- // Verify bits compatibility
- if (validCamelCase) {
- if ((matchRule & R_PREFIX_MATCH) != 0) {
- if ((matchRule & R_CASE_SENSITIVE) != 0) {
- // This is equivalent to Camel Case match rule
- matchRule &= ~R_PREFIX_MATCH;
- matchRule &= ~R_CASE_SENSITIVE;
- }
- }
- } else {
- matchRule &= ~R_CAMELCASE_MATCH;
- if ((matchRule & R_PREFIX_MATCH) == 0) {
- matchRule |= R_PREFIX_MATCH;
- matchRule |= R_CASE_SENSITIVE;
- }
- }
- }
- return matchRule;
- }
-
-}
+package org.rubypeople.rdt.core.search;
+
+import org.rubypeople.rdt.core.IField;
+import org.rubypeople.rdt.core.IImportDeclaration;
+import org.rubypeople.rdt.core.IMember;
+import org.rubypeople.rdt.core.IMethod;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.internal.compiler.parser.ScannerHelper;
+import org.rubypeople.rdt.internal.core.LocalVariable;
+import org.rubypeople.rdt.internal.core.search.indexing.IIndexConstants;
+import org.rubypeople.rdt.internal.core.search.matching.ConstructorPattern;
+import org.rubypeople.rdt.internal.core.search.matching.FieldPattern;
+import org.rubypeople.rdt.internal.core.search.matching.InternalSearchPattern;
+import org.rubypeople.rdt.internal.core.search.matching.LocalVariablePattern;
+import org.rubypeople.rdt.internal.core.search.matching.MatchLocator;
+import org.rubypeople.rdt.internal.core.search.matching.MethodPattern;
+import org.rubypeople.rdt.internal.core.search.matching.OrPattern;
+import org.rubypeople.rdt.internal.core.search.matching.QualifiedTypeDeclarationPattern;
+import org.rubypeople.rdt.internal.core.search.matching.TypeDeclarationPattern;
+import org.rubypeople.rdt.internal.core.search.matching.TypeReferencePattern;
+import org.rubypeople.rdt.internal.core.util.CharOperation;
+
+public abstract class SearchPattern extends InternalSearchPattern {
+// Rules for pattern matching: (exact, prefix, pattern) [ | case sensitive]
+ /**
+ * Match rule: The search pattern matches exactly the search result,
+ * that is, the source of the search result equals the search pattern.
+ */
+ public static final int R_EXACT_MATCH = 0;
+
+ /**
+ * Match rule: The search pattern is a prefix of the search result.
+ */
+ public static final int R_PREFIX_MATCH = 0x0001;
+
+ /**
+ * Match rule: The search pattern contains one or more wild cards ('*' or '?').
+ * A '*' wild-card can replace 0 or more characters in the search result.
+ * A '?' wild-card replaces exactly 1 character in the search result.
+ */
+ public static final int R_PATTERN_MATCH = 0x0002;
+
+ /**
+ * Match rule: The search pattern contains a regular expression.
+ */
+ public static final int R_REGEXP_MATCH = 0x0004;
+
+ /**
+ * Match rule: The search pattern matches the search result only if cases are the same.
+ * Can be combined to previous rules, e.g. {@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE}
+ */
+ public static final int R_CASE_SENSITIVE = 0x0008;
+
+ /**
+ * Match rule: The search pattern matches search results as raw/parameterized types/methods with same erasure.
+ * This mode has no effect on other java elements search.<br>
+ * Type search example:
+ * <ul>
+ * <li>pattern: <code>List<Exception></code></li>
+ * <li>match: <code>List<Object></code></li>
+ * </ul>
+ * Method search example:
+ * <ul>
+ * <li>declaration: <code><T>foo(T t)</code></li>
+ * <li>pattern: <code><Exception>foo(new Exception())</code></li>
+ * <li>match: <code><Object>foo(new Object())</code></li>
+ * </ul>
+ * Can be combined to all other match rules, e.g. {@link #R_CASE_SENSITIVE} | {@link #R_ERASURE_MATCH}
+ * This rule is not activated by default, so raw types or parameterized types with same erasure will not be found
+ * for pattern List<String>,
+ * Note that with this pattern, the match selection will be only on the erasure even for parameterized types.
+ * @since 3.1
+ */
+ public static final int R_ERASURE_MATCH = 0x0010;
+
+ /**
+ * Match rule: The search pattern matches search results as raw/parameterized types/methods with equivalent type parameters.
+ * This mode has no effect on other java elements search.<br>
+ * Type search example:
+ * <ul>
+ * <li>pattern: <code>List<Exception></code></li>
+ * <li>match:
+ * <ul>
+ * <li><code>List<? extends Throwable></code></li>
+ * <li><code>List<? super RuntimeException></code></li>
+ * <li><code>List<?></code></li>
+ * </ul>
+ * </li>
+ * </ul>
+ * Method search example:
+ * <ul>
+ * <li>declaration: <code><T>foo(T t)</code></li>
+ * <li>pattern: <code><Exception>foo(new Exception())</code></li>
+ * <li>match:
+ * <ul>
+ * <li><code><? extends Throwable>foo(new Exception())</code></li>
+ * <li><code><? super RuntimeException>foo(new Exception())</code></li>
+ * <li><code>foo(new Exception())</code></li>
+ * </ul>
+ * </ul>
+ * Can be combined to all other match rules, e.g. {@link #R_CASE_SENSITIVE} | {@link #R_EQUIVALENT_MATCH}
+ * This rule is not activated by default, so raw types or equivalent parameterized types will not be found
+ * for pattern List<String>,
+ * This mode is overridden by {@link #R_ERASURE_MATCH} as erasure matches obviously include equivalent ones.
+ * That means that pattern with rule set to {@link #R_EQUIVALENT_MATCH} | {@link #R_ERASURE_MATCH}
+ * will return same results than rule only set with {@link #R_ERASURE_MATCH}.
+ * @since 3.1
+ */
+ public static final int R_EQUIVALENT_MATCH = 0x0020;
+
+ /**
+ * Match rule: The search pattern matches exactly the search result,
+ * that is, the source of the search result equals the search pattern.
+ * @since 3.1
+ */
+ public static final int R_FULL_MATCH = 0x0040;
+
+ /**
+ * Match rule: The search pattern contains a Camel Case expression.
+ * <br>
+ * Examples:
+ * <ul>
+ * <li><code>NPE</code> type string pattern will match
+ * <code>NullPointerException</code> and <code>NpPermissionException</code> types,</li>
+ * <li><code>NuPoEx</code> type string pattern will only match
+ * <code>NullPointerException</code> type.</li>
+ * </ul>
+ * @see CharOperation#camelCaseMatch(char[], char[]) for a detailed explanation
+ * of Camel Case matching.
+ *<br>
+ * Can be combined to {@link #R_PREFIX_MATCH} match rule. For example,
+ * when prefix match rule is combined with Camel Case match rule,
+ * <code>"nPE"</code> pattern will match <code>nPException</code>.
+ *<br>
+ * Match rule {@link #R_PATTERN_MATCH} may also be combined but both rules
+ * will not be used simultaneously as they are mutually exclusive.
+ * Used match rule depends on whether string pattern contains specific pattern
+ * characters (e.g. '*' or '?') or not. If it does, then only Pattern match rule
+ * will be used, otherwise only Camel Case match will be used.
+ * For example, with <code>"NPE"</code> string pattern, search will only use
+ * Camel Case match rule, but with <code>N*P*E*</code> string pattern, it will
+ * use only Pattern match rule.
+ *
+ * @since 3.2
+ */
+ public static final int R_CAMELCASE_MATCH = 0x0080;
+
+ private static final int MODE_MASK = R_EXACT_MATCH | R_PREFIX_MATCH | R_PATTERN_MATCH | R_REGEXP_MATCH;
+
+ private int matchRule;
+
+ /**
+ * Creates a search pattern with the rule to apply for matching index keys.
+ * It can be exact match, prefix...
[truncated message content] |
|
From: <caw...@us...> - 2007-05-15 16:35:38
|
Revision: 2477
http://svn.sourceforge.net/rubyeclipse/?rev=2477&view=rev
Author: cawilliams
Date: 2007-05-15 09:35:35 -0700 (Tue, 15 May 2007)
Log Message:
-----------
Modified Paths:
--------------
trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java 2007-05-15 16:34:48 UTC (rev 2476)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java 2007-05-15 16:35:35 UTC (rev 2477)
@@ -215,7 +215,7 @@
*/
public void start(BundleContext context) throws Exception {
super.start(context);
- Set<Gem> gems = GemManager.getInstance().getGems();
+ Set<Gem> gems = GemManager.getInstance().getGems(); // FIXME What if user has explicity disabled using ruby-debug?!
if (gems.isEmpty()) {
GemManager.getInstance().addGemListener(new GemListener() {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-15 16:34:49
|
Revision: 2476
http://svn.sourceforge.net/rubyeclipse/?rev=2476&view=rev
Author: cawilliams
Date: 2007-05-15 09:34:48 -0700 (Tue, 15 May 2007)
Log Message:
-----------
handle case where we already have the list of local gems
Modified Paths:
--------------
trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java 2007-05-15 16:33:08 UTC (rev 2475)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java 2007-05-15 16:34:48 UTC (rev 2476)
@@ -3,6 +3,7 @@
import java.io.File;
import java.io.IOException;
import java.net.URL;
+import java.util.Set;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
@@ -214,24 +215,30 @@
*/
public void start(BundleContext context) throws Exception {
super.start(context);
- GemManager.getInstance().addGemListener(new GemListener() {
+ Set<Gem> gems = GemManager.getInstance().getGems();
+ if (gems.isEmpty()) {
+ GemManager.getInstance().addGemListener(new GemListener() {
- public void gemsRefreshed() {
- boolean rubyDebugInstalled = GemManager.getInstance().gemInstalled("ruby-debug-ide");
- LaunchingPlugin.getDefault().getPluginPreferences().setValue(org.rubypeople.rdt.internal.launching.PreferenceConstants.USE_RUBY_DEBUG, rubyDebugInstalled);
- Job job = new RubyDebugGemListener(this);
- job.schedule();
- }
+ public void gemsRefreshed() {
+ boolean rubyDebugInstalled = GemManager.getInstance().gemInstalled("ruby-debug-ide");
+ LaunchingPlugin.getDefault().getPluginPreferences().setValue(org.rubypeople.rdt.internal.launching.PreferenceConstants.USE_RUBY_DEBUG, rubyDebugInstalled);
+ Job job = new RubyDebugGemListener(this);
+ job.schedule();
+ }
- public void gemRemoved(Gem gem) {
- // ignore
- }
+ public void gemRemoved(Gem gem) {
+ // ignore
+ }
- public void gemAdded(Gem gem) {
- // ignore
- }
+ public void gemAdded(Gem gem) {
+ // ignore
+ }
- });
+ });
+ } else {
+ boolean rubyDebugInstalled = GemManager.getInstance().gemInstalled("ruby-debug-ide");
+ LaunchingPlugin.getDefault().getPluginPreferences().setValue(org.rubypeople.rdt.internal.launching.PreferenceConstants.USE_RUBY_DEBUG, rubyDebugInstalled);
+ }
}
/*
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-15 16:33:12
|
Revision: 2475
http://svn.sourceforge.net/rubyeclipse/?rev=2475&view=rev
Author: cawilliams
Date: 2007-05-15 09:33:08 -0700 (Tue, 15 May 2007)
Log Message:
-----------
rename addGemObserver to addGemListener, add a removeGemListener method and an installedGem(name) query method.
Use these new methods to add a hook into the start method of plugin to set it to use ruby-debug as our debugger if the gem is installed
Modified Paths:
--------------
trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java
trunk/com.aptana.rdt/src/com/aptana/rdt/ui/gems/GemsView.java
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java 2007-05-14 19:15:03 UTC (rev 2474)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java 2007-05-15 16:33:08 UTC (rev 2475)
@@ -6,13 +6,19 @@
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
+import org.rubypeople.rdt.internal.launching.LaunchingPlugin;
import org.rubypeople.rdt.internal.ui.IRubyStatusConstants;
+import com.aptana.rdt.internal.gems.Gem;
+import com.aptana.rdt.internal.gems.GemManager;
+import com.aptana.rdt.internal.gems.GemManager.GemListener;
import com.aptana.rdt.internal.ui.RubyRedMessages;
/**
@@ -184,14 +190,48 @@
super();
plugin = this;
}
+
+ private static class RubyDebugGemListener extends Job {
+ private GemListener listener;
+
+ public RubyDebugGemListener(GemListener listener) {
+ super("Removing temporary gem listener");
+ this.listener = listener;
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ GemManager.getInstance().removeGemListener(listener);
+ return Status.OK_STATUS;
+ }
+
+ }
+
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
+ GemManager.getInstance().addGemListener(new GemListener() {
+ public void gemsRefreshed() {
+ boolean rubyDebugInstalled = GemManager.getInstance().gemInstalled("ruby-debug-ide");
+ LaunchingPlugin.getDefault().getPluginPreferences().setValue(org.rubypeople.rdt.internal.launching.PreferenceConstants.USE_RUBY_DEBUG, rubyDebugInstalled);
+ Job job = new RubyDebugGemListener(this);
+ job.schedule();
+ }
+
+ public void gemRemoved(Gem gem) {
+ // ignore
+ }
+
+ public void gemAdded(Gem gem) {
+ // ignore
+ }
+
+ });
}
/*
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java 2007-05-14 19:15:03 UTC (rev 2474)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java 2007-05-15 16:33:08 UTC (rev 2475)
@@ -531,7 +531,7 @@
return false;
}
- public void addGemObserver(GemListener listener) {
+ public void addGemListener(GemListener listener) {
listeners.add(listener);
}
@@ -556,4 +556,16 @@
}
return Collections.unmodifiableSortedSet(logical);
}
+
+ public boolean gemInstalled(String gemName) {
+ Set<Gem> gems = getGems();
+ for (Gem gem : gems) {
+ if (gem.getName().equalsIgnoreCase(gemName)) return true;
+ }
+ return false;
+ }
+
+ public void removeGemListener(GemListener listener) {
+ listeners.remove(listener);
+ }
}
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/ui/gems/GemsView.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/ui/gems/GemsView.java 2007-05-14 19:15:03 UTC (rev 2474)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/ui/gems/GemsView.java 2007-05-15 16:33:08 UTC (rev 2475)
@@ -58,7 +58,7 @@
gemViewer.setInput(GemManager.getInstance().getGems());
createPopupMenu();
- GemManager.getInstance().addGemObserver(this);
+ GemManager.getInstance().addGemListener(this);
}
@Override
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-14 19:15:08
|
Revision: 2474
http://svn.sourceforge.net/rubyeclipse/?rev=2474&view=rev
Author: cawilliams
Date: 2007-05-14 12:15:03 -0700 (Mon, 14 May 2007)
Log Message:
-----------
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/ISourceElementRequestor.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyMethod.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyMethodElementInfo.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyScriptStructureBuilder.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyTypeElementInfo.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/SourceParser.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/SourceIndexerRequestor.java
Removed Paths:
-------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubySingletonMethod.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/ISourceElementRequestor.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/ISourceElementRequestor.java 2007-05-14 17:58:42 UTC (rev 2473)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/ISourceElementRequestor.java 2007-05-14 19:15:03 UTC (rev 2474)
@@ -54,4 +54,7 @@
public void acceptUnknownReference(String name, int startOffset, int endOffset);
public void acceptProblem(CategorizedProblem problem);
public void acceptMixin(String string);
+
+ public void acceptModuleFunction(String function);
+ public void acceptMethodVisibilityChange(String methodName, int visibility);
}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyMethod.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyMethod.java 2007-05-14 17:58:42 UTC (rev 2473)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyMethod.java 2007-05-14 19:15:03 UTC (rev 2474)
@@ -27,6 +27,7 @@
import org.rubypeople.rdt.core.IMethod;
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.internal.core.util.Util;
@@ -111,7 +112,24 @@
}
public boolean isSingleton() {
- return isConstructor();
+ try {
+ RubyMethodElementInfo info = (RubyMethodElementInfo) getElementInfo();
+ return info.isSingleton();
+ } catch (RubyModelException e) {
+ RubyCore.log(e);
+ }
+ return isConstructor();
}
+ public static RubyMethod singleton(RubyElement currentType, String name, String[] parameterNames2) {
+ RubyMethod method = new RubyMethod(currentType, name, parameterNames2);
+ try {
+ RubyMethodElementInfo info = (RubyMethodElementInfo) method.getElementInfo();
+ info.setIsSingleton(true);
+ } catch (RubyModelException e) {
+ RubyCore.log(e);
+ }
+ return method;
+ }
+
}
\ No newline at end of file
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyMethodElementInfo.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyMethodElementInfo.java 2007-05-14 17:58:42 UTC (rev 2473)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyMethodElementInfo.java 2007-05-14 19:15:03 UTC (rev 2474)
@@ -27,6 +27,7 @@
* parameters.
*/
protected String[] argumentNames;
+ private boolean isSingleton;
public String[] getArgumentNames() {
return this.argumentNames;
@@ -56,4 +57,12 @@
protected void setArgumentNames(String[] names) {
this.argumentNames = names;
}
+
+ protected void setIsSingleton(boolean b) {
+ isSingleton = b;
+ }
+
+ public boolean isSingleton() {
+ return isSingleton || isConstructor();
+ }
}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyScriptStructureBuilder.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyScriptStructureBuilder.java 2007-05-14 17:58:42 UTC (rev 2473)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyScriptStructureBuilder.java 2007-05-14 19:15:03 UTC (rev 2474)
@@ -32,6 +32,7 @@
import java.util.List;
import java.util.Map;
+import org.rubypeople.rdt.core.IMethod;
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.IRubyScript;
import org.rubypeople.rdt.core.RubyCore;
@@ -226,12 +227,7 @@
}
public void enterMethod(MethodInfo methodInfo) {
- RubyMethod method;
- if (methodInfo.isClassLevel) {
- method = new RubySingletonMethod(getCurrentType(), methodInfo.name, methodInfo.parameterNames);
- } else {
- method = new RubyMethod(getCurrentType(), methodInfo.name, methodInfo.parameterNames);
- }
+ RubyMethod method = new RubyMethod(getCurrentType(), methodInfo.name, methodInfo.parameterNames);
modelStack.push(method);
infoStack.peek().addChild(method);
@@ -242,6 +238,7 @@
info.setNameSourceStart(methodInfo.nameSourceStart);
info.setNameSourceEnd(methodInfo.nameSourceEnd);
info.setSourceRangeStart(methodInfo.declarationStart);
+ info.setIsSingleton(methodInfo.isClassLevel);
infoStack.push(info);
newElements.put(method, info);
}
@@ -331,4 +328,43 @@
parentType.setIncludedModuleNames(newIncludedModuleNames);
}
+ public void acceptMethodVisibilityChange(String methodName, int visibility) {
+ RubyElementInfo info = getCurrentTypeInfo();
+ if (!(info instanceof RubyTypeElementInfo)) return;
+ RubyTypeElementInfo parentType = (RubyTypeElementInfo) info;
+
+ IMethod[] methods = parentType.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ RubyMethod method = (RubyMethod) methods[i];
+ if (!method.getElementName().equals(methodName)) continue;;
+ try {
+ RubyMethodElementInfo methodInfo = (RubyMethodElementInfo) method.getElementInfo();
+ methodInfo.setVisibility(visibility);
+ return;
+ } catch (RubyModelException e) {
+ RubyCore.log(e);
+ }
+ }
+ }
+
+ public void acceptModuleFunction(String methodName) {
+ RubyElementInfo info = getCurrentTypeInfo();
+ if (!(info instanceof RubyTypeElementInfo)) return;
+ RubyTypeElementInfo parentType = (RubyTypeElementInfo) info;
+
+ IMethod[] methods = parentType.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ RubyMethod method = (RubyMethod) methods[i];
+ if (!method.getElementName().equals(methodName)) continue;
+ try {
+ RubyMethodElementInfo methodInfo = (RubyMethodElementInfo) method.getElementInfo();
+ methodInfo.setIsSingleton(true);
+ return;
+ } catch (RubyModelException e) {
+ RubyCore.log(e);
+ }
+ }
+
+ }
+
}
\ No newline at end of file
Deleted: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubySingletonMethod.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubySingletonMethod.java 2007-05-14 17:58:42 UTC (rev 2473)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubySingletonMethod.java 2007-05-14 19:15:03 UTC (rev 2474)
@@ -1,47 +0,0 @@
-/*
- * Created on Jul 10, 2005
- *
- * TODO To change the template for this generated file go to
- * Window - Preferences - Java - Code Style - Code Templates
- */
-package org.rubypeople.rdt.internal.core;
-
-/**
- * RubySingletonMethod represents a singleton method in ruby. Example:
- * [code]
- * class A
- * def self.method1
- * end
- *
- * def A.method2
- * end
- *
- * class << self
- * def method3
- * end
- * end
- * end
- * [/code]
- *
- * @author zdennis
- */
-public class RubySingletonMethod extends RubyMethod {
-
- /**
- * @param parent
- * @param name
- * @param parameterNames
- */
- public RubySingletonMethod(RubyElement parent, String name, String[] parameterNames) {
- super(parent, name, parameterNames);
- }
-
- public boolean isSingleton() {
- return true;
- }
-
- public String getElementName() {
- return parent.getElementName() + "." + this.name;
- }
-
-}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyTypeElementInfo.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyTypeElementInfo.java 2007-05-14 17:58:42 UTC (rev 2473)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyTypeElementInfo.java 2007-05-14 19:15:03 UTC (rev 2474)
@@ -195,19 +195,20 @@
* @see IType
*/
public IMethod[] getMethods() {
- RubyMethod[] methodHandles = getMethodHandles();
- int length = methodHandles.length;
- IMethod[] methods = new IMethod[length];
- int methodIndex = 0;
- for (int i = 0; i < length; i++) {
- try {
- IMethod method = (IMethod) methodHandles[i].getElementInfo();
- methods[methodIndex++] = method;
- } catch (RubyModelException e) {
- // ignore
- }
- }
- return methods;
+ return getMethodHandles();
+// RubyMethod[] methodHandles = getMethodHandles();
+// int length = methodHandles.length;
+// IMethod[] methods = new IMethod[length];
+// int methodIndex = 0;
+// for (int i = 0; i < length; i++) {
+// try {
+// IMethod method = (IMethod) methodHandles[i].getElementInfo();
+// methods[methodIndex++] = method;
+// } catch (RubyModelException e) {
+// // ignore
+// }
+// }
+// return methods;
}
public RubyMethod[] getMethodHandles() {
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/SourceParser.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/SourceParser.java 2007-05-14 17:58:42 UTC (rev 2473)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/SourceParser.java 2007-05-14 19:15:03 UTC (rev 2474)
@@ -24,6 +24,7 @@
*/
package org.rubypeople.rdt.internal.core;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -31,6 +32,7 @@
import org.jruby.ast.AliasNode;
import org.jruby.ast.ArrayNode;
import org.jruby.ast.AssignableNode;
+import org.jruby.ast.CallNode;
import org.jruby.ast.ClassNode;
import org.jruby.ast.ClassVarAsgnNode;
import org.jruby.ast.Colon2Node;
@@ -42,6 +44,7 @@
import org.jruby.ast.DefsNode;
import org.jruby.ast.FCallNode;
import org.jruby.ast.GlobalAsgnNode;
+import org.jruby.ast.IArgumentNode;
import org.jruby.ast.InstAsgnNode;
import org.jruby.ast.IterNode;
import org.jruby.ast.LocalAsgnNode;
@@ -70,6 +73,7 @@
*/
public class SourceParser extends InOrderVisitor { // TODO Rename to SourceElementParser
+ private static final String MODULE_FUNCTION = "module_function";
private static final String EMPTY_STRING = "";
private static final String PROTECTED = "protected";
private static final String PRIVATE = "private";
@@ -85,6 +89,7 @@
private Visibility currentVisibility = Visibility.PUBLIC;
private boolean inSingletonClass;
public ISourceElementRequestor requestor;
+ private boolean inModuleFunction;
/**
*
@@ -148,6 +153,7 @@
Instruction ins = super.visitModuleNode(iVisited);
requestor.exitType(iVisited.getPosition().getEndOffset() - 1);
+ inModuleFunction = false;
return ins;
}
@@ -165,7 +171,7 @@
} else {
methodInfo.isConstructor = false;
}
- methodInfo.isClassLevel = inSingletonClass;
+ methodInfo.isClassLevel = inSingletonClass || inModuleFunction;
methodInfo.visibility = convertVisibility(visibility);
methodInfo.parameterNames = ASTUtil.getArgs(iVisited.getArgsNode(), iVisited.getScope());
@@ -342,11 +348,31 @@
}
public Instruction visitFCallNode(FCallNode iVisited) {
- String functionName = iVisited.getName();
- if (functionName.equals(REQUIRE) || functionName.equals(LOAD)) {
+ String name = iVisited.getName();
+ if (name.equals(REQUIRE) || name.equals(LOAD)) {
addImport(iVisited);
- } else if (functionName.equals(INCLUDE)) { // Collect included mixins
+ } else if (name.equals(INCLUDE)) { // Collect included mixins
includeModule(iVisited);
+ } if (name.equals(PUBLIC)) {
+ List<String> arguments = getArgumentsFromFunctionCall(iVisited);
+ for (String methodName : arguments) {
+ requestor.acceptMethodVisibilityChange(methodName, convertVisibility(Visibility.PUBLIC));
+ }
+ } else if (name.equals(PRIVATE)) {
+ List<String> arguments = getArgumentsFromFunctionCall(iVisited);
+ for (String methodName : arguments) {
+ requestor.acceptMethodVisibilityChange(methodName, convertVisibility(Visibility.PRIVATE));
+ }
+ } else if (name.equals(PROTECTED)) {
+ List<String> arguments = getArgumentsFromFunctionCall(iVisited);
+ for (String methodName : arguments) {
+ requestor.acceptMethodVisibilityChange(methodName, convertVisibility(Visibility.PROTECTED));
+ }
+ } else if (name.equals(MODULE_FUNCTION)) {
+ List<String> arguments = getArgumentsFromFunctionCall(iVisited);
+ for (String methodName : arguments) {
+ requestor.acceptModuleFunction(methodName);
+ }
}
return super.visitFCallNode(iVisited);
}
@@ -417,10 +443,57 @@
currentVisibility = Visibility.PRIVATE;
} else if (functionName.equals(PROTECTED)) {
currentVisibility = Visibility.PROTECTED;
+ } else if (functionName.equals(MODULE_FUNCTION)) {
+ inModuleFunction = true;
}
return super.visitVCallNode(iVisited);
}
+ @Override
+ public Instruction visitCallNode(CallNode iVisited) {
+ String name = iVisited.getName();
+ if (name.equals(PUBLIC)) {
+ List<String> arguments = getArgumentsFromFunctionCall(iVisited);
+ for (String methodName : arguments) {
+ requestor.acceptMethodVisibilityChange(methodName, convertVisibility(Visibility.PUBLIC));
+ }
+ } else if (name.equals(PRIVATE)) {
+ List<String> arguments = getArgumentsFromFunctionCall(iVisited);
+ for (String methodName : arguments) {
+ requestor.acceptMethodVisibilityChange(methodName, convertVisibility(Visibility.PRIVATE));
+ }
+ } else if (name.equals(PROTECTED)) {
+ List<String> arguments = getArgumentsFromFunctionCall(iVisited);
+ for (String methodName : arguments) {
+ requestor.acceptMethodVisibilityChange(methodName, convertVisibility(Visibility.PROTECTED));
+ }
+ } else if (name.equals(MODULE_FUNCTION)) {
+ List<String> arguments = getArgumentsFromFunctionCall(iVisited);
+ for (String methodName : arguments) {
+ requestor.acceptModuleFunction(methodName);
+ }
+ }
+ return super.visitCallNode(iVisited);
+ }
+
+ private List<String> getArgumentsFromFunctionCall(IArgumentNode iVisited) {
+ List<String> arguments = new ArrayList<String>();
+ Node argsNode = iVisited.getArgsNode();
+ Iterator iter = null;
+ if (argsNode instanceof SplatNode) {
+ SplatNode splat = (SplatNode) argsNode;
+ iter = splat.childNodes().iterator();
+ } else if (argsNode instanceof ArrayNode) {
+ ArrayNode arrayNode = (ArrayNode) iVisited.getArgsNode();
+ iter = arrayNode.childNodes().iterator();
+ }
+ for (; iter.hasNext();) {
+ Node mixinNameNode = (Node) iter.next();
+ arguments.add(ASTUtil.getNameReflectively(mixinNameNode));
+ }
+ return arguments;
+ }
+
public Instruction visitAliasNode(AliasNode iVisited) {
String name = iVisited.getNewName();
MethodInfo method = new MethodInfo();
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/SourceIndexerRequestor.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/SourceIndexerRequestor.java 2007-05-14 17:58:42 UTC (rev 2473)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/SourceIndexerRequestor.java 2007-05-14 19:15:03 UTC (rev 2474)
@@ -118,4 +118,14 @@
typeStack.pop();
}
+ public void acceptMethodVisibilityChange(String methodName, int visibility) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void acceptModuleFunction(String function) {
+ // TODO Auto-generated method stub
+
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-05-14 17:58:46
|
Revision: 2473
http://svn.sourceforge.net/rubyeclipse/?rev=2473&view=rev
Author: cawilliams
Date: 2007-05-14 10:58:42 -0700 (Mon, 14 May 2007)
Log Message:
-----------
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyAbstractEditor.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-05-14 13:32:09 UTC (rev 2472)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyAbstractEditor.java 2007-05-14 17:58:42 UTC (rev 2473)
@@ -253,7 +253,7 @@
}
protected ISourceViewer createRubySourceViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, boolean isOverviewRulerVisible, int styles, IPreferenceStore store) {
- return new RubySourceViewer(parent, verticalRuler, overviewRuler,
+ return new AdaptedSourceViewer(parent, verticalRuler, overviewRuler,
isOverviewRulerVisible, styles, store);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|