|
From: <caw...@us...> - 2007-08-21 19:15:41
|
Revision: 3031
http://rubyeclipse.svn.sourceforge.net/rubyeclipse/?rev=3031&view=rev
Author: cawilliams
Date: 2007-08-21 12:15:40 -0700 (Tue, 21 Aug 2007)
Log Message:
-----------
fix for #5628 - Add quick fix for Comparable inclusion missing <=>
Also add a task marker to method stubs
Modified Paths:
--------------
trunk/com.aptana.rdt.ui/src/com/aptana/rdt/internal/ui/text/correction/QuickFixProcessor.java
trunk/com.aptana.rdt.ui/src/com/aptana/rdt/ui/AptanaRDTUIPlugin.java
Modified: trunk/com.aptana.rdt.ui/src/com/aptana/rdt/internal/ui/text/correction/QuickFixProcessor.java
===================================================================
--- trunk/com.aptana.rdt.ui/src/com/aptana/rdt/internal/ui/text/correction/QuickFixProcessor.java 2007-08-21 18:24:14 UTC (rev 3030)
+++ trunk/com.aptana.rdt.ui/src/com/aptana/rdt/internal/ui/text/correction/QuickFixProcessor.java 2007-08-21 19:15:40 UTC (rev 3031)
@@ -6,13 +6,17 @@
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
+import org.jruby.ast.BlockNode;
import org.jruby.ast.ClassNode;
+import org.jruby.ast.CommentNode;
import org.jruby.ast.DefnNode;
+import org.jruby.ast.InstAsgnNode;
import org.jruby.ast.ModuleNode;
import org.jruby.ast.Node;
import org.jruby.ast.visitor.rewriter.DefaultFormatHelper;
import org.jruby.ast.visitor.rewriter.FormatHelper;
import org.jruby.ast.visitor.rewriter.ReWriteVisitor;
+import org.jruby.lexer.yacc.IDESourcePosition;
import org.rubypeople.rdt.core.IRubyScript;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.core.formatter.Indents;
@@ -27,6 +31,7 @@
import org.rubypeople.rdt.ui.text.ruby.IRubyCompletionProposal;
import com.aptana.rdt.IProblem;
+import com.aptana.rdt.ui.AptanaRDTUIPlugin;
public class QuickFixProcessor implements IQuickFixProcessor {
@@ -57,57 +62,92 @@
LocalCorrectionsSubProcessor.addReplacementProposal("initialize\n", "Rename to 'initialize'", problem, proposals);
break;
case IProblem.ConstantNamingConvention:
- String constName = getSource(context, problem);
+ String constName = getProblemSource(context, problem);
String fixed = Util.camelCaseToUnderscores(constName).toUpperCase();
LocalCorrectionsSubProcessor.addReplacementProposal(fixed, "Convert to UPPERCASE_WITH_UNDERSCORES convention", problem, proposals);
break;
case IProblem.LocalAndMethodNamingConvention:
- String name = getSource(context, problem);
+ String name = getProblemSource(context, problem);
fixed = Util.camelCaseToUnderscores(name).toLowerCase();
LocalCorrectionsSubProcessor.addReplacementProposal(fixed, "Convert to lowercase_with_undercores convention", problem, proposals);
break;
case IProblem.MethodMissingWithoutRespondTo:
// FIXME Only do this stuff when we apply the proposal! Don't do all this work just to create the proposal...
- IRubyScript script = context.getRubyScript();
- String src = script.getSource();
- int offset = 0;
- Node rootNode = ASTProvider.getASTProvider().getAST(script, ASTProvider.WAIT_YES, null);
- Node typeNode = ClosestSpanningNodeLocator.Instance().findClosestSpanner(rootNode, problem.getOffset(), new INodeAcceptor() {
-
- public boolean doesAccept(Node node) {
- return node instanceof ClassNode || node instanceof ModuleNode;
- }
-
- });
- if (typeNode instanceof ClassNode) {
- ClassNode classNode = (ClassNode) typeNode;
- offset = classNode.getBodyNode().getPosition().getStartOffset();
- } else if (typeNode instanceof ModuleNode) {
- ModuleNode classNode = (ModuleNode) typeNode;
- offset = classNode.getBodyNode().getPosition().getStartOffset();
- }
- DefnNode methodNode = NodeFactory.createMethodNode("respond_to?", new String[] {"symbol", "include_private = false"}, null);
- Node insert = NodeFactory.createBlockNode(true, NodeFactory.createNewLineNode(methodNode));
- String text = ReWriteVisitor.createCodeFromNode(insert, src, getFormatHelper());
- // Figure out indent at offset and apply that to each line of text and at end of text
- String line = src.substring(0, src.indexOf("\n", offset));
- line = line.substring(line.lastIndexOf("\n") + 1);
- Map options = script.getRubyProject().getOptions(true);
- String indent = Indents.extractIndentString(line, options);
- text = indent + text;
- text = text + "\n";
- text = text.replaceAll("\\n", "\n" + indent);
+ int offset = getOffsetOfFirstLineInsideType(context, problem);
+ String text = insertedMethodText(context, offset, "respond_to?", new String[] {"symbol", "include_private = false"});
LocalCorrectionsSubProcessor.addReplacementProposal(offset, 0, text, "Add respond_to? method stub", proposals);
break;
+ case IProblem.ComparableInclusionMissingCompareMethod:
+ offset = getOffsetOfFirstLineInsideType(context, problem);
+ text = insertedMethodText(context, offset, "<=>", new String[] {"other"});
+ LocalCorrectionsSubProcessor.addReplacementProposal(offset, 0, text, "Add <=> method stub", proposals);
+ break;
default:
}
}
+
+ private String insertedMethodText(IInvocationContext context, int offset, String methodName, String[] args) {
+ IRubyScript script = context.getRubyScript();
+ String src = "";
+ try {
+ src = script.getSource();
+ } catch (RubyModelException e) {
+ AptanaRDTUIPlugin.log(e);
+ }
+
+ DefnNode methodNode = NodeFactory.createMethodNode(methodName, args, null);
+ Node insert = NodeFactory.createBlockNode(true, NodeFactory.createNewLineNode(methodNode));
+ String text = ReWriteVisitor.createCodeFromNode(insert, src, getFormatHelper());
+
+ StringBuffer buffer = new StringBuffer(text);
+ int index = text.indexOf("\n", 1);
+ buffer.insert(index + 1, " # TODO Auto-generated method stub\n");
+ // Figure out indent at offset and apply that to each line of text and at end of text
+ String indent = findIndent(offset, script, src);
+ buffer.insert(0, indent);
+ buffer.append("\n");
+ text = buffer.toString();
+ text = text.replaceAll("\\n", "\n" + indent);
+ return text;
+ }
- private String getSource(IInvocationContext context, IProblemLocation problem) throws RubyModelException {
+ private String findIndent(int offset, IRubyScript script, String src) {
+ if (src == null || src.length() == 0) return "";
+ int index = src.indexOf("\n", offset);
+ if (index < 1 || index > src.length()) return "";
+ String line = src.substring(0, index);
+ index = line.lastIndexOf("\n");
+ Map options = script.getRubyProject().getOptions(true);
+ if (index == -1 || ((index + 1) >= line.length()) ) return Indents.extractIndentString(line, options);
+ line = line.substring(index + 1);
+ return Indents.extractIndentString(line, options);
+ }
+
+ private int getOffsetOfFirstLineInsideType(IInvocationContext context, IProblemLocation problem) {
IRubyScript script = context.getRubyScript();
+ int offset = -1;
+ Node rootNode = ASTProvider.getASTProvider().getAST(script, ASTProvider.WAIT_YES, null);
+ Node typeNode = ClosestSpanningNodeLocator.Instance().findClosestSpanner(rootNode, problem.getOffset(), new INodeAcceptor() {
+
+ public boolean doesAccept(Node node) {
+ return node instanceof ClassNode || node instanceof ModuleNode;
+ }
+
+ });
+ if (typeNode instanceof ClassNode) {
+ ClassNode classNode = (ClassNode) typeNode;
+ offset = classNode.getBodyNode().getPosition().getStartOffset();
+ } else if (typeNode instanceof ModuleNode) {
+ ModuleNode classNode = (ModuleNode) typeNode;
+ offset = classNode.getBodyNode().getPosition().getStartOffset();
+ }
+ return offset;
+ }
+
+ private String getProblemSource(IInvocationContext context, IProblemLocation problem) throws RubyModelException {
+ IRubyScript script = context.getRubyScript();
String src = script.getSource();
- String constName = src.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
- return constName;
+ return src.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
}
protected FormatHelper getFormatHelper() {
@@ -120,6 +160,7 @@
case IProblem.ConstantNamingConvention:
case IProblem.MethodMissingWithoutRespondTo:
case IProblem.LocalAndMethodNamingConvention:
+ case IProblem.ComparableInclusionMissingCompareMethod:
return true;
default:
return false;
Modified: trunk/com.aptana.rdt.ui/src/com/aptana/rdt/ui/AptanaRDTUIPlugin.java
===================================================================
--- trunk/com.aptana.rdt.ui/src/com/aptana/rdt/ui/AptanaRDTUIPlugin.java 2007-08-21 18:24:14 UTC (rev 3030)
+++ trunk/com.aptana.rdt.ui/src/com/aptana/rdt/ui/AptanaRDTUIPlugin.java 2007-08-21 19:15:40 UTC (rev 3031)
@@ -2,6 +2,7 @@
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
+import org.rubypeople.rdt.core.RubyModelException;
/**
* The activator class controls the plug-in life cycle
@@ -47,4 +48,8 @@
return plugin;
}
+ public static void log(RubyModelException e) {
+ getDefault().getLog().log(e.getStatus());
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|