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 withnull, and that behavior is often confusing and unintended.
+
+ 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