|
From: <caw...@us...> - 2007-07-10 17:11:48
|
Revision: 2739
http://svn.sourceforge.net/rubyeclipse/?rev=2739&view=rev
Author: cawilliams
Date: 2007-07-10 10:11:46 -0700 (Tue, 10 Jul 2007)
Log Message:
-----------
improve code completion at top-level
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/CompletionProposal.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyType.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/preferences/MembersOrderPreferencePage.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/CompletionProposalLabelProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyScriptCompletion.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/viewsupport/RubyElementImageProvider.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/CompletionProposal.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/CompletionProposal.java 2007-07-10 16:22:43 UTC (rev 2738)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/CompletionProposal.java 2007-07-10 17:11:46 UTC (rev 2739)
@@ -2,17 +2,20 @@
public class CompletionProposal {
- public static final int FIELD_REF = 2;
+ public static final int GLOBAL_REF = 1;
+ public static final int CONSTANT_REF = 2;
public static final int KEYWORD = 3;
+ public static final int INSTANCE_VARIABLE_REF = 4;
public static final int LOCAL_VARIABLE_REF = 5;
public static final int METHOD_REF = 6;
public static final int METHOD_DECLARATION = 7;
+ public static final int CLASS_VARIABLE_REF = 8;
public static final int TYPE_REF = 9;
public static final int VARIABLE_DECLARATION = 10;
public static final int POTENTIAL_METHOD_DECLARATION = 11;
public static final int METHOD_NAME_REFERENCE = 12;
- protected static final int FIRST_KIND = FIELD_REF;
+ protected static final int FIRST_KIND = GLOBAL_REF;
protected static final int LAST_KIND = METHOD_NAME_REFERENCE;
/**
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-10 16:22:43 UTC (rev 2738)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-10 17:11:46 UTC (rev 2739)
@@ -140,18 +140,7 @@
});
for (Node typeNode : typeNodes) {
- List<Node> methods = ScopedNodeLocator.Instance().findNodesInScope(typeNode, new INodeAcceptor() {
-
- public boolean doesAccept(Node node) {
- return (node instanceof DefnNode) || (node instanceof DefsNode);
- }
-
- });
- for (Node methodNode : methods) {
- MethodDefNode methodDef = (MethodDefNode) methodNode;
- NodeMethod method = new NodeMethod(methodDef);
- list.add(suggestMethod(method, name, 100));
- }
+ list.addAll(addASTMethodsInScope(typeNode, name));
}
}
IType[] types = requestor.findType(name);
@@ -181,6 +170,28 @@
fContext = null;
}
+ private Collection<CompletionProposal> addASTMethodsInScope(Node typeNode, String name) {
+ List<CompletionProposal> list = new ArrayList<CompletionProposal>();
+ if (typeNode == null) return list;
+ List<Node> methods = ScopedNodeLocator.Instance().findNodesInScope(typeNode, new INodeAcceptor() {
+
+ public boolean doesAccept(Node node) {
+ return (node instanceof DefnNode) || (node instanceof DefsNode);
+ }
+
+ });
+ for (Node methodNode : methods) {
+ Node scoping = findNearestScope(typeNode, methodNode.getPosition().getStartOffset() - 1);
+ if (!scoping.equals(typeNode)) continue;
+ MethodDefNode methodDef = (MethodDefNode) methodNode;
+ NodeMethod method = new NodeMethod(methodDef);
+ CompletionProposal proposal = suggestMethod(method, name, 100);
+ if (proposal == null) continue;
+ list.add(proposal);
+ }
+ return list;
+ }
+
private Map<String, CompletionProposal> suggestTypesConstants(IType type) throws RubyModelException {
Map<String, CompletionProposal> proposals = new HashMap<String, CompletionProposal>();
SearchPattern pattern = SearchPattern.createPattern(IRubyElement.CONSTANT, "*", IRubySearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH);
@@ -190,7 +201,7 @@
IRubyElement element = (IRubyElement) match.getElement();
if (element.getElementType() != IRubyElement.CONSTANT) continue; // XXX we shouldn't have to do this
// Add proposal
- CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.FIELD_REF, element.getElementName());
+ CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.CONSTANT_REF, element.getElementName());
proposal.setType(type.getFullyQualifiedName());
proposal.setName(element.getElementName());
proposals.put(element.getElementName(), proposal);
@@ -249,19 +260,31 @@
private void suggestMethodsForEnclosingType(IRubyScript script) throws RubyModelException {
IMember element = (IMember) script.getElementAt(fContext.getOffset());
- IType type = null;
+ boolean includeInstance = !fContext.inTypeDefinition();
+ IType[] types;
if (element == null) {
// We're in the top level, so we're in "Object"
RubyElementRequestor requestor = new RubyElementRequestor(script);
- IType[] types = requestor.findType(OBJECT);
- if (types != null && types.length > 0) type = types[0];
+ IType[] tmpTypes = requestor.findType(OBJECT);
+ List<IType> filtered = new ArrayList<IType>();
+ for (int i = 0; i < tmpTypes.length; i++) {
+ // FIXME We shouldn't be getting these types with bad fully qualified names anyhow, should we?
+ if (!tmpTypes[i].getFullyQualifiedName().equals(OBJECT)) continue;
+ filtered.add(tmpTypes[i]);
+ }
+ types = filtered.toArray(new IType[filtered.size()]);
+ includeInstance = false;
} else if (element instanceof IType) {
- type = (IType) element;
+ types = new IType[] {(IType) element};
} else {
- type = element.getDeclaringType();
+ types = new IType[] {element.getDeclaringType()};
}
- if (type == null) return;
- List<CompletionProposal> list = sort(suggestMethods(100, type, !fContext.inTypeDefinition()));
+ if (types == null || types.length < 1) return;
+ Map<String, CompletionProposal> map = new HashMap<String, CompletionProposal>();
+ for (int i = 0; i < types.length; i++) {
+ map.putAll(suggestMethods(100, types[i], includeInstance));
+ }
+ List<CompletionProposal> list = sort(map);
for (CompletionProposal proposal : list) {
fRequestor.accept(proposal);
}
@@ -300,7 +323,7 @@
String name = element.getElementName();
if (!fContext.prefixStartsWith(name))
continue;
- CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.FIELD_REF, name);
+ CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.CONSTANT_REF, name);
proposal.setType(name);
fRequestor.accept(proposal);
}
@@ -349,7 +372,7 @@
String name = element.getElementName();
if (!fContext.prefixStartsWith(name))
continue;
- CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.FIELD_REF, name);
+ CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.CONSTANT_REF, name);
proposal.setType(name);
fRequestor.accept(proposal);
}
@@ -487,24 +510,37 @@
return;
}
- // XXX Just find enclosing scope and grab variables?
- Node enclosingNode = ClosestSpanningNodeLocator.Instance().findClosestSpanner(rootNode, fContext.getOffset(), new INodeAcceptor() {
- public boolean doesAccept(Node node) {
- return (node instanceof DefnNode || node instanceof DefsNode || node instanceof ClassNode || node instanceof ModuleNode || node instanceof RootNode);
- }
- });
-
+ // Grab enclosing scope
+ Node enclosingNode = findNearestScope(rootNode, fContext.getOffset());
+ if (enclosingNode == null) enclosingNode = rootNode;
+ // Add variables in this scope
Collection<String> variables = addVariablesinScope(getScope(enclosingNode));
for (String variable : variables) {
- CompletionProposal proposal = new CompletionProposal(CompletionProposal.LOCAL_VARIABLE_REF, variable, 100);
+ int type = CompletionProposal.LOCAL_VARIABLE_REF;
+ if (variable.startsWith("$")) {
+ type = CompletionProposal.GLOBAL_REF;
+ }
+ CompletionProposal proposal = new CompletionProposal(type, variable, 100);
proposal.setReplaceRange(fContext.getReplaceStart(), fContext.getReplaceStart() + variable.length());
fRequestor.accept(proposal);
}
+ // Add methods in this scope
+ Node enclosingTypeNode = ClosestSpanningNodeLocator.Instance().findClosestSpanner(rootNode, fContext.getOffset(), new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ return (node instanceof ClassNode || node instanceof ModuleNode || node instanceof RootNode);
+ }
+ });
+ if (enclosingTypeNode == null) enclosingTypeNode = rootNode;
+ Collection<CompletionProposal> methodProposals = addASTMethodsInScope(enclosingTypeNode, "");
+ for (CompletionProposal proposal : methodProposals) {
+ if (proposal == null) continue;
+ fRequestor.accept(proposal);
+ }
// Find the enclosing type (class or module) to get instance and
// classvars from
- Node enclosingTypeNode = ClosestSpanningNodeLocator.Instance().findClosestSpanner(rootNode, fContext.getOffset(), new INodeAcceptor() {
+ enclosingTypeNode = ClosestSpanningNodeLocator.Instance().findClosestSpanner(rootNode, fContext.getOffset(), new INodeAcceptor() {
public boolean doesAccept(Node node) {
return (node instanceof ClassNode || node instanceof ModuleNode);
}
@@ -523,6 +559,14 @@
}
}
+ private Node findNearestScope(Node scopeNode, int offset) {
+ return ClosestSpanningNodeLocator.Instance().findClosestSpanner(scopeNode, offset, new INodeAcceptor() {
+ public boolean doesAccept(Node node) {
+ return (node instanceof DefnNode || node instanceof DefsNode || node instanceof ClassNode || node instanceof ModuleNode || node instanceof RootNode);
+ }
+ });
+ }
+
private Set<String> addVariablesinScope(StaticScope scope) {
Set<String> matches = new HashSet<String>();
if (scope == null) return matches;
@@ -538,6 +582,7 @@
}
private StaticScope getScope(Node enclosingNode) {
+ if (enclosingNode == null) return ((RootNode)fContext.getRootNode()).getStaticScope();
if (enclosingNode instanceof RootNode) {
RootNode root = (RootNode) enclosingNode;
return root.getStaticScope();
@@ -643,7 +688,7 @@
fields.add(attr);
}
for (String field : fields) {
- CompletionProposal proposal = new CompletionProposal(CompletionProposal.FIELD_REF, field, 100);
+ CompletionProposal proposal = new CompletionProposal(CompletionProposal.CONSTANT_REF, field, 100);
proposal.setReplaceRange(fContext.getReplaceStart(), fContext.getReplaceStart() + field.length());
fRequestor.accept(proposal);
}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyType.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyType.java 2007-07-10 16:22:43 UTC (rev 2738)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyType.java 2007-07-10 17:11:46 UTC (rev 2739)
@@ -61,9 +61,13 @@
/**
* @see IType
*/
- public String[] getIncludedModuleNames() throws RubyModelException {
+ public String[] getIncludedModuleNames() throws RubyModelException {
RubyTypeElementInfo info = (RubyTypeElementInfo) getElementInfo();
- return info.getIncludedModuleNames();
+ String[] modules = info.getIncludedModuleNames();
+ if (modules == null || modules.length == 0 && getFullyQualifiedName().equals("Object")) {
+ return new String[] {"Kernel"};
+ }
+ return modules;
}
/**
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/preferences/MembersOrderPreferencePage.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/preferences/MembersOrderPreferencePage.java 2007-07-10 16:22:43 UTC (rev 2738)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/preferences/MembersOrderPreferencePage.java 2007-07-10 17:11:46 UTC (rev 2739)
@@ -281,7 +281,7 @@
String s= (String) element;
if (s.equals(FIELDS)) {
//0 will give the default field image
- descriptor= RubyElementImageProvider.getFieldImageDescriptor();
+ descriptor= RubyElementImageProvider.getConstantImageDescriptor();
} else if (s.equals(CONSTRUCTORS)) {
descriptor= RubyElementImageProvider.getMethodImageDescriptor(visibility);
//add a constructor adornment to the image descriptor
@@ -289,7 +289,7 @@
} else if (s.equals(METHODS)) {
descriptor= RubyElementImageProvider.getMethodImageDescriptor(visibility);
} else if (s.equals(STATIC_FIELDS)) {
- descriptor= RubyElementImageProvider.getFieldImageDescriptor();
+ descriptor= RubyElementImageProvider.getConstantImageDescriptor();
//add a static fields adornment to the image descriptor
descriptor= new RubyElementImageDescriptor(descriptor, RubyElementImageDescriptor.STATIC, RubyElementImageProvider.SMALL_SIZE);
} else if (s.equals(STATIC_METHODS)) {
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/CompletionProposalLabelProvider.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/CompletionProposalLabelProvider.java 2007-07-10 16:22:43 UTC (rev 2738)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/CompletionProposalLabelProvider.java 2007-07-10 17:11:46 UTC (rev 2739)
@@ -53,9 +53,18 @@
descriptor = RubyElementImageProvider.getTypeImageDescriptor(
false, false, false);
break;
- case CompletionProposal.FIELD_REF:
- descriptor = RubyElementImageProvider.getFieldImageDescriptor();
+ case CompletionProposal.CONSTANT_REF:
+ descriptor = RubyElementImageProvider.getConstantImageDescriptor();
break;
+ case CompletionProposal.GLOBAL_REF:
+ descriptor = RubyElementImageProvider.getGlobalVariableImageDescriptor();
+ break;
+ case CompletionProposal.INSTANCE_VARIABLE_REF:
+ descriptor = RubyElementImageProvider.getInstanceVariableImageDescriptor();
+ break;
+ case CompletionProposal.CLASS_VARIABLE_REF:
+ descriptor = RubyElementImageProvider.getClassVariableImageDescriptor();
+ break;
case CompletionProposal.LOCAL_VARIABLE_REF:
case CompletionProposal.VARIABLE_DECLARATION:
descriptor = RubyPluginImages.DESC_OBJS_LOCAL_VAR;
@@ -87,7 +96,7 @@
int flags= proposal.getFlags();
int kind= proposal.getKind();
- if (kind == CompletionProposal.FIELD_REF || kind == CompletionProposal.METHOD_DECLARATION || kind == CompletionProposal.METHOD_DECLARATION || kind == CompletionProposal.METHOD_NAME_REFERENCE || kind == CompletionProposal.METHOD_REF)
+ if (kind == CompletionProposal.CONSTANT_REF || kind == CompletionProposal.METHOD_DECLARATION || kind == CompletionProposal.METHOD_DECLARATION || kind == CompletionProposal.METHOD_NAME_REFERENCE || kind == CompletionProposal.METHOD_REF)
if (Flags.isStatic(flags))
adornments |= RubyElementImageDescriptor.STATIC;
@@ -104,7 +113,10 @@
// return createOverrideMethodProposalLabel(proposal);
case CompletionProposal.TYPE_REF:
return createTypeProposalLabel(proposal);
- case CompletionProposal.FIELD_REF:
+ case CompletionProposal.CONSTANT_REF:
+ case CompletionProposal.CLASS_VARIABLE_REF:
+ case CompletionProposal.INSTANCE_VARIABLE_REF:
+ case CompletionProposal.GLOBAL_REF:
case CompletionProposal.LOCAL_VARIABLE_REF:
case CompletionProposal.VARIABLE_DECLARATION:
case CompletionProposal.METHOD_DECLARATION:
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyScriptCompletion.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyScriptCompletion.java 2007-07-10 16:22:43 UTC (rev 2738)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyScriptCompletion.java 2007-07-10 17:11:46 UTC (rev 2739)
@@ -131,7 +131,9 @@
return baseRelevance + 4;
case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
return baseRelevance + 4 /* + 99 */;
- case CompletionProposal.FIELD_REF:
+ case CompletionProposal.CONSTANT_REF:
+ case CompletionProposal.CLASS_VARIABLE_REF:
+ case CompletionProposal.INSTANCE_VARIABLE_REF:
return baseRelevance + 5;
case CompletionProposal.LOCAL_VARIABLE_REF:
case CompletionProposal.VARIABLE_DECLARATION:
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/viewsupport/RubyElementImageProvider.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/viewsupport/RubyElementImageProvider.java 2007-07-10 16:22:43 UTC (rev 2738)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/viewsupport/RubyElementImageProvider.java 2007-07-10 17:11:46 UTC (rev 2739)
@@ -301,8 +301,19 @@
return RubyPluginImages.DESC_OBJS_MODULE;
}
- public static ImageDescriptor getFieldImageDescriptor() {
- // TODO What about other types of fields!
+ public static ImageDescriptor getConstantImageDescriptor() {
+ return RubyPluginImages.DESC_OBJS_CONSTANT;
+ }
+
+ public static ImageDescriptor getClassVariableImageDescriptor() {
return RubyPluginImages.DESC_OBJS_CLASS_VAR;
}
+
+ public static ImageDescriptor getInstanceVariableImageDescriptor() {
+ return RubyPluginImages.DESC_OBJS_INSTANCE_VAR;
+ }
+
+ public static ImageDescriptor getGlobalVariableImageDescriptor() {
+ return RubyPluginImages.DESC_OBJS_GLOBAL;
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|