[uast-inspection] IDEA-352839 introduce an option to check if calls contain only exception as an argument

GitOrigin-RevId: 8e44bb25369e0c6f936e9aa9a14ea4ddbb348c26
This commit is contained in:
Mikhail Pyltsin
2024-05-22 18:15:09 +02:00
committed by intellij-monorepo-bot
parent a6a4834e74
commit f2c420a40b
6 changed files with 43 additions and 10 deletions

View File

@@ -156,6 +156,7 @@ jvm.inspection.logging.string.template.as.argument.display.name=String template
jvm.inspection.logging.string.template.as.argument.problem.descriptor=String template as argument to <code>#ref()</code> logging call #loc
jvm.inspection.logging.string.template.as.argument.quickfix.name=Replace with placeholders
jvm.inspection.logging.string.template.as.argument.skip.on.primitives=Do not warn when only expressions with primitive types, their wrappers or String are included
jvm.inspection.logging.string.template.as.argument.skip.on.only.exception=Do not warn when call only with an exception as argument.
jvm.inspection.logging.string.template.as.argument.warn.on.label=Warn on:
jvm.inspection.logging.string.template.as.argument.all.levels.option=all log levels
jvm.inspection.logging.string.template.as.argument.warn.level.and.lower.option=warn level and lower

View File

@@ -30,6 +30,9 @@ class LoggingStringTemplateAsArgumentInspection : AbstractBaseUastLocalInspectio
@JvmField
var mySkipPrimitives: Boolean = true
@JvmField
var mySkipWithTheOnlyException: Boolean = false
override fun getOptionsPane(): OptPane {
return OptPane.pane(
OptPane.dropdown(
@@ -47,7 +50,9 @@ class LoggingStringTemplateAsArgumentInspection : AbstractBaseUastLocalInspectio
JvmAnalysisBundle.message("jvm.inspection.logging.string.template.as.argument.trace.level.option")),
),
OptPane.checkbox("mySkipPrimitives",
JvmAnalysisBundle.message("jvm.inspection.logging.string.template.as.argument.skip.on.primitives"))
JvmAnalysisBundle.message("jvm.inspection.logging.string.template.as.argument.skip.on.primitives")),
OptPane.checkbox("mySkipWithTheOnlyException",
JvmAnalysisBundle.message("jvm.inspection.logging.string.template.as.argument.skip.on.only.exception"))
)
}
@@ -113,11 +118,10 @@ class LoggingStringTemplateAsArgumentInspection : AbstractBaseUastLocalInspectio
return true
}
//strange behavior for last parameter as exception. let's ignore this case
val injected = parts.filter { it !is ULiteralExpression }
if ((injected.size == 1 &&
InheritanceUtil.isInheritor(injected.first().getExpressionType(), CommonClassNames.JAVA_LANG_THROWABLE)) ||
((valueArguments.lastIndex - indexStringExpression) == 1 &&
if ((injected.isNotEmpty() &&
InheritanceUtil.isInheritor(injected.last().getExpressionType(), CommonClassNames.JAVA_LANG_THROWABLE)) ||
(mySkipWithTheOnlyException && (valueArguments.lastIndex - indexStringExpression) == 1 &&
InheritanceUtil.isInheritor(valueArguments.last().getExpressionType(), CommonClassNames.JAVA_LANG_THROWABLE))
) {
return true

View File

@@ -23,9 +23,10 @@ class StringTemplateAsArgument {
fun testException(){
var exception = RuntimeException()
loggerLog4J.info("exception: $exception")
val variable1 = 1
loggerLog4J.info("variable1: $variable1", exception)
loggerLog4J.info("variable1: $variable1 exception: $exception")
loggerLog4J.info("exception: $exception")
loggerLog4J.<warning descr="String template as argument to 'info()' logging call">info</warning>("variable1: $variable1", exception)
}
fun testLoggerSlf4J() {
@@ -36,7 +37,7 @@ class StringTemplateAsArgument {
loggerSlf4J.<warning descr="String template as argument to 'info()' logging call">info</warning>("${getInt()}")
loggerSlf4J.<warning descr="String template as argument to 'info()' logging call">info</warning>("variable1: ${variable1}")
loggerSlf4J.<warning descr="String template as argument to 'info()' logging call">info</warning>("variable1: $variable1")
loggerSlf4J.info("variable1: $variable1", RuntimeException())
loggerSlf4J.<warning descr="String template as argument to 'info()' logging call">info</warning>("variable1: $variable1", RuntimeException())
loggerSlf4J.<warning descr="String template as argument to 'info()' logging call">info</warning>("{} variable1: $variable1", 1, RuntimeException())
loggerSlf4J.<warning descr="String template as argument to 'info()' logging call">info</warning>("{} variable1: $variable1 {}", 1, 2, RuntimeException())
loggerSlf4J.<warning descr="String template as argument to 'info()' logging call">info</warning>("{} variable1: $variable1 {} {}", 1, 2, RuntimeException())

View File

@@ -24,7 +24,7 @@ class StringTemplateAsArgumentFix {
loggerSlf4J.info("variable1: {}", variable1)
loggerSlf4J.info("variable1: {}", variable1)
loggerSlf4J.info("variable1: {}", variable1)
loggerSlf4J.info("variable1: $variable1", RuntimeException())
loggerSlf4J.info("variable1: {}", variable1, RuntimeException())
loggerSlf4J.info("{} variable1: {}", 1, variable1)
loggerSlf4J.info("{} variable1: {} {} variable1: {}", 1, variable1, 2, variable1)
loggerSlf4J.info("{} variable1: {} {} variable1: {} {}", 1, variable1, 2, variable1, 3)

View File

@@ -0,0 +1,14 @@
import org.apache.logging.log4j.LogManager
import org.slf4j.LoggerFactory
class StringTemplateAsArgument {
private val loggerLog4J = LogManager.getLogger()
fun testException() {
var exception = RuntimeException()
val variable1 = 1
loggerLog4J.info("variable1: $variable1 exception: $exception")
loggerLog4J.info("exception: $exception")
loggerLog4J.info("variable1: $variable1", exception)
}
}

View File

@@ -2,10 +2,10 @@ package com.intellij.codeInspection.tests.kotlin.logging
import com.intellij.codeInspection.InspectionProfileEntry
import com.intellij.codeInspection.logging.LoggingStringTemplateAsArgumentInspection
import com.intellij.codeInspection.logging.LoggingUtil
import com.intellij.jvm.analysis.KotlinJvmAnalysisTestUtil
import com.intellij.jvm.analysis.internal.testFramework.logging.LoggingStringTemplateAsArgumentInspectionTestBase
import com.intellij.testFramework.TestDataPath
import com.intellij.codeInspection.logging.LoggingUtil
import org.junit.experimental.runners.Enclosed
import org.junit.runner.RunWith
@@ -84,4 +84,17 @@ class KotlinLoggingStringTemplateAsArgumentInspectionTest {
myFixture.testQuickFix(file = "StringTemplateAsArgumentFix.kt", checkPreview = true)
}
}
class TestCaseSkipExceptions : KotlinLoggingStringTemplateAsArgumentInspectionTestBase() {
override val inspection: InspectionProfileEntry
get() = LoggingStringTemplateAsArgumentInspection().apply {
mySkipPrimitives = false
myLimitLevelType = LoggingUtil.LimitLevelType.ALL
mySkipWithTheOnlyException = true
}
fun `test highlighting`() {
myFixture.testHighlighting("StringTemplateAsArgumentSkipException.kt")
}
}
}