diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index af5a151b788e..5cd616d45e65 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -1457,4 +1457,31 @@ public final class PsiUtil { return GrLiteralImpl.getLiteralValue(element); } + + public static boolean isEligibleForInvocationWithNull(@NotNull GrCall call) { + if (isCompileStatic(call) || call.hasClosureArguments()) { + return false; + } + var argumentList = call.getArgumentList(); + if (argumentList == null || !argumentList.isEmpty()) { + return false; + } + PsiMethod method = call.resolveMethod(); + if (method == null) { + return false; + } + PsiParameterList parameterList = method.getParameterList(); + if (parameterList.getParametersCount() != 1) { + return false; + } + PsiParameter parameter = parameterList.getParameter(0); + if (parameter == null || parameter.isVarArgs() || (parameter instanceof GrParameter && ((GrParameter)parameter).isOptional())) { + return false; + } + PsiTypeElement typeElement = parameter.getTypeElement(); + if (typeElement != null && !(typeElement.getType() instanceof PsiClassType)) { + return false; + } + return true; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyImplicitNullArgumentCollector.kt b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyImplicitNullArgumentCollector.kt index 9b9ebac9b95c..4a436c9a0b39 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyImplicitNullArgumentCollector.kt +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyImplicitNullArgumentCollector.kt @@ -5,14 +5,13 @@ import com.intellij.codeInsight.hints.FactoryInlayHintsCollector import com.intellij.codeInsight.hints.InlayHintsSink import com.intellij.openapi.editor.Editor import com.intellij.psi.PsiElement -import com.intellij.psi.PsiPrimitiveType import com.intellij.psi.util.parentOfType import com.intellij.refactoring.suggested.endOffset import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil -class GroovyImplicitNullArgumentCollector(editor: Editor) : - FactoryInlayHintsCollector(editor) { +class GroovyImplicitNullArgumentCollector(editor: Editor) : FactoryInlayHintsCollector(editor) { override fun collect(element: PsiElement, editor: Editor, sink: InlayHintsSink): Boolean { if (element !is GrArgumentList) { @@ -22,15 +21,9 @@ class GroovyImplicitNullArgumentCollector(editor: Editor) : return true } val methodCall = element.parentOfType()?.takeIf { it.argumentList === element } ?: return true - if (methodCall.hasClosureArguments()) { - return true + if (PsiUtil.isEligibleForInvocationWithNull(methodCall)) { + sink.addInlineElement(element.firstChild.endOffset, true, factory.roundWithBackground(factory.smallText("null")), false) } - val resolvedMethod = methodCall.resolveMethod() ?: return true - if (resolvedMethod.parameterList.parametersCount != 1) return true - if (resolvedMethod.isVarArgs) return true - val parameterTypeElement = resolvedMethod.parameterList.getParameter(0)?.typeElement - if (parameterTypeElement != null && parameterTypeElement.type is PsiPrimitiveType) return true - sink.addInlineElement(element.firstChild.endOffset, true, factory.roundWithBackground(factory.smallText("null")), false) return true } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyImplicitNullArgumentHintProviderTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyImplicitNullArgumentHintProviderTest.groovy index 23932bb0108f..a3eb655241ba 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyImplicitNullArgumentHintProviderTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyImplicitNullArgumentHintProviderTest.groovy @@ -1,12 +1,19 @@ // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.plugins.groovy.codeInsight.hint +import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.utils.inlays.InlayHintsProviderTestCase import groovy.transform.CompileStatic +import org.jetbrains.plugins.groovy.GroovyProjectDescriptors @CompileStatic class GroovyImplicitNullArgumentHintProviderTest extends InlayHintsProviderTestCase { + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return GroovyProjectDescriptors.GROOVY_2_5 + } + def doTest(String text) { testProvider("test.groovy", text, new GroovyImplicitNullArgumentHintProvider(), new GroovyImplicitNullArgumentHintProvider.Settings()) } @@ -50,6 +57,17 @@ class Foo { } new Foo(<# null #>) +""" + } + + void 'test don\'t show hint with @CompileStatic'() { + doTest """ +@groovy.transform.CompileStatic +class Foo { + def foo(String s) {} + + def bar() { foo() } +} """ } }