IDEA-118096 Documentation popup not usable because of Jetbrains annotations

This commit is contained in:
Alexey Kudravtsev
2013-12-20 13:52:57 +04:00
parent c52f140d18
commit 32133c0ad1
4 changed files with 67 additions and 24 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2009 JetBrains s.r.o. * Copyright 2000-2013 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -78,13 +78,13 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
@Override @Override
@Nullable @Nullable
public PsiExpressionList findElementForParameterInfo(final CreateParameterInfoContext context) { public PsiExpressionList findElementForParameterInfo(@NotNull final CreateParameterInfoContext context) {
PsiExpressionList argumentList = findArgumentList(context.getFile(), context.getOffset(), context.getParameterListStart()); PsiExpressionList argumentList = findArgumentList(context.getFile(), context.getOffset(), context.getParameterListStart());
if (argumentList != null) { if (argumentList != null) {
return findMethodsForArgumentList(context, argumentList); return findMethodsForArgumentList(context, argumentList);
} }
return argumentList; return null;
} }
private PsiExpressionList findArgumentList(final PsiFile file, int offset, int parameterStart) { private PsiExpressionList findArgumentList(final PsiFile file, int offset, int parameterStart) {
@@ -112,17 +112,17 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
} }
@Override @Override
public void showParameterInfo(@NotNull final PsiExpressionList element, final CreateParameterInfoContext context) { public void showParameterInfo(@NotNull final PsiExpressionList element, @NotNull final CreateParameterInfoContext context) {
context.showHint(element, element.getTextRange().getStartOffset(), this); context.showHint(element, element.getTextRange().getStartOffset(), this);
} }
@Override @Override
public PsiExpressionList findElementForUpdatingParameterInfo(final UpdateParameterInfoContext context) { public PsiExpressionList findElementForUpdatingParameterInfo(@NotNull final UpdateParameterInfoContext context) {
return findArgumentList(context.getFile(), context.getOffset(), context.getParameterListStart()); return findArgumentList(context.getFile(), context.getOffset(), context.getParameterListStart());
} }
@Override @Override
public void updateParameterInfo(@NotNull final PsiExpressionList o, final UpdateParameterInfoContext context) { public void updateParameterInfo(@NotNull final PsiExpressionList o, @NotNull final UpdateParameterInfoContext context) {
PsiElement parameterOwner = context.getParameterOwner(); PsiElement parameterOwner = context.getParameterOwner();
if (parameterOwner != o) { if (parameterOwner != o) {
context.removeHint(); context.removeHint();
@@ -357,7 +357,8 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
} }
} }
public static String updateMethodPresentation(PsiMethod method, @Nullable PsiSubstitutor substitutor, ParameterInfoUIContext context) { @NotNull
public static String updateMethodPresentation(@NotNull PsiMethod method, @Nullable PsiSubstitutor substitutor, @NotNull ParameterInfoUIContext context) {
CodeInsightSettings settings = CodeInsightSettings.getInstance(); CodeInsightSettings settings = CodeInsightSettings.getInstance();
if (!method.isValid() || substitutor != null && !substitutor.isValid()) { if (!method.isValid() || substitutor != null && !substitutor.isValid()) {
@@ -444,16 +445,20 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
private static void appendModifierList(@NotNull StringBuilder buffer, @NotNull PsiModifierListOwner owner) { private static void appendModifierList(@NotNull StringBuilder buffer, @NotNull PsiModifierListOwner owner) {
int lastSize = buffer.length(); int lastSize = buffer.length();
for (PsiAnnotation a : AnnotationUtil.getAllAnnotations(owner, false, null)) { for (PsiAnnotation annotation : AnnotationUtil.getAllAnnotations(owner, false, null)) {
if (lastSize != buffer.length()) buffer.append(" "); final PsiJavaCodeReferenceElement element = annotation.getNameReferenceElement();
final PsiJavaCodeReferenceElement element = a.getNameReferenceElement(); if (element != null) {
if (element != null) buffer.append("@").append(element.getReferenceName()); final PsiElement resolved = element.resolve();
if (resolved instanceof PsiClass && !AnnotationUtil.isAnnotated((PsiClass)resolved, "java.lang.annotation.Documented", false)) continue;
if (lastSize != buffer.length()) buffer.append(" ");
buffer.append("@").append(element.getReferenceName());
}
} }
if (lastSize != buffer.length()) buffer.append(" "); if (lastSize != buffer.length()) buffer.append(" ");
} }
@Override @Override
public void updateUI(final Object p, final ParameterInfoUIContext context) { public void updateUI(final Object p, @NotNull final ParameterInfoUIContext context) {
if (p instanceof CandidateInfo) { if (p instanceof CandidateInfo) {
CandidateInfo info = (CandidateInfo)p; CandidateInfo info = (CandidateInfo)p;
PsiMethod method = (PsiMethod)info.getElement(); PsiMethod method = (PsiMethod)info.getElement();

View File

@@ -1,3 +1,18 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight; package com.intellij.codeInsight;
import com.intellij.codeInsight.hint.ParameterInfoComponent; import com.intellij.codeInsight.hint.ParameterInfoComponent;
@@ -8,21 +23,29 @@ import com.intellij.lang.parameterInfo.ParameterInfoUIContextEx;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*; import com.intellij.psi.*;
import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.LightCodeInsightTestCase; import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.testFramework.utils.parameterInfo.MockCreateParameterInfoContext; import com.intellij.testFramework.utils.parameterInfo.MockCreateParameterInfoContext;
import com.intellij.testFramework.utils.parameterInfo.MockParameterInfoUIContext;
import com.intellij.testFramework.utils.parameterInfo.MockUpdateParameterInfoContext; import com.intellij.testFramework.utils.parameterInfo.MockUpdateParameterInfoContext;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ArrayUtilRt; import com.intellij.util.ArrayUtilRt;
import com.intellij.util.Function; import com.intellij.util.Function;
import junit.framework.Assert; import junit.framework.Assert;
import java.io.IOException;
public class ParameterInfoTest extends LightCodeInsightTestCase { public class ParameterInfoTest extends LightCodeInsightTestCase {
private static final String BASE_PATH = "/codeInsight/parameterInfo/"; private static final String BASE_PATH = "/codeInsight/parameterInfo/";
private Object[] doTest(String paramsList) throws Exception { private void doTest(String paramsList) throws Exception {
configureByFile(BASE_PATH + getTestName(false) + ".java"); configureByFile(BASE_PATH + getTestName(false) + ".java");
String joined = invokeParameterInfo();
assertEquals(paramsList, joined);
}
private static String invokeParameterInfo() {
final MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); final MethodParameterInfoHandler handler = new MethodParameterInfoHandler();
final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile); final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile);
final PsiExpressionList list = handler.findElementForParameterInfo(context); final PsiExpressionList list = handler.findElementForParameterInfo(context);
@@ -31,14 +54,12 @@ public class ParameterInfoTest extends LightCodeInsightTestCase {
assertTrue(context.getItemsToShow().length > 0); assertTrue(context.getItemsToShow().length > 0);
Object[] params = handler.getParametersForDocumentation(context.getItemsToShow()[0], context); Object[] params = handler.getParametersForDocumentation(context.getItemsToShow()[0], context);
assertNotNull(params); assertNotNull(params);
String joined = StringUtil.join(params, new Function<Object, String>() { return StringUtil.join(params, new Function<Object, String>() {
@Override @Override
public String fun(Object o) { public String fun(Object o) {
return ((PsiParameter)o).getName(); return ((PsiParameter)o).getName();
} }
}, ","); }, ",");
assertEquals(paramsList, joined);
return params;
} }
public void testPrivateMethodOfEnclosingClass() throws Exception { public void testPrivateMethodOfEnclosingClass() throws Exception {
@@ -49,6 +70,20 @@ public class ParameterInfoTest extends LightCodeInsightTestCase {
doTest("param"); doTest("param");
} }
public void testParameterInfoDoesNotShowInternalJetbrainsAnnotations() throws IOException {
configureFromFileText("x.java", "class X { void f(@org.intellij.lang.annotations.Flow int i) { f(<caret>0); }}");
final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile);
PsiMethod method = PsiTreeUtil.getParentOfType(myFile.findElementAt(context.getOffset()), PsiMethod.class);
final String list = MethodParameterInfoHandler.updateMethodPresentation(method, PsiSubstitutor.EMPTY, new MockParameterInfoUIContext<PsiMethod>(method));
assertEquals("int i", list);
PsiAnnotation[] annotations = AnnotationUtil.getAllAnnotations(method.getParameterList().getParameters()[0], false, null);
assertEquals(1, annotations.length);
}
public void testNoParams() throws Exception { public void testNoParams() throws Exception {
doTestPresentation("<html>&lt;no parameters&gt;</html>"); doTestPresentation("<html>&lt;no parameters&gt;</html>");
} }
@@ -66,7 +101,7 @@ public class ParameterInfoTest extends LightCodeInsightTestCase {
assertNotNull(list); assertNotNull(list);
final Object[] itemsToShow = context.getItemsToShow(); final Object[] itemsToShow = context.getItemsToShow();
assertNotNull(itemsToShow); assertNotNull(itemsToShow);
assertTrue(itemsToShow.length == 2); assertEquals(2, itemsToShow.length);
assertTrue(itemsToShow[0] instanceof MethodCandidateInfo); assertTrue(itemsToShow[0] instanceof MethodCandidateInfo);
final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, -1); final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, -1);
final Boolean [] enabled = new Boolean[itemsToShow.length]; final Boolean [] enabled = new Boolean[itemsToShow.length];
@@ -95,7 +130,7 @@ public class ParameterInfoTest extends LightCodeInsightTestCase {
assertNotNull(list); assertNotNull(list);
final Object[] itemsToShow = context.getItemsToShow(); final Object[] itemsToShow = context.getItemsToShow();
assertNotNull(itemsToShow); assertNotNull(itemsToShow);
assertTrue(itemsToShow.length == 2); assertEquals(2, itemsToShow.length);
assertTrue(itemsToShow[0] instanceof MethodCandidateInfo); assertTrue(itemsToShow[0] instanceof MethodCandidateInfo);
final PsiMethod method = ((MethodCandidateInfo)itemsToShow[0]).getElement(); final PsiMethod method = ((MethodCandidateInfo)itemsToShow[0]).getElement();
final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, 1); final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, 1);
@@ -118,7 +153,7 @@ public class ParameterInfoTest extends LightCodeInsightTestCase {
assertNotNull(list); assertNotNull(list);
final Object[] itemsToShow = context.getItemsToShow(); final Object[] itemsToShow = context.getItemsToShow();
assertNotNull(itemsToShow); assertNotNull(itemsToShow);
assertTrue(itemsToShow.length == 1); assertEquals(1, itemsToShow.length);
assertTrue(itemsToShow[0] instanceof MethodCandidateInfo); assertTrue(itemsToShow[0] instanceof MethodCandidateInfo);
final PsiMethod method = ((MethodCandidateInfo)itemsToShow[0]).getElement(); final PsiMethod method = ((MethodCandidateInfo)itemsToShow[0]).getElement();
final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, -1); final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, -1);
@@ -134,17 +169,21 @@ public class ParameterInfoTest extends LightCodeInsightTestCase {
private void doTestAnnotationPresentation(String expectedString) { private void doTestAnnotationPresentation(String expectedString) {
configureByFile(BASE_PATH + getTestName(false) + ".java"); configureByFile(BASE_PATH + getTestName(false) + ".java");
String text = invokeParameterInfoForAnnotations();
Assert.assertEquals(expectedString, text);
}
private static String invokeParameterInfoForAnnotations() {
final AnnotationParameterInfoHandler handler = new AnnotationParameterInfoHandler(); final AnnotationParameterInfoHandler handler = new AnnotationParameterInfoHandler();
final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile); final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile);
final PsiAnnotationParameterList list = handler.findElementForParameterInfo(context); final PsiAnnotationParameterList list = handler.findElementForParameterInfo(context);
assertNotNull(list); assertNotNull(list);
final Object[] itemsToShow = context.getItemsToShow(); final Object[] itemsToShow = context.getItemsToShow();
assertNotNull(itemsToShow); assertNotNull(itemsToShow);
assertTrue(itemsToShow.length == 1); assertEquals(1, itemsToShow.length);
assertTrue(itemsToShow[0] instanceof PsiAnnotationMethod); assertTrue(itemsToShow[0] instanceof PsiAnnotationMethod);
final PsiAnnotationMethod method = (PsiAnnotationMethod)itemsToShow[0]; final PsiAnnotationMethod method = (PsiAnnotationMethod)itemsToShow[0];
final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, -1); final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, -1);
Assert.assertEquals(expectedString, return AnnotationParameterInfoHandler.updateUIText(method, parameterContext);
AnnotationParameterInfoHandler.updateUIText(method, parameterContext));
} }
} }

View File

@@ -19,7 +19,6 @@ import org.jetbrains.annotations.NonNls;
import java.lang.annotation.*; import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.CLASS) @Retention(RetentionPolicy.CLASS)
@Target({ElementType.PARAMETER, ElementType.METHOD}) @Target({ElementType.PARAMETER, ElementType.METHOD})
/** /**