add some javadoc tag parameter completion variants (IDEA-110161, IDEA-22340, IDEA-56357)

This commit is contained in:
peter
2013-07-05 19:21:36 +02:00
parent c538b5ada0
commit 59ca5fc3fc
3 changed files with 86 additions and 15 deletions
@@ -29,6 +29,7 @@ import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.PsiJavaPatterns;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
@@ -38,10 +39,13 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.filters.TrueFilter;
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
import com.intellij.psi.javadoc.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ProcessingContext;
import com.intellij.util.Processor;
import com.intellij.util.SystemProperties;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -120,18 +124,19 @@ public class JavaDocCompletionContributor extends CompletionContributor {
@Override
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
List<String> ret = new ArrayList<String>();
final List<String> ret = new ArrayList<String>();
final PsiElement position = parameters.getPosition();
final PsiDocComment comment = PsiTreeUtil.getParentOfType(position, PsiDocComment.class);
assert comment != null;
final PsiElement parent = comment.getContext();
final boolean isInline = position.getContext() instanceof PsiInlineDocTag;
final JavadocManager manager = JavadocManager.SERVICE.getInstance(position.getProject());
final JavadocTagInfo[] infos = manager.getTagInfos(parent);
for (JavadocTagInfo info : infos) {
if (info.getName().equals(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME)) continue;
if (isInline != (info.isInline())) continue;
ret.add(info.getName());
for (JavadocTagInfo info : JavadocManager.SERVICE.getInstance(position.getProject()).getTagInfos(parent)) {
String tagName = info.getName();
if (tagName.equals(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME)) continue;
if (isInline != info.isInline()) continue;
ret.add(tagName);
addSpecialTags(ret, comment, tagName);
}
InspectionProfile inspectionProfile =
@@ -149,11 +154,43 @@ public class JavaDocCompletionContributor extends CompletionContributor {
result.addElement(TailTypeDecorator.withTail(LookupElementBuilder.create(s), TailType.INSERT_SPACE));
}
}
result.stopHere(); // no word completions at this point
}
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
return "javadoc-tag-chooser";
private static void addSpecialTags(final List<String> result, PsiDocComment comment, String tagName) {
if ("author".equals(tagName)) {
result.add(tagName + " " + SystemProperties.getUserName());
return;
}
if ("param".equals(tagName)) {
PsiMethod psiMethod = PsiTreeUtil.getParentOfType(comment, PsiMethod.class);
if (psiMethod != null) {
PsiDocTag[] tags = comment.getTags();
for (PsiParameter param : psiMethod.getParameterList().getParameters()) {
if (!JavaDocLocalInspection.isFound(tags, param)) {
result.add(tagName + " " + param.getName());
}
}
}
return;
}
if ("see".equals(tagName)) {
PsiMember member = PsiTreeUtil.getParentOfType(comment, PsiMember.class);
if (member instanceof PsiClass) {
InheritanceUtil.processSupers((PsiClass)member, false, new Processor<PsiClass>() {
@Override
public boolean process(PsiClass psiClass) {
String name = psiClass.getQualifiedName();
if (StringUtil.isNotEmpty(name) && !CommonClassNames.JAVA_LANG_OBJECT.equals(name)) {
result.add("see " + name);
}
return true;
}
});
}
}
}
}
@@ -14,6 +14,7 @@ import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
import com.intellij.psi.javadoc.PsiDocTag
import com.intellij.util.ObjectUtils
import com.intellij.util.ProcessingContext
import com.intellij.util.SystemProperties
import org.jetbrains.annotations.NotNull
/**
* @author mike
@@ -33,7 +34,7 @@ public class JavadocCompletionTest extends LightFixtureCompletionTestCase {
public void testNamesInClass() throws Exception {
configureByFile("ClassTagName.java");
assertStringItems("author", "deprecated", "param", "see", "serial", "since", "version");
assertStringItems("author", 'author ' + SystemProperties.getUserName(), "deprecated", "param", "see", "serial", "since", "version");
}
public void testNamesInField() throws Exception {
@@ -48,7 +49,7 @@ public class JavadocCompletionTest extends LightFixtureCompletionTestCase {
public void testNamesInMethod1() throws Exception {
configureByFile("MethodTagName1.java");
assertStringItems("see", "serialData", "since", "throws", "class");
assertStringItems("see", "serialData", "since", "throws");
}
public void testParamValueCompletion() throws Exception {
@@ -198,6 +199,39 @@ public class JavadocCompletionTest extends LightFixtureCompletionTestCase {
checkResultByFile(getTestName(false) + "_after.java");
}
public void "test suggest param names"() {
myFixture.configureByText "a.java", '''
class Foo {
/**
* @par<caret>
*/
void foo(int intParam, Object param2) {
}
}
'''
myFixture.completeBasic()
myFixture.assertPreferredCompletionItems 0, 'param', 'param intParam', 'param param2'
myFixture.type('\n intParam\n@para')
myFixture.completeBasic()
myFixture.assertPreferredCompletionItems 0, 'param', 'param param2'
}
public void "test see super class"() {
myFixture.addClass("package foo; public interface Foo {}")
myFixture.addClass("package bar; public class Bar {} ")
myFixture.configureByText "a.java", '''
import foo.*;
import bar.*;
/**
* @se<caret>
*/
class Impl extends Bar implements Foo {}
'''
myFixture.completeBasic()
myFixture.assertPreferredCompletionItems 0, 'see', 'see bar.Bar', 'see foo.Foo'
}
public void testCustomReferenceProvider() throws Exception {
PsiReferenceRegistrarImpl registrar =
(PsiReferenceRegistrarImpl) ReferenceProvidersRegistry.getInstance().getRegistrar(StdLanguages.JAVA);
@@ -139,7 +139,7 @@ public class CompletionLookupArranger extends LookupArranger {
public void addElement(Lookup lookup, LookupElement element, LookupElementPresentation presentation) {
StatisticsWeigher.clearBaseStatisticsInfo(element);
final String invariant = presentation.getItemText() + "###" + getTailTextOrSpace(presentation) + "###" + presentation.getTypeText();
final String invariant = presentation.getItemText() + "\0###" + getTailTextOrSpace(presentation) + "###" + presentation.getTypeText();
element.putUserData(PRESENTATION_INVARIANT, invariant);
CompletionSorterImpl sorter = obtainSorter(element);
@@ -332,9 +332,9 @@ public class CompletionLookupArranger extends LookupArranger {
return old;
}
Object selectedValue = ((LookupImpl)lookup).getList().getSelectedValue();
Object selectedValue = lookup.getList().getSelectedValue();
if (selectedValue instanceof EmptyLookupItem && ((EmptyLookupItem)selectedValue).isLoading()) {
int index = ((LookupImpl)lookup).getList().getSelectedIndex();
int index = lookup.getList().getSelectedIndex();
if (index >= 0 && index < items.size()) {
return index;
}