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 ecff6c9e9e46..a37d59046c11 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 @@ -787,11 +787,21 @@ public final class MethodParameterInfoHandler return html.replaceAll("", "").replaceAll("", ""); } - private static void appendModifierList(@NotNull StringBuilder buffer, @NotNull PsiModifierListOwner owner) { + private static void appendModifierList(@NotNull StringBuilder buffer, @Nullable PsiType type, @NotNull PsiModifierListOwner owner) { if (DumbService.isDumb(owner.getProject())) return; int lastSize = buffer.length(); Set shownAnnotations = new HashSet<>(); + if (type != null) { + PsiAnnotation[] annotations = type.getAnnotations(); + for (PsiAnnotation annotation : annotations) { + final PsiJavaCodeReferenceElement element = annotation.getNameReferenceElement(); + if (element != null) { + String referenceName = element.getReferenceName(); + shownAnnotations.add(referenceName); + } + } + } for (PsiAnnotation annotation : AnnotationUtil.getAllAnnotations(owner, false, null, true)) { final PsiJavaCodeReferenceElement element = annotation.getNameReferenceElement(); if (element != null) { @@ -897,7 +907,7 @@ public final class MethodParameterInfoHandler PsiType paramType = substitutor.substitute(param.getType()); String type = paramType.getPresentableText(!DumbService.isDumb(param.getProject())); StringBuilder buffer = new StringBuilder(); - appendModifierList(buffer, param); + appendModifierList(buffer, paramType, param); String modifiers = buffer.toString(); String name = param.getName(); String javaDoc = JavaDocInfoGeneratorFactory.create(param.getProject(), param).generateMethodParameterJavaDoc(); @@ -915,7 +925,7 @@ public final class MethodParameterInfoHandler PsiType returnType = substitutor.substitute(method.getReturnType()); String type = returnType == null ? "" : returnType.getPresentableText(true); StringBuilder buffer = new StringBuilder(); - appendModifierList(buffer, method); + appendModifierList(buffer, returnType, method); String modifiers = buffer.toString(); List parameters = ContainerUtil.map(method.getParameterList().getParameters(), param -> ParameterPresentation.from(param, substitutor)); diff --git a/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java b/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java index c0bbeb3710fa..9ba3e7a9fd2d 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java @@ -326,7 +326,17 @@ public abstract class PsiNameHelper { else { PsiJavaCodeReferenceElement refElement = annotation.getNameReferenceElement(); if (refElement != null) { - sb.append('@').append(refElement.getText()).append(' '); + String referenceName = refElement.getReferenceName(); + if (referenceName != null) { + sb.append('@').append(referenceName); + } else { + String refElementText = refElement.getText(); + if (!refElementText.startsWith("@")) { + sb.append('@'); + } + sb.append(refElementText); + } + sb.append(' '); updated = true; } } diff --git a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/parameterInfo/FirParameterInfoTestGenerated.java b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/parameterInfo/FirParameterInfoTestGenerated.java index e3fd6b0cdb9b..324ab7059ee6 100644 --- a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/parameterInfo/FirParameterInfoTestGenerated.java +++ b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/parameterInfo/FirParameterInfoTestGenerated.java @@ -103,6 +103,25 @@ public abstract class FirParameterInfoTestGenerated extends AbstractFirParameter } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../../idea/tests/testData/parameterInfo/fromJava") + public static class FromJava extends AbstractFirParameterInfoTest { + @java.lang.Override + @org.jetbrains.annotations.NotNull + public final KotlinPluginMode getPluginMode() { + return KotlinPluginMode.K2; + } + + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("Usage.java") + public void testUsage() throws Exception { + runTest("../../idea/tests/testData/parameterInfo/fromJava/Usage.java"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../../idea/tests/testData/parameterInfo/functionCall") public static class FunctionCall extends AbstractFirParameterInfoTest { diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/parameterInfo/AbstractParameterInfoTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/parameterInfo/AbstractParameterInfoTest.kt index e10a6ce8bba5..cd640bc6fcf4 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/parameterInfo/AbstractParameterInfoTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/parameterInfo/AbstractParameterInfoTest.kt @@ -4,8 +4,10 @@ package org.jetbrains.kotlin.idea.parameterInfo import com.intellij.codeInsight.hint.ShowParameterInfoContext import com.intellij.codeInsight.hint.ShowParameterInfoHandler +import com.intellij.lang.java.JavaLanguage import com.intellij.lang.parameterInfo.ParameterInfoHandler import com.intellij.openapi.util.io.FileUtil +import com.intellij.psi.JavaTokenType import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiElement import com.intellij.psi.PsiWhiteSpace @@ -57,15 +59,16 @@ abstract class AbstractParameterInfoTest : KotlinLightCodeInsightFixtureTestCase myFixture.configureByFile(File(fileName).canonicalPath) - val file = myFixture.file as KtFile + val file = myFixture.file withCustomCompilerOptions(file.text, project, myFixture.module) { val lastChild = file.allChildren.filter { it !is PsiWhiteSpace }.last() val expectedResultText = run { val lines = when (lastChild.node.elementType) { KtTokens.BLOCK_COMMENT -> lastChild.text.substring(2, lastChild.text.length - 2).trim() + JavaTokenType.C_STYLE_COMMENT -> lastChild.text.substring(2, lastChild.text.length - 2).trim() KtTokens.EOL_COMMENT -> lastChild.text.substring(2).trim() - else -> error("Unexpected last file child") + else -> error("Unexpected last file child ${lastChild.node.elementType}") }.lines() lines.mapNotNull { line -> when { @@ -83,10 +86,19 @@ abstract class AbstractParameterInfoTest : KotlinLightCodeInsightFixtureTestCase lateinit var mockCreateParameterInfoContext: MockCreateParameterInfoContext lateinit var parameterOwner: PsiElement executeOnPooledThreadInReadAction { - val handlers = ShowParameterInfoHandler.getHandlers(project, KotlinLanguage.INSTANCE) - @Suppress("UNCHECKED_CAST") - handler = handlers.firstOrNull { it.findElementForParameterInfo(context) != null } as? ParameterInfoHandler - ?: error("Could not find parameter info handler") + if (file is KtFile) { + val handlers = + ShowParameterInfoHandler.getHandlers(project, KotlinLanguage.INSTANCE) + @Suppress("UNCHECKED_CAST") + handler = + handlers.firstOrNull { it.findElementForParameterInfo(context) != null } as? ParameterInfoHandler + ?: error("Could not find parameter info handler") + } else { + val handlers = + ShowParameterInfoHandler.getHandlers(project, JavaLanguage.INSTANCE) + handler = handlers.firstOrNull { it.findElementForParameterInfo(context) != null } as? ParameterInfoHandler + ?: error("Could not find parameter info handler") + } mockCreateParameterInfoContext = MockCreateParameterInfoContext(file, myFixture) parameterOwner = handler.findElementForParameterInfo(mockCreateParameterInfoContext) as PsiElement diff --git a/plugins/kotlin/idea/tests/testData/parameterInfo/fromJava/Usage.extra.kt b/plugins/kotlin/idea/tests/testData/parameterInfo/fromJava/Usage.extra.kt new file mode 100644 index 000000000000..de4477772df0 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/parameterInfo/fromJava/Usage.extra.kt @@ -0,0 +1,6 @@ +package p + +@Target(AnnotationTarget.TYPE) +annotation class MyAnnotation + +class Foo(bar: @MyAnnotation String) \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/parameterInfo/fromJava/Usage.java b/plugins/kotlin/idea/tests/testData/parameterInfo/fromJava/Usage.java new file mode 100644 index 000000000000..07b2d2a372a1 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/parameterInfo/fromJava/Usage.java @@ -0,0 +1,10 @@ +import p.Foo; + +public class Usage { + void usage() { + new Foo(""); + } +} +/* +Text: (@MyAnnotation @NotNull String bar), Disabled: true, Strikeout: false, Green: false +*/