mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 06:50:54 +07:00
[uast-inspections] IDEA-354390 Support structured logging for SLF4J
- don't highlight if last arguments are structured arguments GitOrigin-RevId: fb0bf20ff547df4e41c5c6a50e89afe29d149f48
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b5ebbd1b62
commit
71cab9b683
@@ -8,12 +8,15 @@ import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.codeInspection.options.OptPane
|
||||
import com.intellij.codeInspection.util.InspectionMessage
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.util.InheritanceUtil
|
||||
import com.intellij.uast.UastHintedVisitorAdapter
|
||||
import org.jetbrains.uast.UCallExpression
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.visitor.AbstractUastNonRecursiveVisitor
|
||||
|
||||
|
||||
private const val STRUCTURED_ARGUMENT_CLASS = "net.logstash.logback.argument.StructuredArgument"
|
||||
|
||||
class LoggingPlaceholderCountMatchesArgumentCountInspection : AbstractBaseUastLocalInspectionTool() {
|
||||
@JvmField
|
||||
var slf4jToLog4J2Type = Slf4jToLog4J2Type.AUTO
|
||||
@@ -73,12 +76,22 @@ class LoggingPlaceholderCountMatchesArgumentCountInspection : AbstractBaseUastLo
|
||||
if (placeholderCountHolder.count <= finalArgumentCount) ResultType.SUCCESS else ResultType.PARTIAL_PLACE_HOLDER_MISMATCH
|
||||
}
|
||||
else {
|
||||
if (placeholderCountHolder.count == finalArgumentCount) ResultType.SUCCESS else ResultType.PLACE_HOLDER_MISMATCH
|
||||
if (placeholderCountHolder.count == finalArgumentCount) ResultType.SUCCESS else calculateSlf4jStructureLogging(placeholderCountHolder, context, finalArgumentCount)
|
||||
}
|
||||
}
|
||||
PlaceholderLoggerType.SLF4J_EQUAL_PLACEHOLDERS, PlaceholderLoggerType.LOG4J_EQUAL_PLACEHOLDERS, PlaceholderLoggerType.AKKA_PLACEHOLDERS -> {
|
||||
if (placeholderCountHolder.status == PlaceholdersStatus.PARTIAL) {
|
||||
if (placeholderCountHolder.count <= finalArgumentCount) ResultType.SUCCESS else ResultType.PARTIAL_PLACE_HOLDER_MISMATCH
|
||||
if (placeholderCountHolder.count <= finalArgumentCount) {
|
||||
ResultType.SUCCESS
|
||||
}
|
||||
else {
|
||||
if (context.loggerType == PlaceholderLoggerType.SLF4J_EQUAL_PLACEHOLDERS) {
|
||||
calculateSlf4jStructureLogging(placeholderCountHolder, context, finalArgumentCount)
|
||||
}
|
||||
else {
|
||||
ResultType.PARTIAL_PLACE_HOLDER_MISMATCH
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (placeholderCountHolder.count == finalArgumentCount) ResultType.SUCCESS else ResultType.PLACE_HOLDER_MISMATCH
|
||||
@@ -112,6 +125,31 @@ class LoggingPlaceholderCountMatchesArgumentCountInspection : AbstractBaseUastLo
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate results for SLF4J if previous calculation failed and check if arguments can be `StructuredArgument`.
|
||||
* In this case, IDEA shouldn't highlight it because these arguments can be used in json events only
|
||||
*/
|
||||
private fun calculateSlf4jStructureLogging(placeholderCountHolder: PlaceholderCountResult, context: PlaceholderContext, finalArgumentCount: Int): ResultType {
|
||||
if (placeholderCountHolder.count >= finalArgumentCount) {
|
||||
//by default
|
||||
return ResultType.PLACE_HOLDER_MISMATCH
|
||||
}
|
||||
if (placeholderCountHolder.count < 0 || context.placeholderParameters.size < finalArgumentCount) {
|
||||
return ResultType.PLACE_HOLDER_MISMATCH
|
||||
}
|
||||
|
||||
for (argumentIndex in (placeholderCountHolder.count)..<finalArgumentCount) {
|
||||
val argument = context.placeholderParameters.getOrNull(argumentIndex) ?: continue
|
||||
val argumentType = argument.getExpressionType() ?: continue
|
||||
if (argumentType.equalsToText(STRUCTURED_ARGUMENT_CLASS) ||
|
||||
InheritanceUtil.isInheritor(argumentType, STRUCTURED_ARGUMENT_CLASS)) {
|
||||
continue
|
||||
}
|
||||
return ResultType.PLACE_HOLDER_MISMATCH
|
||||
}
|
||||
return ResultType.SUCCESS
|
||||
}
|
||||
|
||||
private fun registerProblem(holder: ProblemsHolder, logStringArgument: UExpression, result: Result) {
|
||||
val errorString = buildErrorString(result)
|
||||
val anchor = logStringArgument.sourcePsi ?: return
|
||||
|
||||
@@ -169,5 +169,16 @@ public interface Logger {
|
||||
LoggingEventBuilder atTrace();
|
||||
}
|
||||
""".trimIndent())
|
||||
fixture.addClass("""
|
||||
package net.logstash.logback.argument;
|
||||
public final class StructuredArguments {
|
||||
public static StructuredArgument kv(Object... object){
|
||||
return new StructuredArgument();}
|
||||
}
|
||||
""".trimIndent())
|
||||
fixture.addClass("""
|
||||
package net.logstash.logback.argument;
|
||||
public class StructuredArgument{}
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
||||
@@ -613,5 +613,47 @@ class JavaLoggingPlaceholderCountMatchesArgumentCountInspectionTest : LoggingPla
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun `test slf4j structured logging`() {
|
||||
inspection.slf4jToLog4J2Type = LoggingPlaceholderCountMatchesArgumentCountInspection.Slf4jToLog4J2Type.NO
|
||||
myFixture.testHighlighting(JvmLanguage.JAVA, """
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import static net.logstash.logback.argument.StructuredArguments.kv;
|
||||
class Demo {
|
||||
public static final Logger log = LoggerFactory.getLogger(Demo.class);
|
||||
public void demo() {
|
||||
log.info(<warning descr="More arguments provided (4) than placeholders specified (2)">"Message1 {} {}"</warning>, 1, //should
|
||||
kv("k1", "v1"), 2,
|
||||
kv("k2", "v2")
|
||||
);
|
||||
log.info("Message2 {} {}", 1, 2,
|
||||
kv("k1", "v1"),
|
||||
kv("k2", "v2")
|
||||
);
|
||||
log.info("Message3 {} {}", 1, 2,
|
||||
kv("k1", "v1"),
|
||||
kv("k2", "v2"), new RuntimeException());
|
||||
log.info(<warning descr="More arguments provided (5) than placeholders specified (2)">"Message4 {} {}"</warning>, 1, 2, //should
|
||||
kv("k1", "v1"),
|
||||
kv("k2", "v2"), 3, new RuntimeException());
|
||||
log.info("Message5 {} {}",
|
||||
kv("k1", "v1"),
|
||||
kv("k2", "v2")
|
||||
);
|
||||
log.atInfo().log("Message6 {} {}", 1,
|
||||
kv("k1", "v1"),
|
||||
kv("k2", "v2"));
|
||||
log.atInfo().log(<warning descr="More arguments provided (4) than placeholders specified (2)">"Message7 {} {}"</warning>, 1, //should
|
||||
kv("k1", "v1"),
|
||||
kv("k2", "v2"), 2);
|
||||
|
||||
log.atInfo().log(<warning descr="More arguments provided (5) than placeholders specified (2)">"Message8 {} {}"</warning>, 1, 2, 3, //should
|
||||
kv("k1", "v1"),
|
||||
kv("k2", "v2"));
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user