From 564c66acbf410b12ceb73aedbac66faf189a148d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 27 Jan 2016 12:51:03 +0300 Subject: [PATCH] [java] skip type annotations from parameter info (IDEA-132058) --- .../api/impls/MethodParameterInfoHandler.java | 42 ++-- .../codeInsight/ParameterInfoTest.java | 221 +++++++++--------- 2 files changed, 127 insertions(+), 136 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java index 7548d43cf112..91d0902fac89 100644 --- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.hint.api.impls; +import com.intellij.codeInsight.AnnotationTargetUtil; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.CodeInsightSettings; @@ -36,35 +37,30 @@ import com.intellij.psi.scope.processor.MethodResolverProcessor; import com.intellij.psi.scope.util.PsiScopesUtil; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.MethodSignatureUtil; -import com.intellij.psi.util.PsiUtilBase; +import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; /** * @author Maxim.Mossienko */ -public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabActionSupport, - DumbAware { - private static final Set ourArgumentListAllowedParentClassesSet = new HashSet( - Arrays.asList(PsiMethodCallExpression.class, PsiNewExpression.class, PsiAnonymousClass.class, PsiEnumConstant.class)); +public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabActionSupport, DumbAware { + private static final Set ourArgumentListAllowedParentClassesSet = ContainerUtil.newHashSet( + PsiMethodCallExpression.class, PsiNewExpression.class, PsiAnonymousClass.class, PsiEnumConstant.class); private static final Set ourStopSearch = Collections.singleton(PsiMethod.class); @Override public Object[] getParametersForLookup(LookupElement item, ParameterInfoContext context) { - final List allElements = JavaCompletionUtil.getAllPsiElements(item); - - if (allElements != null && - !allElements.isEmpty() && - allElements.get(0) instanceof PsiMethod) { - return allElements.toArray(new PsiMethod[allElements.size()]); - } - return null; + final List elements = JavaCompletionUtil.getAllPsiElements(item); + return elements != null && !elements.isEmpty() && elements.get(0) instanceof PsiMethod ? elements.toArray() : null; } @Override @@ -213,9 +209,9 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc if (realResolve == null) { PsiCall call = getCall(o); if (call != null) realResolve = call.resolveMethod(); - if (realResolve == null) realResolve = PsiUtilBase.NULL_PSI_ELEMENT; + if (realResolve == null) realResolve = PsiUtilCore.NULL_PSI_ELEMENT; } - if (realResolve == PsiUtilBase.NULL_PSI_ELEMENT || realResolve == method) context.setHighlightedParameter(candidate); + if (realResolve == PsiUtilCore.NULL_PSI_ELEMENT || realResolve == method) context.setHighlightedParameter(candidate); } } } @@ -477,18 +473,20 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc final PsiJavaCodeReferenceElement element = annotation.getNameReferenceElement(); if (element != null) { final PsiElement resolved = element.resolve(); - if (resolved instanceof PsiClass && !JavaDocInfoGenerator.isDocumentedAnnotationType(resolved)) { + if (resolved instanceof PsiClass && + (!JavaDocInfoGenerator.isDocumentedAnnotationType(resolved) || + AnnotationTargetUtil.findAnnotationTarget((PsiClass)resolved, PsiAnnotation.TargetType.TYPE_USE) != null)) { continue; } String referenceName = element.getReferenceName(); if (shownAnnotations.add(referenceName) || JavaDocInfoGenerator.isRepeatableAnnotationType(resolved)) { - if (lastSize != buffer.length()) buffer.append(" "); - buffer.append("@").append(referenceName); + if (lastSize != buffer.length()) buffer.append(' '); + buffer.append('@').append(referenceName); } } } - if (lastSize != buffer.length()) buffer.append(" "); + if (lastSize != buffer.length()) buffer.append(' '); } @Override diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java index b5e28307fb67..5f7e03c73b47 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight; +import com.intellij.JavaTestUtil; import com.intellij.codeInsight.hint.ParameterInfoComponent; import com.intellij.codeInsight.hint.api.impls.AnnotationParameterInfoHandler; import com.intellij.codeInsight.hint.api.impls.MethodParameterInfoHandler; @@ -24,176 +25,168 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.testFramework.LightCodeInsightTestCase; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import com.intellij.testFramework.utils.parameterInfo.MockCreateParameterInfoContext; import com.intellij.testFramework.utils.parameterInfo.MockParameterInfoUIContext; import com.intellij.testFramework.utils.parameterInfo.MockUpdateParameterInfoContext; -import com.intellij.util.Function; -import junit.framework.Assert; import java.io.IOException; -public class ParameterInfoTest extends LightCodeInsightTestCase { +public class ParameterInfoTest extends LightCodeInsightFixtureTestCase { + @Override + protected String getBasePath() { + return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/parameterInfo/"; + } - private static final String BASE_PATH = "/codeInsight/parameterInfo/"; + public void testPrivateMethodOfEnclosingClass() { doTest("param"); } + public void testNotAccessible() { doTest("param"); } - private void doTest(String paramsList) throws Exception { - configureByFile(BASE_PATH + getTestName(false) + ".java"); + private void doTest(String paramsList) { + myFixture.configureByFile(getTestName(false) + ".java"); - String joined = invokeParameterInfo(); + MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); + CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile()); + PsiExpressionList list = handler.findElementForParameterInfo(context); + assertNotNull(list); + Object[] itemsToShow = context.getItemsToShow(); + assertNotNull(itemsToShow); + assertTrue(itemsToShow.length > 0); + Object[] params = handler.getParametersForDocumentation(itemsToShow[0], context); + assertNotNull(params); + String joined = StringUtil.join(params, o -> ((PsiParameter)o).getName(), ","); assertEquals(paramsList, joined); } - private static String invokeParameterInfo() { - final MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); - final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile); - final PsiExpressionList list = handler.findElementForParameterInfo(context); - assertNotNull(list); - assertNotNull(context.getItemsToShow()); - assertTrue(context.getItemsToShow().length > 0); - Object[] params = handler.getParametersForDocumentation(context.getItemsToShow()[0], context); - assertNotNull(params); - return StringUtil.join(params, new Function() { - @Override - public String fun(Object o) { - return ((PsiParameter)o).getName(); - } - }, ","); - } - - public void testPrivateMethodOfEnclosingClass() throws Exception { - doTest("param"); - } - - public void testNotAccessible() throws Exception { - doTest("param"); - } - public void testParameterInfoDoesNotShowInternalJetbrainsAnnotations() throws IOException { - configureFromFileText("x.java", "class X { void f(@org.intellij.lang.annotations.Flow int i) { f(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(method)); + myFixture.configureByText("x.java", "class X { void f(@org.intellij.lang.annotations.Flow int i) { f(0); }}"); + CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile()); + PsiMethod method = PsiTreeUtil.getParentOfType(getFile().findElementAt(context.getOffset()), PsiMethod.class); + assertNotNull(method); + MockParameterInfoUIContext uiContext = new MockParameterInfoUIContext<>(method); + String list = MethodParameterInfoHandler.updateMethodPresentation(method, PsiSubstitutor.EMPTY, uiContext); assertEquals("int i", list); - PsiAnnotation[] annotations = AnnotationUtil.getAllAnnotations(method.getParameterList().getParameters()[0], false, null); assertEquals(1, annotations.length); } - public void testNoParams() throws Exception { - doTestPresentation("<no parameters>"); - } + public void testSelectionWithGenerics() { + myFixture.configureByFile(getTestName(false) + ".java"); - public void testGenericsInsideCall() throws Exception { - doTestPresentation("List<String> param"); - } - - public void testSelectionWithGenerics() throws Exception { - configureByFile(BASE_PATH + getTestName(false) + ".java"); - - final MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); - final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile); - final PsiExpressionList list = handler.findElementForParameterInfo(context); + MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); + CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile()); + PsiExpressionList list = handler.findElementForParameterInfo(context); assertNotNull(list); - final Object[] itemsToShow = context.getItemsToShow(); + Object[] itemsToShow = context.getItemsToShow(); assertNotNull(itemsToShow); assertEquals(2, itemsToShow.length); assertTrue(itemsToShow[0] instanceof MethodCandidateInfo); - final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, -1); - final MockUpdateParameterInfoContext updateParameterInfoContext = new MockUpdateParameterInfoContext(myEditor, myFile, itemsToShow); + ParameterInfoComponent.createContext(itemsToShow, getEditor(), handler, -1); + MockUpdateParameterInfoContext updateParameterInfoContext = new MockUpdateParameterInfoContext(getEditor(), getFile(), itemsToShow); updateParameterInfoContext.setParameterOwner(list); handler.updateParameterInfo(list, updateParameterInfoContext); assertTrue(updateParameterInfoContext.isUIComponentEnabled(0) || updateParameterInfoContext.isUIComponentEnabled(1)); } - public void testStopAtAccessibleStaticCorrectCandidate() throws Exception { - configureByFile(BASE_PATH + getTestName(false) + ".java"); + public void testStopAtAccessibleStaticCorrectCandidate() { + myFixture.configureByFile(getTestName(false) + ".java"); - final MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); - final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile); - final PsiExpressionList list = handler.findElementForParameterInfo(context); + MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); + CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile()); + PsiExpressionList list = handler.findElementForParameterInfo(context); assertNotNull(list); - final Object[] itemsToShow = context.getItemsToShow(); + Object[] itemsToShow = context.getItemsToShow(); assertNotNull(itemsToShow); assertEquals(1, itemsToShow.length); assertEquals(0, ((MethodCandidateInfo)itemsToShow[0]).getElement().getParameterList().getParametersCount()); } - public void testAfterGenericsInsideCall() throws Exception { - configureByFile(BASE_PATH + getTestName(false) + ".java"); + public void testAfterGenericsInsideCall() { + myFixture.configureByFile(getTestName(false) + ".java"); - final MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); - final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile); - final PsiExpressionList list = handler.findElementForParameterInfo(context); + MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); + CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile()); + PsiExpressionList list = handler.findElementForParameterInfo(context); assertNotNull(list); - final Object[] itemsToShow = context.getItemsToShow(); + Object[] itemsToShow = context.getItemsToShow(); assertNotNull(itemsToShow); assertEquals(2, itemsToShow.length); assertTrue(itemsToShow[0] instanceof MethodCandidateInfo); - final PsiMethod method = ((MethodCandidateInfo)itemsToShow[0]).getElement(); - final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, 1); + PsiMethod method = ((MethodCandidateInfo)itemsToShow[0]).getElement(); + ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, getEditor(), handler, 1); parameterContext.setUIComponentEnabled(true); - Assert.assertEquals("Class<T> type, boolean tags", - MethodParameterInfoHandler - .updateMethodPresentation(method, ((MethodCandidateInfo)itemsToShow[0]).getSubstitutor(), parameterContext)); + PsiSubstitutor substitutor = ((MethodCandidateInfo)itemsToShow[0]).getSubstitutor(); + String presentation = MethodParameterInfoHandler.updateMethodPresentation(method, substitutor, parameterContext); + assertEquals("Class<T> type, boolean tags", presentation); } - public void testGenericsOutsideCall() throws Exception { - doTestPresentation("List<String> param"); + public void testNoParams() { doTestPresentation("<no parameters>", -1); } + public void testGenericsInsideCall() { doTestPresentation("List<String> param", -1); } + public void testGenericsOutsideCall() { doTestPresentation("List<String> param", -1); } + public void testIgnoreVarargs() { doTestPresentation("Class<T> a, Class<? extends CharSequence>... stopAt", 1); } + + private void doTestPresentation(String expectedString, int parameterIndex) { + myFixture.configureByFile(getTestName(false) + ".java"); + String presentation = parameterPresentation(parameterIndex); + assertEquals(expectedString, presentation); } - public void testIgnoreVarargs() throws Exception { - doTestPresentation("Class<T> a, Class<? extends CharSequence>... stopAt", 1); - } - - private void doTestPresentation(String expectedString) { - doTestPresentation(expectedString, -1); - } - - private void doTestPresentation(String expectedString, int currentParameterIndex) { - configureByFile(BASE_PATH + getTestName(false) + ".java"); - - final MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); - final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile); - final PsiExpressionList list = handler.findElementForParameterInfo(context); + private String parameterPresentation(int parameterIndex) { + MethodParameterInfoHandler handler = new MethodParameterInfoHandler(); + CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile()); + PsiExpressionList list = handler.findElementForParameterInfo(context); assertNotNull(list); - final Object[] itemsToShow = context.getItemsToShow(); + Object[] itemsToShow = context.getItemsToShow(); assertNotNull(itemsToShow); assertEquals(1, itemsToShow.length); assertTrue(itemsToShow[0] instanceof MethodCandidateInfo); - final PsiMethod method = ((MethodCandidateInfo)itemsToShow[0]).getElement(); - final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, - currentParameterIndex); - Assert.assertEquals(expectedString, - MethodParameterInfoHandler - .updateMethodPresentation(method, ((MethodCandidateInfo)itemsToShow[0]).getSubstitutor(), parameterContext)); + PsiMethod method = ((MethodCandidateInfo)itemsToShow[0]).getElement(); + ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, getEditor(), handler, parameterIndex); + PsiSubstitutor substitutor = ((MethodCandidateInfo)itemsToShow[0]).getSubstitutor(); + return MethodParameterInfoHandler.updateMethodPresentation(method, substitutor, parameterContext); } - public void testAnnotationWithGenerics() throws Exception { - doTestAnnotationPresentation("Class<List<String[]>> value()"); + public void testAnnotationWithGenerics() { + myFixture.configureByFile(getTestName(false) + ".java"); + String text = annoParameterPresentation(); + assertEquals("Class<List<String[]>> value()", text); } - private void doTestAnnotationPresentation(String expectedString) { - configureByFile(BASE_PATH + getTestName(false) + ".java"); - - String text = invokeParameterInfoForAnnotations(); - Assert.assertEquals(expectedString, text); - } - - private static String invokeParameterInfoForAnnotations() { - final AnnotationParameterInfoHandler handler = new AnnotationParameterInfoHandler(); - final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile); - final PsiAnnotationParameterList list = handler.findElementForParameterInfo(context); + private String annoParameterPresentation() { + AnnotationParameterInfoHandler handler = new AnnotationParameterInfoHandler(); + CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile()); + PsiAnnotationParameterList list = handler.findElementForParameterInfo(context); assertNotNull(list); - final Object[] itemsToShow = context.getItemsToShow(); + Object[] itemsToShow = context.getItemsToShow(); assertNotNull(itemsToShow); assertEquals(1, itemsToShow.length); assertTrue(itemsToShow[0] instanceof PsiAnnotationMethod); - final PsiAnnotationMethod method = (PsiAnnotationMethod)itemsToShow[0]; - final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, -1); + PsiAnnotationMethod method = (PsiAnnotationMethod)itemsToShow[0]; + ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, getEditor(), handler, -1); return AnnotationParameterInfoHandler.updateUIText(method, parameterContext); } -} + + public void testParameterAnnotation() { + myFixture.addClass("import java.lang.annotation.*;\n@Documented @Target({ElementType.PARAMETER}) @interface TA { }"); + myFixture.configureByText("a.java", "class C {\n void m(@TA String s) { }\n void t() { m(\"test\"); }\n}"); + assertEquals("@TA String s", parameterPresentation(-1)); + } + + public void testParameterUndocumentedAnnotation() { + myFixture.addClass("import java.lang.annotation.*;\n@Target({ElementType.PARAMETER}) @interface TA { }"); + myFixture.configureByText("a.java", "class C {\n void m(@TA String s) { }\n void t() { m(\"test\"); }\n}"); + assertEquals("String s", parameterPresentation(-1)); + } + + public void testParameterTypeAnnotation() { + myFixture.addClass("import java.lang.annotation.*;\n@Documented @Target({ElementType.PARAMETER, ElementType.TYPE_USE}) @interface TA { }"); + myFixture.configureByText("a.java", "class C {\n void m(@TA String s) { }\n void t() { m(\"test\"); }\n}"); + assertEquals("@TA String s", parameterPresentation(-1)); + } + + public void testParameterUndocumentedTypeAnnotation() { + myFixture.addClass("import java.lang.annotation.*;\n@Target({ElementType.PARAMETER, ElementType.TYPE_USE}) @interface TA { }"); + myFixture.configureByText("a.java", "class C {\n void m(@TA String s) { }\n void t() { m(\"test\"); }\n}"); + assertEquals("@TA String s", parameterPresentation(-1)); + } +} \ No newline at end of file