From 8f06d4fbadbc1e5b8e98daf343c729e0512af6bd Mon Sep 17 00:00:00 2001 From: Konstantin Nisht Date: Wed, 21 Oct 2020 19:49:36 +0300 Subject: [PATCH] [groovy] IDEA-251327: Add inspection for calls with implicit null GitOrigin-RevId: 66d8c31982330f201cd08043a44752577c013b9c --- .../GroovyImplicitNullArgumentCall.html | 20 ++++++++++++ .../messages/GroovyBundle.properties | 2 ++ ...roovyImplicitNullArgumentCallInspection.kt | 31 +++++++++++++++++++ plugins/groovy/src/META-INF/plugin.xml | 4 +++ 4 files changed, 57 insertions(+) create mode 100644 plugins/groovy/groovy-psi/resources/inspectionDescriptions/GroovyImplicitNullArgumentCall.html create mode 100644 plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyImplicitNullArgumentCallInspection.kt diff --git a/plugins/groovy/groovy-psi/resources/inspectionDescriptions/GroovyImplicitNullArgumentCall.html b/plugins/groovy/groovy-psi/resources/inspectionDescriptions/GroovyImplicitNullArgumentCall.html new file mode 100644 index 000000000000..282871133496 --- /dev/null +++ b/plugins/groovy/groovy-psi/resources/inspectionDescriptions/GroovyImplicitNullArgumentCall.html @@ -0,0 +1,20 @@ + + +Reports calls with no arguments to method that has exactly one parameter. +This is equivalent to call with null, and that behavior is often confusing and unintended. +
+Example: +
+
+    def foo(String s){}
+
+    foo()
+
+Will be executed as following: +
+    def foo(String s){}
+
+    foo(null)
+
+ + diff --git a/plugins/groovy/groovy-psi/resources/messages/GroovyBundle.properties b/plugins/groovy/groovy-psi/resources/messages/GroovyBundle.properties index cfc17ee8115f..1901333c343e 100644 --- a/plugins/groovy/groovy-psi/resources/messages/GroovyBundle.properties +++ b/plugins/groovy/groovy-psi/resources/messages/GroovyBundle.properties @@ -538,6 +538,7 @@ inspection.display.name.check.labeled.statement=Labeled statement inspection inspection.display.name.variable.can.be.final=Variable can be final inspection.display.name.equals.between.inconvertible.types='equals()' between objects of inconvertible types inspection.display.name.singleton.constructor=@Singleton constructors +inspection.display.name.implicit.null.argument=Implicit null argument inspection.message.access.to.static.field.locked.on.instance.data=Access to static field #ref locked on instance data #loc inspection.message.assignment.replaceable.with.operator.assignment=#ref could be simplified to ''{0}'' #loc inspection.message.assignment.to.for.loop.parameter=Assignment to for-loop parameter '#ref' #loc @@ -638,6 +639,7 @@ inspection.message.unused.catch.parameter.ref=Unused catch parameter '#ref' #loc inspection.message.package.name.mismatch.actual.0.expected.1=Package name mismatch. Actual: ''{0}'', expected: ''{1}'' inspection.message.property.not.indexable.type.must.be.array.or.list.but.found.0=Property is not indexable. Type must be array or list but found {0} inspection.message.type.argument.0.can.not.be.1=Type of argument ''{0}'' can not be ''{1}'' +inspection.message.method.called.with.implicit.null.argument=Method is called with implicit null argument text.class.0.is.unused=Class {0} is unused text.constructor.0.is.unused=Constructor {0} is unused text.method.0.is.unused=Method {0} is unused diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyImplicitNullArgumentCallInspection.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyImplicitNullArgumentCallInspection.kt new file mode 100644 index 000000000000..70a967fe3ace --- /dev/null +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyImplicitNullArgumentCallInspection.kt @@ -0,0 +1,31 @@ +// 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.codeInspection.confusing + +import com.intellij.codeInspection.ProblemHighlightType +import com.intellij.psi.util.parentOfType +import org.jetbrains.plugins.groovy.GroovyBundle +import org.jetbrains.plugins.groovy.codeInspection.BaseInspection +import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor +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 GroovyImplicitNullArgumentCallInspection : BaseInspection() { + + override fun buildErrorString(vararg args: Any?): String { + return GroovyBundle.message("inspection.message.method.called.with.implicit.null.argument") + } + + override fun buildVisitor(): BaseInspectionVisitor = object : BaseInspectionVisitor() { + override fun visitArgumentList(list: GrArgumentList) { + if (list.allArguments.isNotEmpty()) { + return + } + val call = list.parentOfType()?.takeIf { it.argumentList === list } ?: return + if (PsiUtil.isEligibleForInvocationWithNull(call)) { + registerError(list, ProblemHighlightType.WEAK_WARNING) + } + super.visitArgumentList(list) + } + } +} diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 01f8166bbb19..6f4ca85d87e6 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -1075,6 +1075,10 @@ groupKey="inspection.confusing" enabledByDefault="true" implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyGStringKeyInspection"/> +