* Merge with HEAD
diff --git a/plugins/org.eclipse.dltk.ruby.ui/plugin.properties b/plugins/org.eclipse.dltk.ruby.ui/plugin.properties
index f6f7d0e..c328787 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/plugin.properties
+++ b/plugins/org.eclipse.dltk.ruby.ui/plugin.properties
@@ -76,6 +76,8 @@
RubyEditorFoldingPreferencePage.name = Folding
RubyCodeTemplatesPreferencePage.name = Templates
+RubyTaskTagsPreferencePage.name = Task Tags
+
# Decorators
RubyProjectDecorator.name = Ruby Project Decorator
diff --git a/plugins/org.eclipse.dltk.ruby.ui/plugin.xml b/plugins/org.eclipse.dltk.ruby.ui/plugin.xml
index f889310..4f39f7f 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/plugin.xml
+++ b/plugins/org.eclipse.dltk.ruby.ui/plugin.xml
@@ -153,6 +153,11 @@
id="org.eclipse.dltk.ruby.preferences.templates"
name="%RubyCodeTemplatesPreferencePage.name">
</page>
+ <page
+ category="org.eclipse.dltk.ruby.preferences"
+ class="org.eclipse.dltk.ruby.internal.ui.preferences.RubyTodoTaskPreferencePage"
+ id="org.eclipse.dltk.ruby.preferences.todo"
+ name="%RubyTaskTagsPreferencePage.name"/>
</extension>
<extension point="org.eclipse.ui.views">
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/documentation/RubyDocumentationProvider.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/documentation/RubyDocumentationProvider.java
index 20533dc..8475e17 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/documentation/RubyDocumentationProvider.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/documentation/RubyDocumentationProvider.java
@@ -5,7 +5,9 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
-
+ * Contributors:
+ * xored software, Inc. - initial API and Implementation (Andrei Sobolev)
+ * xored software, Inc. - RubyDocumentation display improvements (Alex Panchenko <alex@xored.com>)
*******************************************************************************/
package org.eclipse.dltk.ruby.internal.ui.documentation;
@@ -40,6 +42,12 @@
public class RubyDocumentationProvider implements IScriptDocumentationProvider {
+ private static final String PUBLIC = "public"; //$NON-NLS-1$
+
+ private static final String PROTECTED = "protected"; //$NON-NLS-1$
+
+ private static final String PRIVATE = "private"; //$NON-NLS-1$
+
protected String getLine(Document d, int line) throws BadLocationException {
return d.get(d.getLineOffset(line), d.getLineLength(line));
}
@@ -73,30 +81,51 @@
.setDocumentPartitioner(IRubyPartitions.RUBY_PARTITIONING, null);
}
+ private static int findOffsetBeforeMethod(Document doc, int start)
+ throws BadLocationException {
+ int line = doc.getLineOfOffset(start);
+ for (;;) {
+ if (--line < 0) {
+ throw new BadLocationException();
+ }
+ final IRegion r = doc.getLineInformation(line);
+ if (r.getLength() == 0) {
+ continue;
+ }
+ String s = doc.get(r.getOffset(), r.getLength());
+ if (isBlank(s)) {
+ continue;
+ }
+ s = s.trim();
+ if (PUBLIC.equals(s) || PROTECTED.equals(s) || PRIVATE.equals(s)) {
+ /**
+ * skip access modifiers between method and comment, e.g.
+ *
+ * <code>
+ * # foo-method documentation
+ * public
+ * def foo
+ * end
+ * </code>
+ */
+ continue;
+ }
+ return r.getOffset() + r.getLength() - 1;
+ }
+ }
+
public static String getHeaderComment(String contents, int offset) {
int start = offset;
int end = start;
- String result = ""; //$NON-NLS-1$
-
Document doc = new Document(contents);
installStuff(doc);
- int pos = 0;
-
- if (start > 0) {
- try {
- int line = doc.getLineOfOffset(start);
- if (line == 0)
- return null;
- IRegion inf = doc.getLineInformation(line - 1);
- pos = inf.getOffset() + inf.getLength() - 1;
- } catch (BadLocationException e) {
- return null;
- }
- }
-
try {
+ int pos = 0;
+ if (start > 0) {
+ pos = findOffsetBeforeMethod(doc, start);
+ }
while (pos >= 0 && pos <= doc.getLength()) {
ITypedRegion region = TextUtilities.getPartition(doc,
IRubyPartitions.RUBY_PARTITIONING, pos, true);
@@ -136,15 +165,13 @@
if (end >= doc.getLength())
end = doc.getLength() - 1;
- result = doc.get(start, end - start);
+ return doc.get(start, end - start);
} catch (BadLocationException e1) {
return null;
} finally {
removeStuff(doc);
}
-
- return result;
}
protected String getHeaderComment(IMember member) {
@@ -181,6 +208,8 @@
return null;
}
+ private static final String NOTHING_KNOWN_ABOUT = "Nothing known about"; //$NON-NLS-1$
+
private Reader proccessBuiltinMethod(IMethod method) {
final String divider = "#"; //$NON-NLS-1$
IModelElement pp = method.getAncestor(IModelElement.TYPE);
@@ -190,13 +219,13 @@
+ method.getElementName();
RiHelper helper = RiHelper.getInstance();
String doc = helper.getDocFor(keyword);
- if (doc != null && (doc.indexOf("Nothing known about") != -1) //$NON-NLS-1$
- || doc.trim().length() == 0) {
+ if (doc != null
+ && (doc.indexOf(NOTHING_KNOWN_ABOUT) >= 0 || isBlank(doc))) {
// XXX megafix: some Kernel methods are documented in Object
if (pp.getElementName().equals("Kernel")) { //$NON-NLS-1$
keyword = "Object" + divider + method.getElementName(); //$NON-NLS-1$
doc = helper.getDocFor(keyword);
- if (doc == null || doc.indexOf("Nothing known about") >= 0) { //$NON-NLS-1$
+ if (doc != null && doc.indexOf(NOTHING_KNOWN_ABOUT) >= 0) {
doc = null;
}
} else {
@@ -315,4 +344,26 @@
public Reader getInfo(String content) {
return null;
}
+
+ /**
+ * Checks if a String is whitespace, empty ("") or null.
+ *
+ * @param str
+ * the String to check, may be null
+ * @return <code>true</code> if the String is null, empty or whitespace
+ */
+ private static boolean isBlank(String s) {
+ if (s != null) {
+ final int len = s.length();
+ if (len != 0) {
+ for (int i = 0; i < len; i++) {
+ if (!Character.isWhitespace(s.charAt(i))) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyPreferencesMessages.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyPreferencesMessages.java
index 310964a..7962f29 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyPreferencesMessages.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyPreferencesMessages.java
@@ -29,4 +29,7 @@
public static String EditorFoldingPreferencePageDescription;
public static String GlobalPreferencePageDescription;
+
+ public static String TodoTaskDescription;
+
}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyPreferencesMessages.properties b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyPreferencesMessages.properties
index 954ce64..4e61f8c 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyPreferencesMessages.properties
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyPreferencesMessages.properties
@@ -16,3 +16,4 @@
GlobalPreferencePageDescription = General Ruby preferences
+TodoTaskDescription = Strings indicating tasks in Ruby comments.
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyTodoTaskPreferencePage.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyTodoTaskPreferencePage.java
new file mode 100644
index 0000000..0c6bb3a
--- /dev/null
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/preferences/RubyTodoTaskPreferencePage.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2008 xored software, Inc.
+ *
+ * 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:
+ * xored software, Inc. - initial API and Implementation (Alex Panchenko)
+ *******************************************************************************/
+package org.eclipse.dltk.ruby.internal.ui.preferences;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.dltk.ruby.core.RubyPlugin;
+import org.eclipse.dltk.ui.preferences.TodoTaskAbstractPreferencePage;
+
+public class RubyTodoTaskPreferencePage extends TodoTaskAbstractPreferencePage {
+
+ protected String getHelpId() {
+ return null;
+ }
+
+ protected void setDescription() {
+ setDescription(RubyPreferencesMessages.TodoTaskDescription);
+ }
+
+ protected Preferences getPluginPreferences() {
+ return RubyPlugin.getDefault().getPluginPreferences();
+ }
+
+}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/completion/RubyCompletionProposalLabelProvider.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/completion/RubyCompletionProposalLabelProvider.java
index 311b404..2b40b92 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/completion/RubyCompletionProposalLabelProvider.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/completion/RubyCompletionProposalLabelProvider.java
@@ -10,14 +10,25 @@
package org.eclipse.dltk.ruby.internal.ui.text.completion;
import org.eclipse.dltk.core.CompletionProposal;
+import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IMethod;
import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.IProjectFragment;
+import org.eclipse.dltk.core.IScriptFolder;
+import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
+import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
import org.eclipse.dltk.ruby.core.model.FakeMethod;
+import org.eclipse.dltk.ui.ScriptElementLabels;
import org.eclipse.dltk.ui.text.completion.CompletionProposalLabelProvider;
public class RubyCompletionProposalLabelProvider extends
CompletionProposalLabelProvider {
+
+ private static final String SEPARATOR = " - "; //$NON-NLS-1$
+ private static final String PACKAGE_SEPARATOR = "::"; //$NON-NLS-1$
+ private static final String FOLDER_SEPARATOR = "/"; //$NON-NLS-1$
+
protected String createMethodProposalLabel(CompletionProposal methodProposal) {
StringBuffer nameBuffer = new StringBuffer();
@@ -30,7 +41,7 @@
nameBuffer.append(')');
IMethod method = (IMethod) methodProposal.getModelElement();
- nameBuffer.append(" - "); //$NON-NLS-1$
+ nameBuffer.append(SEPARATOR);
if (method instanceof FakeMethod
&& ((FakeMethod) method).getReceiver() != null) {
nameBuffer.append(((FakeMethod) method).getReceiver());
@@ -38,7 +49,7 @@
IModelElement parent = method.getParent();
if (parent instanceof IType) {
IType type = (IType) parent;
- nameBuffer.append(type.getTypeQualifiedName("::")); //$NON-NLS-1$
+ nameBuffer.append(type.getTypeQualifiedName(PACKAGE_SEPARATOR));
} else {
nameBuffer.append(parent.getElementName());
}
@@ -57,10 +68,10 @@
// parameters
nameBuffer.append('(');
appendUnboundedParameterList(nameBuffer, methodProposal);
- nameBuffer.append(')'); //$NON-NLS-1$
+ nameBuffer.append(')');
IMethod method = (IMethod) methodProposal.getModelElement();
- nameBuffer.append(" - "); //$NON-NLS-1$
+ nameBuffer.append(SEPARATOR);
if (method instanceof FakeMethod
&& ((FakeMethod) method).getReceiver() != null) {
String receiver = ((FakeMethod) method).getReceiver();
@@ -69,7 +80,7 @@
IModelElement parent = method.getParent();
if (parent instanceof IType) {
IType type = (IType) parent;
- nameBuffer.append(type.getTypeQualifiedName("::")); //$NON-NLS-1$
+ nameBuffer.append(type.getTypeQualifiedName(PACKAGE_SEPARATOR));
} else {
nameBuffer.append(parent.getElementName());
}
@@ -79,22 +90,83 @@
}
protected String createTypeProposalLabel(CompletionProposal typeProposal) {
- StringBuffer nameBuffer = new StringBuffer();
-
+ final StringBuffer nameBuffer = new StringBuffer();
nameBuffer.append(typeProposal.getName());
-
- IType type = (IType) typeProposal.getModelElement();
- nameBuffer.append(" - "); //$NON-NLS-1$
- IModelElement parent = type.getParent();
+ final IType type = (IType) typeProposal.getModelElement();
+ final IModelElement parent = type.getParent();
+ final ISourceModule parentModule;
if (parent instanceof IType) {
- IType type2 = (IType) parent;
- nameBuffer.append(type2.getElementName()); // XXX, fqn may be
- // better idea
+ nameBuffer.append(SEPARATOR);
+ parentModule = appendType((IType) parent, nameBuffer);
+ } else if (parent instanceof ISourceModule) {
+ parentModule = (ISourceModule) parent;
} else {
- nameBuffer.append(parent.getElementName());
+ parentModule = null;
}
-
+ if (parentModule != null) {
+ nameBuffer.append(SEPARATOR);
+ appendSourceModule(parentModule, nameBuffer);
+ }
return nameBuffer.toString();
}
+ private ISourceModule appendType(IType type, StringBuffer sb) {
+ final IModelElement parent = type.getParent();
+ if (parent instanceof IType) {
+ final ISourceModule module = appendType((IType) parent, sb);
+ sb.append(PACKAGE_SEPARATOR);
+ sb.append(type.getElementName());
+ return module;
+ } else {
+ sb.append(type.getElementName());
+ if (parent instanceof ISourceModule) {
+ return (ISourceModule) parent;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private void appendSourceModule(ISourceModule module, StringBuffer sb) {
+ final IModelElement parent = module.getParent();
+ final IProjectFragment fragment;
+ if (parent instanceof IScriptFolder) {
+ fragment = appendScriptFolder((IScriptFolder) parent, sb);
+ } else {
+ fragment = null;
+ }
+ sb.append(module.getElementName());
+ if (fragment != null) {
+ if (!fragment.isArchive()) {
+ if (fragment.getPath().toString().startsWith(
+ IBuildpathEntry.BUILTIN_EXTERNAL_ENTRY_STR)) {
+ sb.append(' ');
+ sb.append(ScriptElementLabels.BUILTINS_FRAGMENT);
+ } else if (fragment.isExternal()) {
+ sb.append(SEPARATOR);
+ sb.append(EnvironmentPathUtils.getLocalPath(
+ fragment.getPath()).toPortableString());
+ }
+ }
+ }
+ }
+
+ private IProjectFragment appendScriptFolder(IScriptFolder folder,
+ StringBuffer sb) {
+ final IModelElement parent = folder.getParent();
+ final IProjectFragment fragment;
+ if (parent instanceof IScriptFolder) {
+ fragment = appendScriptFolder((IScriptFolder) parent, sb);
+ } else if (parent instanceof IProjectFragment) {
+ fragment = (IProjectFragment) parent;
+ } else {
+ fragment = null;
+ }
+ if (!folder.isRootFolder()) {
+ sb.append(folder.getElementName());
+ sb.append(FOLDER_SEPARATOR);
+ }
+ return fragment;
+ }
+
}