package com.intellij.logging.highlighting import com.intellij.jvm.analysis.internal.testFramework.logging.LoggingPlaceholderAnnotatorTestBase class JavaLoggingPlaceholderAnnotatorTest : LoggingPlaceholderAnnotatorTestBase() { override val fileName: String = "Logging.java" fun `test log4j2 default log`() = doTest( """ import org.apache.logging.log4j.*; class Logging { public static final Logger LOG = LogManager.getLogger(); void m(Integer fst, Integer snd) { LOG.debug("{} {}", fst, snd); LOG.info("{} {}", fst, snd); LOG.trace("{} {}", fst, snd); LOG.warn("{} {}", fst, snd); LOG.error("{} {}", fst, snd); LOG.fatal("{} {}", fst, snd); LOG.log(Level.ALL, "{} {}", fst, snd); } }""") fun `test log4j2 formatter log`() = doTest(""" import org.apache.logging.log4j.*; class Logging { public static final Logger LOG = LogManager.getFormatterLogger(); void m(Integer fst, Integer snd) { LOG.debug("%s %s", fst, snd); LOG.info("%s %s", fst, snd); LOG.trace("%s %s", fst, snd); LOG.warn("%s %s", fst, snd); LOG.error("%s %s", fst, snd); LOG.fatal("%s %s", fst, snd); LOG.log(Level.ALL, "%s %s", fst, snd); } } """.trimIndent()) fun `test log4j2 default log builder`() = doTest(""" import org.apache.logging.log4j.*; class Logging { public static final Logger LOG = LogManager.getLogger(); void m(Integer fst, Integer snd) { LOG.atDebug().log("{} {}", fst, snd); LOG.atInfo().log("{} {}", fst, snd); LOG.atWarn().log("{} {}", fst, snd); LOG.atError().log("{} {}", fst, snd); LOG.atFatal().log("{} {}", fst, snd); LOG.atTrace().log("{} {}", fst, snd); LOG.atLevel(Level.ALL).log("{} {}", fst, snd); } } """.trimIndent()) fun `test log4j2 formatter log builder`() = doTest(""" import org.apache.logging.log4j.*; class Logging { public static final Logger LOG = LogManager.getFormatterLogger(); void m(Integer fst, Integer snd) { LOG.atDebug().log("%s %s", fst, snd); LOG.atInfo().log("%s %s", fst, snd); LOG.atWarn().log("%s %s", fst, snd); LOG.atError().log("%s %s", fst, snd); LOG.atFatal().log("%s %s", fst, snd); LOG.atTrace().log("%s %s", fst, snd); LOG.atLevel(Level.ALL).log("%s %s", fst, snd); } } """.trimIndent()) fun `test log4j2 formatter log with previous placeholder`() = doTest(""" import org.apache.logging.log4j.*; class Logging { public static final Logger LOG = LogManager.getFormatterLogger(); void m(Integer fst, Integer snd) { LOG.atDebug().log("%s %", fst); LOG.debug("%s %", fst); } } ""${'"'}.trimIndent()) """.trimIndent()) fun `test log4j2 formatter log with numbered placeholder`() { val dollar = "$" doTest(""" import org.apache.logging.log4j.*; class Logging { private static final Logger LOG = LogManager.getFormatterLogger(); void foo(Integer fst, Integer snd, Integer thrd) { LOG.info("%1${dollar}s %2${dollar}s %3${dollar}s", fst, snd, thrd); LOG.info("%2${dollar}s %3${dollar}s %1${dollar}s %s %s %s", fst, snd, thrd); } } """.trimIndent()) } fun `test log4j2 respects exception`() = doTest(""" import org.apache.logging.log4j.*; class Logging { public static final Logger LOG = LogManager.getLogger(); void m(Integer fst) { LOG.info("{} {}", fst, new Exception()); LOG.info("{}", new Exception()); } } """.trimIndent()) fun `test log4j2 builder respects exception`() = doTest(""" import org.apache.logging.log4j.*; class Logging { public static final Logger LOG = LogManager.getLogger(); void m(Integer fst) { LOG.atInfo().log("{} {}", fst, new Exception()); LOG.atInfo().log("{}", new Exception()); LOG.atInfo().withThrowable(new Exception()).log("{}"); } } """.trimIndent()) fun `test slf4j default log`() = doTest(""" import org.slf4j.*; class Logging { public static final Logger LOG = LoggerFactory.getLogger(Logging.class); void m(Integer fst, Integer snd) { LOG.debug("{} {}", fst, snd); LOG.info("{} {}", fst, snd); LOG.trace("{} {}", fst, snd); LOG.warn("{} {}", fst, snd); LOG.error("{} {}", fst, snd); } } """.trimIndent()) fun `test slf4j default log builder`() = doTest(""" import org.slf4j.*; class Logging { public static final Logger LOG = LoggerFactory.getLogger(Logging.class); void m(Integer fst, Integer snd) { LOG.atInfo().log("{} {}", fst, snd); LOG.atDebug().log("{} {}", fst, snd); LOG.atWarn().log("{} {}", fst, snd); LOG.atError().log("{} {}", fst, snd); LOG.atTrace().log("{} {}", fst, snd); } } """.trimIndent()) fun `test slf4j default log builder with setMessage and addArgument`() = doTest(""" import org.slf4j.*; class Logging { public static final Logger LOG = LoggerFactory.getLogger(Logging.class); void m(Integer fst, Integer snd) { LOG.atInfo().addArgument(fst).addArgument(snd).setMessage("{} {}").log(); LOG.atInfo().addArgument(fst).addArgument(snd).setMessage("{} {}").setMessage("{} {}").log(); LOG.atInfo().addArgument(fst).addArgument(snd).log("{} {}"); LOG.atInfo().addArgument(fst).log("{} {}", snd); } } """.trimIndent()) fun `test slf4j respects exception`() = doTest(""" import org.slf4j.*; class Logging { public static final Logger LOG = LoggerFactory.getLogger(Logging.class); void m(Integer fst, Integer snd) { LOG.info("{} {}", fst, new Exception()); LOG.info("{}", new Exception()); } } """.trimIndent()) fun `test slf4j builder respects exception`() = doTest( """ import org.slf4j.*; class Logging { public static final Logger LOG = LoggerFactory.getLogger(Logging.class); void m(Integer fst, Integer snd) { LOG.atInfo().log("{} {}", fst, new Exception()); LOG.atInfo().log("{}", new Exception()); LOG.atInfo().addArgument(fst).addArgument(new Exception()).setMessage("{} {}").log(); LOG.atInfo().addArgument(fst).setCause(new Exception()).setMessage("{} {}").log(); LOG.atInfo().addArgument(fst).setCause(new Exception()).log("{} {}"); } } """.trimIndent() ) fun `test support multiline string`() { val multilineString = "\"\"\" \n" + " {} {} {}\n \n" + " \n \n \"\"\"" doTest(""" import org.slf4j.*; class Logging { public static final Logger LOG = LoggerFactory.getLogger(Logging.class); void m(Integer fst, Integer snd) { LOG.info($multilineString, fst, snd); } } """.trimIndent()) } fun `test does not support string concatenation`() = doTest(""" import org.slf4j.* class Logging { public static final Logger LOG = LoggerFactory.getLogger(Logging.class); void m(Integer fst, Integer snd) { LOG.info("{} {}" + " foo bar", fst, snd); } } """.trimIndent()) fun `test lazy init`() = doTest(""" import org.apache.logging.log4j.LogBuilder; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; class LazyInitializer { static class StaticInitializer { private static final Logger log; static { log = LogManager.getLogger(); } public StaticInitializer() { log.info("{}", 1); } } static class StaticInitializerBuilder { private static final LogBuilder log; static { log = LogManager.getLogger().atDebug(); } public StaticInitializerBuilder() { log.log("{}", "arg"); } } static class StaticInitializerBuilder2 { private static final LogBuilder log; static { if (1 == 1) { log = LogManager.getLogger().atDebug(); } else { log = LogManager.getFormatterLogger().atDebug(); } } public StaticInitializerBuilder2() { log.log("{}", 1); } } static class ConstructorInitializer { private final Logger log; public ConstructorInitializer() { log = LogManager.getLogger(); } public ConstructorInitializer(int i) { log = LogManager.getLogger(); } public void test() { log.info("{} {}", 2, 1); } } static class ConstructorInitializer2 { private final Logger log; public ConstructorInitializer2() { log = LogManager.getFormatterLogger(); } public ConstructorInitializer2(int i) { log = LogManager.getLogger(); } public void test() { log.info("{}", 1); } } } """.trimIndent()) }