diff --git a/.gitignore b/.gitignore index 59b5bce..448f384 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ lib_managed/ project/project target/ +.bsp # Worksheets (Eclipse or IntelliJ) *.sc diff --git a/.travis.yml b/.travis.yml index e6f6d24..4d49d23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ scala: - 2.11.12 - 2.12.13 - 2.13.4 - + - 3.0.0-RC1 env: - ADOPTOPENJDK=8 - ADOPTOPENJDK=11 diff --git a/build.sbt b/build.sbt index 92a9908..7421bf2 100644 --- a/build.sbt +++ b/build.sbt @@ -9,10 +9,20 @@ scalacOptions ++= Seq( "-Ywarn-unused" ) incOptions := incOptions.value.withLogRecompileOnMacro(false) -libraryDependencies ++= Dependencies.scalaLogging(scalaVersion.value) +libraryDependencies ++= Dependencies.scalaLogging(scalaVersion.value, isDotty.value) initialCommands := """|import com.typesafe.scalalogging._ |import org.slf4j.{ Logger => Underlying, _ }""".stripMargin +unmanagedSourceDirectories in Compile ++= { + val sourceDir = (sourceDirectory in Compile).value + val extraFilesOpt = CrossVersion.partialVersion(scalaVersion.value) match { + case Some((2, _)) => Some(sourceDir / "scala-2.x") + case Some((3, _)) => Some(sourceDir / "scala-3.x") + case _ => None + } + extraFilesOpt.toSeq +} + // OSGi import com.typesafe.sbt.osgi.SbtOsgi diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 19b2f86..e6b67cd 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,27 +2,29 @@ import sbt._ object Version { val logback = "1.2.3" - val mockito = "1.16.23" - val scalaTest = "3.2.3" + val mockito = "3.2.4.0" + val scalaTest = "3.2.4" val slf4j = "1.7.30" } object Library { - val logbackClassic = "ch.qos.logback" % "logback-classic" % Version.logback - val mockitoScala = "org.mockito" %% "mockito-scala-scalatest" % Version.mockito - def scalaReflect(scalaVersion: String) = "org.scala-lang" % "scala-reflect" % scalaVersion - val scalaTest = "org.scalatest" %% "scalatest" % Version.scalaTest - val slf4jApi = "org.slf4j" % "slf4j-api" % Version.slf4j + val logbackClassic = "ch.qos.logback" % "logback-classic" % Version.logback + val mockitoScala = "org.scalatestplus" %% "mockito-3-4" % Version.mockito + def scalaReflect(scalaVersion: String) = "org.scala-lang" % "scala-reflect" % scalaVersion + val scalaTest = "org.scalatest" %% "scalatest" % Version.scalaTest + val slf4jApi = "org.slf4j" % "slf4j-api" % Version.slf4j } object Dependencies { import Library._ - def scalaLogging(scalaVersion: String) = List( - scalaReflect(scalaVersion), - slf4jApi, - logbackClassic % "test", - mockitoScala % "test", - scalaTest % "test" - ) + def scalaLogging(scalaVersion: String, isDotty: Boolean) = { + List(scalaReflect(scalaVersion)).filter(_ => !isDotty) ++ + List( + slf4jApi, + logbackClassic % "test", + mockitoScala % "test", + scalaTest % "test" + ) + } } diff --git a/project/plugins.sbt b/project/plugins.sbt index e9d6f53..bea7326 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,3 +3,4 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.9.6") addSbtPlugin("com.scalapenos" % "sbt-prompt" % "1.0.2") addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.5") addSbtPlugin("com.dwijnand" % "sbt-travisci" % "1.2.0") +addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.5.3") diff --git a/src/main/scala-2.x/com/typesafe/scalalogging/LoggerImpl.scala b/src/main/scala-2.x/com/typesafe/scalalogging/LoggerImpl.scala new file mode 100644 index 0000000..f1bfcb8 --- /dev/null +++ b/src/main/scala-2.x/com/typesafe/scalalogging/LoggerImpl.scala @@ -0,0 +1,85 @@ +package com.typesafe.scalalogging + +import org.slf4j.Marker +class LoggerImpl { + + // Error + + def error(message: String): Unit = macro LoggerMacro.errorMessage + + def error(message: String, cause: Throwable): Unit = macro LoggerMacro.errorMessageCause + + def error(message: String, args: Any*): Unit = macro LoggerMacro.errorMessageArgs + + def error(marker: Marker, message: String): Unit = macro LoggerMacro.errorMessageMarker + + def error(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.errorMessageCauseMarker + + def error(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.errorMessageArgsMarker + + def whenErrorEnabled(body: Unit): Unit = macro LoggerMacro.errorCode + + // Warn + + def warn(message: String): Unit = macro LoggerMacro.warnMessage + + def warn(message: String, cause: Throwable): Unit = macro LoggerMacro.warnMessageCause + + def warn(message: String, args: Any*): Unit = macro LoggerMacro.warnMessageArgs + + def warn(marker: Marker, message: String): Unit = macro LoggerMacro.warnMessageMarker + + def warn(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.warnMessageCauseMarker + + def warn(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.warnMessageArgsMarker + + def whenWarnEnabled(body: Unit): Unit = macro LoggerMacro.warnCode + + // Info + + def info(message: String): Unit = macro LoggerMacro.infoMessage + + def info(message: String, cause: Throwable): Unit = macro LoggerMacro.infoMessageCause + + def info(message: String, args: Any*): Unit = macro LoggerMacro.infoMessageArgs + + def info(marker: Marker, message: String): Unit = macro LoggerMacro.infoMessageMarker + + def info(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.infoMessageCauseMarker + + def info(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.infoMessageArgsMarker + + def whenInfoEnabled(body: Unit): Unit = macro LoggerMacro.infoCode + + // Debug + + def debug(message: String): Unit = macro LoggerMacro.debugMessage + + def debug(message: String, cause: Throwable): Unit = macro LoggerMacro.debugMessageCause + + def debug(message: String, args: Any*): Unit = macro LoggerMacro.debugMessageArgs + + def debug(marker: Marker, message: String): Unit = macro LoggerMacro.debugMessageMarker + + def debug(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.debugMessageCauseMarker + + def debug(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.debugMessageArgsMarker + + def whenDebugEnabled(body: Unit): Unit = macro LoggerMacro.debugCode + + // Trace + + def trace(message: String): Unit = macro LoggerMacro.traceMessage + + def trace(message: String, cause: Throwable): Unit = macro LoggerMacro.traceMessageCause + + def trace(message: String, args: Any*): Unit = macro LoggerMacro.traceMessageArgs + + def trace(marker: Marker, message: String): Unit = macro LoggerMacro.traceMessageMarker + + def trace(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.traceMessageCauseMarker + + def trace(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.traceMessageArgsMarker + + def whenTraceEnabled(body: Unit): Unit = macro LoggerMacro.traceCode +} \ No newline at end of file diff --git a/src/main/scala/com/typesafe/scalalogging/LoggerMacro.scala b/src/main/scala-2.x/com/typesafe/scalalogging/LoggerMacro.scala similarity index 100% rename from src/main/scala/com/typesafe/scalalogging/LoggerMacro.scala rename to src/main/scala-2.x/com/typesafe/scalalogging/LoggerMacro.scala diff --git a/src/main/scala-2.x/com/typesafe/scalalogging/LoggerTakingImplicitImpl.scala b/src/main/scala-2.x/com/typesafe/scalalogging/LoggerTakingImplicitImpl.scala new file mode 100644 index 0000000..5bf76c3 --- /dev/null +++ b/src/main/scala-2.x/com/typesafe/scalalogging/LoggerTakingImplicitImpl.scala @@ -0,0 +1,77 @@ +package com.typesafe.scalalogging + +import org.slf4j.Marker + +class LoggerTakingImplicitImpl[A] private[scalalogging] { + + // Error + + def error(message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessage[A] + + def error(message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessageCause[A] + + def error(message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessageArgs[A] + + def error(marker: Marker, message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessageMarker[A] + + def error(marker: Marker, message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessageCauseMarker[A] + + def error(marker: Marker, message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessageArgsMarker[A] + + // Warn + + def warn(message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessage[A] + + def warn(message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessageCause[A] + + def warn(message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessageArgs[A] + + def warn(marker: Marker, message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessageMarker[A] + + def warn(marker: Marker, message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessageCauseMarker[A] + + def warn(marker: Marker, message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessageArgsMarker[A] + + // Info + + def info(message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessage[A] + + def info(message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessageCause[A] + + def info(message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessageArgs[A] + + def info(marker: Marker, message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessageMarker[A] + + def info(marker: Marker, message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessageCauseMarker[A] + + def info(marker: Marker, message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessageArgsMarker[A] + + // Debug + + def debug(message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessage[A] + + def debug(message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessageCause[A] + + def debug(message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessageArgs[A] + + def debug(marker: Marker, message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessageMarker[A] + + def debug(marker: Marker, message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessageCauseMarker[A] + + def debug(marker: Marker, message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessageArgsMarker[A] + + // Trace + + def trace(message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessage[A] + + def trace(message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessageCause[A] + + def trace(message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessageArgs[A] + + def trace(marker: Marker, message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessageMarker[A] + + def trace(marker: Marker, message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessageCauseMarker[A] + + def trace(marker: Marker, message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessageArgsMarker[A] + +} \ No newline at end of file diff --git a/src/main/scala/com/typesafe/scalalogging/LoggerTakingImplicitMacro.scala b/src/main/scala-2.x/com/typesafe/scalalogging/LoggerTakingImplicitMacro.scala similarity index 100% rename from src/main/scala/com/typesafe/scalalogging/LoggerTakingImplicitMacro.scala rename to src/main/scala-2.x/com/typesafe/scalalogging/LoggerTakingImplicitMacro.scala diff --git a/src/main/scala-3.x/com/typesafe/scalalogging/LoggerImpl.scala b/src/main/scala-3.x/com/typesafe/scalalogging/LoggerImpl.scala new file mode 100644 index 0000000..9d32826 --- /dev/null +++ b/src/main/scala-3.x/com/typesafe/scalalogging/LoggerImpl.scala @@ -0,0 +1,57 @@ +package com.typesafe.scalalogging + +import org.slf4j.{Marker, Logger as Underlying } + +trait LoggerImpl { + def underlying: Underlying + + + // Error + inline def error(inline message: String): Unit = ${LoggerMacro.errorMessage('underlying, 'message)} + inline def error(inline message: String, inline cause: Throwable): Unit = ${LoggerMacro.errorMessageCause('underlying, 'message, 'cause)} + inline def error(inline message: String, inline args: Any*): Unit = ${LoggerMacro.errorMessageArgs('underlying, 'message, 'args)} + inline def error(inline marker: Marker, inline message: String): Unit = ${LoggerMacro.errorMessageMarker('underlying, 'marker, 'message)} + inline def error(inline marker: Marker, inline message: String, inline cause: Throwable): Unit = ${LoggerMacro.errorMessageCauseMarker('underlying, 'marker, 'message, 'cause)} + inline def error(inline marker: Marker, inline message: String, inline args: Any*): Unit = ${LoggerMacro.errorMessageArgsMarker('underlying, 'marker, 'message, 'args)} + inline def whenErrorEnabled(inline body: Unit): Unit = ${LoggerMacro.errorCode('underlying, 'body)} + + + // Warn + inline def warn(inline message: String): Unit = ${LoggerMacro.warnMessage('underlying, 'message)} + inline def warn(inline message: String, inline cause: Throwable): Unit = ${LoggerMacro.warnMessageCause('underlying, 'message, 'cause)} + inline def warn(inline message: String, inline args: Any*): Unit = ${LoggerMacro.warnMessageArgs('underlying, 'message, 'args)} + inline def warn(inline marker: Marker, inline message: String): Unit = ${LoggerMacro.warnMessageMarker('underlying, 'marker, 'message)} + inline def warn(inline marker: Marker, inline message: String, inline cause: Throwable): Unit = ${LoggerMacro.warnMessageCauseMarker('underlying, 'marker, 'message, 'cause)} + inline def warn(inline marker: Marker, inline message: String, inline args: Any*): Unit = ${LoggerMacro.warnMessageArgsMarker('underlying, 'marker, 'message, 'args)} + inline def whenWarnEnabled(inline body: Unit): Unit = ${LoggerMacro.warnCode('underlying, 'body)} + + + // Info + inline def info(inline message: String): Unit = ${LoggerMacro.infoMessage('underlying, 'message)} + inline def info(inline message: String, inline cause: Throwable): Unit = ${LoggerMacro.infoMessageCause('underlying, 'message, 'cause)} + inline def info(inline message: String, inline args: Any*): Unit = ${LoggerMacro.infoMessageArgs('underlying, 'message, 'args)} + inline def info(inline marker: Marker, inline message: String): Unit = ${LoggerMacro.infoMessageMarker('underlying, 'marker, 'message)} + inline def info(inline marker: Marker, inline message: String, inline cause: Throwable): Unit = ${LoggerMacro.infoMessageCauseMarker('underlying, 'marker, 'message, 'cause)} + inline def info(inline marker: Marker, inline message: String, inline args: Any*): Unit = ${LoggerMacro.infoMessageArgsMarker('underlying, 'marker, 'message, 'args)} + inline def whenInfoEnabled(inline body: Unit): Unit = ${LoggerMacro.infoCode('underlying, 'body)} + + + // Debug + inline def debug(inline message: String): Unit = ${LoggerMacro.debugMessage('underlying, 'message)} + inline def debug(inline message: String, inline cause: Throwable): Unit = ${LoggerMacro.debugMessageCause('underlying, 'message, 'cause)} + inline def debug(inline message: String, inline args: Any*): Unit = ${LoggerMacro.debugMessageArgs('underlying, 'message, 'args)} + inline def debug(inline marker: Marker, inline message: String): Unit = ${LoggerMacro.debugMessageMarker('underlying, 'marker, 'message)} + inline def debug(inline marker: Marker, inline message: String, inline cause: Throwable): Unit = ${LoggerMacro.debugMessageCauseMarker('underlying, 'marker, 'message, 'cause)} + inline def debug(inline marker: Marker, inline message: String, inline args: Any*): Unit = ${LoggerMacro.debugMessageArgsMarker('underlying, 'marker, 'message, 'args)} + inline def whenDebugEnabled(inline body: Unit): Unit = ${LoggerMacro.debugCode('underlying, 'body)} + + + // Trace + inline def trace(inline message: String): Unit = ${LoggerMacro.traceMessage('underlying, 'message)} + inline def trace(inline message: String, inline cause: Throwable): Unit = ${LoggerMacro.traceMessageCause('underlying, 'message, 'cause)} + inline def trace(inline message: String, inline args: Any*): Unit = ${LoggerMacro.traceMessageArgs('underlying, 'message, 'args)} + inline def trace(inline marker: Marker, inline message: String): Unit = ${LoggerMacro.traceMessageMarker('underlying, 'marker, 'message)} + inline def trace(inline marker: Marker, inline message: String, inline cause: Throwable): Unit = ${LoggerMacro.traceMessageCauseMarker('underlying, 'marker, 'message, 'cause)} + inline def trace(inline marker: Marker, inline message: String, inline args: Any*): Unit = ${LoggerMacro.traceMessageArgsMarker('underlying, 'marker, 'message, 'args)} + inline def whenTraceEnabled(inline body: Unit): Unit = ${LoggerMacro.traceCode('underlying, 'body)} +} diff --git a/src/main/scala-3.x/com/typesafe/scalalogging/LoggerMacro.scala b/src/main/scala-3.x/com/typesafe/scalalogging/LoggerMacro.scala new file mode 100644 index 0000000..2013f48 --- /dev/null +++ b/src/main/scala-3.x/com/typesafe/scalalogging/LoggerMacro.scala @@ -0,0 +1,282 @@ +package com.typesafe.scalalogging + +import org.slf4j.Marker +import scala.quoted.* +import org.slf4j.{ Logger as Underlying } + +private[scalalogging] object LoggerMacro { + + // Error + + def errorMessage(underlying: Expr[Underlying], message: Expr[String])(using Quotes): Expr[Unit] = { + val (messageFormat, args) = deconstructInterpolatedMessage(message) + errorMessageArgs(underlying, messageFormat, Expr.ofSeq(args)) + } + + def errorMessageCause(underlying: Expr[Underlying], message: Expr[String], cause: Expr[Throwable]) (using Quotes) = + '{ if ($underlying.isErrorEnabled) $underlying.error($message, $cause) } + + def errorMessageArgs(underlying: Expr[Underlying], message: Expr[String], args: Expr[Seq[Any]]) (using Quotes) = { + val anyRefArgs = formatArgs(args) + if(anyRefArgs.isEmpty) + '{ if ($underlying.isErrorEnabled) $underlying.error($message) } + else if(anyRefArgs.length == 1) + '{ if ($underlying.isErrorEnabled) $underlying.error($message, ${anyRefArgs.head}) } + else + '{ if ($underlying.isErrorEnabled) $underlying.error($message, ${Expr.ofSeq(anyRefArgs)}*) } + } + + def errorMessageMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String]) (using Quotes) = { + val (messageFormat, args) = deconstructInterpolatedMessage(message) + errorMessageArgsMarker(underlying, marker, messageFormat, Expr.ofSeq(args)) + } + + def errorMessageCauseMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String], cause: Expr[Throwable]) (using Quotes) = + '{ if ($underlying.isErrorEnabled($marker)) $underlying.error($marker, $message, $cause) } + + def errorMessageArgsMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String], args: Expr[Seq[Any]]) (using Quotes) = { + val anyRefArgs = formatArgs(args) + if(anyRefArgs.isEmpty) + '{ if ($underlying.isErrorEnabled($marker)) $underlying.error($marker, $message) } + else if(anyRefArgs.length == 1) + '{if ($underlying.isErrorEnabled($marker)) $underlying.error($marker, $message, ${anyRefArgs.head}) } + else + '{ if ($underlying.isErrorEnabled($marker)) $underlying.error($marker, $message, ${Expr.ofSeq(anyRefArgs)}*) } + } + + def errorCode(underlying: Expr[Underlying], body: Expr[Unit]) (using Quotes) = + '{ if ($underlying.isErrorEnabled) $body } + + + + + // Warn + + def warnMessage(underlying: Expr[Underlying], message: Expr[String])(using Quotes): Expr[Unit] = { + val (messageFormat, args) = deconstructInterpolatedMessage(message) + warnMessageArgs(underlying, messageFormat, Expr.ofSeq(args)) + } + + def warnMessageCause(underlying: Expr[Underlying], message: Expr[String], cause: Expr[Throwable]) (using Quotes) = + '{ if ($underlying.isWarnEnabled) $underlying.warn($message, $cause) } + + def warnMessageArgs(underlying: Expr[Underlying], message: Expr[String], args: Expr[Seq[Any]]) (using Quotes) = { + val anyRefArgs = formatArgs(args) + if(anyRefArgs.isEmpty) + '{ if ($underlying.isWarnEnabled) $underlying.warn($message) } + else if(anyRefArgs.length == 1) + '{ if ($underlying.isWarnEnabled) $underlying.warn($message, ${anyRefArgs.head}) } + else + '{ if ($underlying.isWarnEnabled) $underlying.warn($message, ${Expr.ofSeq(anyRefArgs)}*) } + } + + def warnMessageMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String]) (using Quotes) = { + val (messageFormat, args) = deconstructInterpolatedMessage(message) + warnMessageArgsMarker(underlying, marker, messageFormat, Expr.ofSeq(args)) + } + + def warnMessageCauseMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String], cause: Expr[Throwable]) (using Quotes) = + '{ if ($underlying.isWarnEnabled($marker)) $underlying.warn($marker, $message, $cause) } + + def warnMessageArgsMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String], args: Expr[Seq[Any]]) (using Quotes) = { + val anyRefArgs = formatArgs(args) + if(anyRefArgs.isEmpty) + '{ if ($underlying.isWarnEnabled($marker)) $underlying.warn($marker, $message) } + else if(anyRefArgs.length == 1) + '{if ($underlying.isWarnEnabled($marker)) $underlying.warn($marker, $message, ${anyRefArgs.head}) } + else + '{ if ($underlying.isWarnEnabled($marker)) $underlying.warn($marker, $message, ${Expr.ofSeq(anyRefArgs)}*) } + } + + def warnCode(underlying: Expr[Underlying], body: Expr[Unit]) (using Quotes) = + '{ if ($underlying.isWarnEnabled) $body } + + + + + // Info + + def infoMessage(underlying: Expr[Underlying], message: Expr[String])(using Quotes): Expr[Unit] = { + val (messageFormat, args) = deconstructInterpolatedMessage(message) + infoMessageArgs(underlying, messageFormat, Expr.ofSeq(args)) + } + + def infoMessageCause(underlying: Expr[Underlying], message: Expr[String], cause: Expr[Throwable]) (using Quotes) = + '{ if ($underlying.isInfoEnabled) $underlying.info($message, $cause) } + + def infoMessageArgs(underlying: Expr[Underlying], message: Expr[String], args: Expr[Seq[Any]]) (using Quotes) = { + val anyRefArgs = formatArgs(args) + if(anyRefArgs.isEmpty) + '{ if ($underlying.isInfoEnabled) $underlying.info($message) } + else if(anyRefArgs.length == 1) + '{ if ($underlying.isInfoEnabled) $underlying.info($message, ${anyRefArgs.head}) } + else + '{ if ($underlying.isInfoEnabled) $underlying.info($message, ${Expr.ofSeq(anyRefArgs)}*) } + } + + def infoMessageMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String]) (using Quotes) = { + val (messageFormat, args) = deconstructInterpolatedMessage(message) + infoMessageArgsMarker(underlying, marker, messageFormat, Expr.ofSeq(args)) + } + + def infoMessageCauseMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String], cause: Expr[Throwable]) (using Quotes) = + '{ if ($underlying.isInfoEnabled($marker)) $underlying.info($marker, $message, $cause) } + + def infoMessageArgsMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String], args: Expr[Seq[Any]]) (using Quotes) = { + val anyRefArgs = formatArgs(args) + if(anyRefArgs.isEmpty) + '{ if ($underlying.isInfoEnabled($marker)) $underlying.info($marker, $message) } + else if(anyRefArgs.length == 1) + '{if ($underlying.isInfoEnabled($marker)) $underlying.info($marker, $message, ${anyRefArgs.head}) } + else + '{ if ($underlying.isInfoEnabled($marker)) $underlying.info($marker, $message, ${Expr.ofSeq(anyRefArgs)}*) } + } + + def infoCode(underlying: Expr[Underlying], body: Expr[Unit]) (using Quotes) = + '{ if ($underlying.isInfoEnabled) $body } + + + + + + // Debug + + def debugMessage(underlying: Expr[Underlying], message: Expr[String])(using Quotes): Expr[Unit] = { + val (messageFormat, args) = deconstructInterpolatedMessage(message) + debugMessageArgs(underlying, messageFormat, Expr.ofSeq(args)) + } + + def debugMessageCause(underlying: Expr[Underlying], message: Expr[String], cause: Expr[Throwable]) (using Quotes) = + '{ if ($underlying.isDebugEnabled) $underlying.debug($message, $cause) } + + def debugMessageArgs(underlying: Expr[Underlying], message: Expr[String], args: Expr[Seq[Any]]) (using Quotes) = { + val anyRefArgs = formatArgs(args) + if(anyRefArgs.isEmpty) + '{ if ($underlying.isDebugEnabled) $underlying.debug($message) } + else if(anyRefArgs.length == 1) + '{ if ($underlying.isDebugEnabled) $underlying.debug($message, ${anyRefArgs.head}) } + else + '{ if ($underlying.isDebugEnabled) $underlying.debug($message, ${Expr.ofSeq(anyRefArgs)}*) } + } + + def debugMessageMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String]) (using Quotes) = { + val (messageFormat, args) = deconstructInterpolatedMessage(message) + debugMessageArgsMarker(underlying, marker, messageFormat, Expr.ofSeq(args)) + } + + def debugMessageCauseMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String], cause: Expr[Throwable]) (using Quotes) = + '{ if ($underlying.isDebugEnabled($marker)) $underlying.debug($marker, $message, $cause) } + + def debugMessageArgsMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String], args: Expr[Seq[Any]]) (using Quotes) = { + val anyRefArgs = formatArgs(args) + if(anyRefArgs.isEmpty) + '{ if ($underlying.isDebugEnabled($marker)) $underlying.debug($marker, $message) } + else if(anyRefArgs.length == 1) + '{if ($underlying.isDebugEnabled($marker)) $underlying.debug($marker, $message, ${anyRefArgs.head}) } + else + '{ if ($underlying.isDebugEnabled($marker)) $underlying.debug($marker, $message, ${Expr.ofSeq(anyRefArgs)}*) } + } + + def debugCode(underlying: Expr[Underlying], body: Expr[Unit]) (using Quotes) = + '{ if ($underlying.isDebugEnabled) $body } + + + + + // Trace + + def traceMessage(underlying: Expr[Underlying], message: Expr[String])(using Quotes): Expr[Unit] = { + val (messageFormat, args) = deconstructInterpolatedMessage(message) + traceMessageArgs(underlying, messageFormat, Expr.ofSeq(args)) + } + + def traceMessageCause(underlying: Expr[Underlying], message: Expr[String], cause: Expr[Throwable]) (using Quotes) = + '{ if ($underlying.isTraceEnabled) $underlying.trace($message, $cause) } + + def traceMessageArgs(underlying: Expr[Underlying], message: Expr[String], args: Expr[Seq[Any]]) (using Quotes) = { + val anyRefArgs = formatArgs(args) + if(anyRefArgs.isEmpty) + '{ if ($underlying.isTraceEnabled) $underlying.trace($message) } + else if(anyRefArgs.length == 1) + '{ if ($underlying.isTraceEnabled) $underlying.trace($message, ${anyRefArgs.head}) } + else + '{ if ($underlying.isTraceEnabled) $underlying.trace($message, ${Expr.ofSeq(anyRefArgs)}*) } + } + + def traceMessageMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String]) (using Quotes) = { + val (messageFormat, args) = deconstructInterpolatedMessage(message) + traceMessageArgsMarker(underlying, marker, messageFormat, Expr.ofSeq(args)) + } + + def traceMessageCauseMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String], cause: Expr[Throwable]) (using Quotes) = + '{ if ($underlying.isTraceEnabled($marker)) $underlying.trace($marker, $message, $cause) } + + def traceMessageArgsMarker(underlying: Expr[Underlying], marker: Expr[Marker], message: Expr[String], args: Expr[Seq[Any]]) (using Quotes) = { + val anyRefArgs = formatArgs(args) + if(anyRefArgs.isEmpty) + '{ if ($underlying.isTraceEnabled($marker)) $underlying.trace($marker, $message) } + else if(anyRefArgs.length == 1) + '{if ($underlying.isTraceEnabled($marker)) $underlying.trace($marker, $message, ${anyRefArgs.head}) } + else + '{ if ($underlying.isTraceEnabled($marker)) $underlying.trace($marker, $message, ${Expr.ofSeq(anyRefArgs)}*) } + } + + def traceCode(underlying: Expr[Underlying], body: Expr[Unit]) (using Quotes) = + '{ if ($underlying.isTraceEnabled) $body } + + + + /** Checks whether `message` is an interpolated string and transforms it into SLF4J string interpolation. */ + private def deconstructInterpolatedMessage(message: Expr[String])(using Quotes): (Expr[String], Seq[Expr[Any]]) = { + import quotes.reflect.* + import util.* + + message.asTerm match{ + case Inlined(_, _, Apply(Select(Apply(Select(Select(_, "StringContext"), _), messageNode), _), argumentsNode)) => + val messageTextPartsOpt: Option[List[String]] = + messageNode.collectFirst{ + case Typed(Repeated(ls, _), _) => + ls.collect{ case Literal(StringConstant(s)) => s} + } + val argsOpt: Option[List[Term]] = + argumentsNode.collectFirst { + case Typed(Repeated(ls, _), _) => ls + } + + (messageTextPartsOpt, argsOpt) match{ + case (Some(messageTextParts), Some(args)) => + val format = messageTextParts.iterator + // Emulate standard interpolator escaping + .map(StringContext.processEscapes) + // Escape literal slf4j format anchors if the resulting call will require a format string + .map(str => if (args.nonEmpty) str.replace("{}", "\\{}") else str) + .mkString("{}") + + val formatArgs = args.map(_.asExpr) + + (Expr(format), formatArgs) + case _ => + (message, Seq.empty) + } + case _ => (message, Seq.empty) + } + } + def formatArgs(args: Expr[Seq[Any]])(using q: Quotes): Seq[Expr[AnyRef]] = { + import quotes.reflect.* + import util.* + + args.asTerm match { + case p@Inlined(_, _, Typed(Repeated(v, _),_)) => + v.map{ + case t if t.tpe <:< TypeRepr.of[AnyRef] => t.asExprOf[AnyRef] + case t => '{${t.asExpr}.asInstanceOf[AnyRef]} + } + case Repeated(v, _) => + v.map{ + case t if t.tpe <:< TypeRepr.of[AnyRef] => t.asExprOf[AnyRef] + case t => '{${t.asExpr}.asInstanceOf[AnyRef]} + } + case _ => Seq.empty + } + } +} diff --git a/src/main/scala-3.x/com/typesafe/scalalogging/LoggerTakingImplicitImpl.scala b/src/main/scala-3.x/com/typesafe/scalalogging/LoggerTakingImplicitImpl.scala new file mode 100644 index 0000000..7d77745 --- /dev/null +++ b/src/main/scala-3.x/com/typesafe/scalalogging/LoggerTakingImplicitImpl.scala @@ -0,0 +1,117 @@ +package com.typesafe.scalalogging + +import org.slf4j.{Marker, Logger as Underlying } + +trait LoggerTakingImplicitImpl[A] { + def underlying: Underlying + implicit val canLogEv: CanLog[A] + + + // Error + + inline def error(inline message: String)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.errorMessage('underlying, 'canLogEv, 'message)('a)} + + inline def error(inline message: String, inline cause: Throwable)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.errorMessageCause('underlying, 'canLogEv, 'message, 'cause)('a)} + + inline def error(inline message: String, inline args: Any*)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.errorMessageArgs('underlying, 'canLogEv, 'message, 'args)('a)} + + inline def error(inline marker: Marker, inline message: String)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.errorMessageMarker('underlying, 'canLogEv, 'marker, 'message)('a)} + + inline def error(inline marker: Marker, inline message: String, inline cause: Throwable)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.errorMessageCauseMarker('underlying, 'canLogEv, 'marker, 'message, 'cause)('a)} + + inline def error(inline marker: Marker, inline message: String, inline args: Any*)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.errorMessageArgsMarker('underlying, 'canLogEv, 'marker,'message, 'args)('a)} + + + + // Warn + + inline def warn(inline message: String)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.warnMessage('underlying, 'canLogEv, 'message)('a)} + + inline def warn(inline message: String, inline cause: Throwable)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.warnMessageCause('underlying, 'canLogEv, 'message, 'cause)('a)} + + inline def warn(inline message: String, inline args: Any*)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.warnMessageArgs('underlying, 'canLogEv, 'message, 'args)('a)} + + inline def warn(inline marker: Marker, inline message: String)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.warnMessageMarker('underlying, 'canLogEv, 'marker, 'message)('a)} + + inline def warn(inline marker: Marker, inline message: String, inline cause: Throwable)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.warnMessageCauseMarker('underlying, 'canLogEv, 'marker, 'message, 'cause)('a)} + + inline def warn(inline marker: Marker, inline message: String, inline args: Any*)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.warnMessageArgsMarker('underlying, 'canLogEv, 'marker,'message, 'args)('a)} + + + + // Info + + inline def info(inline message: String)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.infoMessage('underlying, 'canLogEv, 'message)('a)} + + inline def info(inline message: String, inline cause: Throwable)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.infoMessageCause('underlying, 'canLogEv, 'message, 'cause)('a)} + + inline def info(inline message: String, inline args: Any*)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.infoMessageArgs('underlying, 'canLogEv, 'message, 'args)('a)} + + inline def info(inline marker: Marker, inline message: String)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.infoMessageMarker('underlying, 'canLogEv, 'marker, 'message)('a)} + + inline def info(inline marker: Marker, inline message: String, inline cause: Throwable)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.infoMessageCauseMarker('underlying, 'canLogEv, 'marker, 'message, 'cause)('a)} + + inline def info(inline marker: Marker, inline message: String, inline args: Any*)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.infoMessageArgsMarker('underlying, 'canLogEv, 'marker,'message, 'args)('a)} + + + + // Debug + + inline def debug(inline message: String)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.debugMessage('underlying, 'canLogEv, 'message)('a)} + + inline def debug(inline message: String, inline cause: Throwable)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.debugMessageCause('underlying, 'canLogEv, 'message, 'cause)('a)} + + inline def debug(inline message: String, inline args: Any*)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.debugMessageArgs('underlying, 'canLogEv, 'message, 'args)('a)} + + inline def debug(inline marker: Marker, inline message: String)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.debugMessageMarker('underlying, 'canLogEv, 'marker, 'message)('a)} + + inline def debug(inline marker: Marker, inline message: String, inline cause: Throwable)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.debugMessageCauseMarker('underlying, 'canLogEv, 'marker, 'message, 'cause)('a)} + + inline def debug(inline marker: Marker, inline message: String, inline args: Any*)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.debugMessageArgsMarker('underlying, 'canLogEv, 'marker,'message, 'args)('a)} + + + + // Trace + + inline def trace(inline message: String)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.traceMessage('underlying, 'canLogEv, 'message)('a)} + + inline def trace(inline message: String, inline cause: Throwable)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.traceMessageCause('underlying, 'canLogEv, 'message, 'cause)('a)} + + inline def trace(inline message: String, inline args: Any*)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.traceMessageArgs('underlying, 'canLogEv, 'message, 'args)('a)} + + inline def trace(inline marker: Marker, inline message: String)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.traceMessageMarker('underlying, 'canLogEv, 'marker, 'message)('a)} + + inline def trace(inline marker: Marker, inline message: String, inline cause: Throwable)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.traceMessageCauseMarker('underlying, 'canLogEv, 'marker, 'message, 'cause)('a)} + + inline def trace(inline marker: Marker, inline message: String, inline args: Any*)(implicit inline a: A): Unit = + ${LoggerTakingImplicitMacro.traceMessageArgsMarker('underlying, 'canLogEv, 'marker,'message, 'args)('a)} +} diff --git a/src/main/scala-3.x/com/typesafe/scalalogging/LoggerTakingImplicitMacro.scala b/src/main/scala-3.x/com/typesafe/scalalogging/LoggerTakingImplicitMacro.scala new file mode 100644 index 0000000..3df74bb --- /dev/null +++ b/src/main/scala-3.x/com/typesafe/scalalogging/LoggerTakingImplicitMacro.scala @@ -0,0 +1,290 @@ +package com.typesafe.scalalogging + +import org.slf4j.{ Marker, Logger => Underlying } + +import scala.quoted.* + +private[scalalogging] object LoggerTakingImplicitMacro { + + // Error + + def errorMessage[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if($underlying.isErrorEnabled){ + $underlying.error($canLogEv.logMessage($message, $a)) + $canLogEv.afterLog($a) + }} + + def errorMessageCause[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String], cause: Expr[Throwable])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isErrorEnabled) { + $underlying.error($canLogEv.logMessage($message, $a), $cause) + $canLogEv.afterLog($a) + }} + + def errorMessageArgs[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String], args: Expr[Seq[Any]])(a: Expr[A])(using Quotes): Expr[Unit] = { + val formatedArgs = LoggerMacro.formatArgs(args) + if (formatedArgs.length == 1) + '{if ($underlying.isErrorEnabled) { + $underlying.error($canLogEv.logMessage($message, $a), ${formatedArgs.head}) + $canLogEv.afterLog($a) + }} + else + '{if ($underlying.isErrorEnabled) { + $underlying.error($canLogEv.logMessage($message, $a), ${Expr.ofSeq(formatedArgs)}*) + $canLogEv.afterLog($a) + }} + } + + def errorMessageMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isErrorEnabled($marker)) { + $underlying.error($marker, $canLogEv.logMessage($message, $a)) + $canLogEv.afterLog($a) + }} + + def errorMessageCauseMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String], cause: Expr[Throwable])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isErrorEnabled($marker)) { + $underlying.error($marker, $canLogEv.logMessage($message, $a), $cause) + $canLogEv.afterLog($a) + }} + + def errorMessageArgsMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String], args: Expr[Seq[Any]])(a: Expr[A])(using Quotes): Expr[Unit] = { + val formatedArgs = LoggerMacro.formatArgs(args) + if (formatedArgs.length == 1) + '{if ($underlying.isErrorEnabled($marker)) { + $underlying.error($marker, $canLogEv.logMessage($message, $a), ${formatedArgs.head}) + $canLogEv.afterLog($a) + }} + else + '{if ($underlying.isErrorEnabled($marker)) { + $underlying.error($marker, $canLogEv.logMessage($message, $a), ${Expr.ofSeq(formatedArgs)}*) + $canLogEv.afterLog($a) + }} + } + + + + + // Warn + + def warnMessage[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if($underlying.isWarnEnabled){ + $underlying.warn($canLogEv.logMessage($message, $a)) + $canLogEv.afterLog($a) + }} + + def warnMessageCause[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String], cause: Expr[Throwable])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isWarnEnabled) { + $underlying.warn($canLogEv.logMessage($message, $a), $cause) + $canLogEv.afterLog($a) + }} + + def warnMessageArgs[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String], args: Expr[Seq[Any]])(a: Expr[A])(using Quotes): Expr[Unit] = { + val formatedArgs = LoggerMacro.formatArgs(args) + if (formatedArgs.length == 1) + '{if ($underlying.isWarnEnabled) { + $underlying.warn($canLogEv.logMessage($message, $a), ${formatedArgs.head}) + $canLogEv.afterLog($a) + }} + else + '{if ($underlying.isWarnEnabled) { + $underlying.warn($canLogEv.logMessage($message, $a), ${Expr.ofSeq(formatedArgs)}*) + $canLogEv.afterLog($a) + }} + } + + def warnMessageMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isWarnEnabled($marker)) { + $underlying.warn($marker, $canLogEv.logMessage($message, $a)) + $canLogEv.afterLog($a) + }} + + def warnMessageCauseMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String], cause: Expr[Throwable])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isWarnEnabled($marker)) { + $underlying.warn($marker, $canLogEv.logMessage($message, $a), $cause) + $canLogEv.afterLog($a) + }} + + def warnMessageArgsMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String], args: Expr[Seq[Any]])(a: Expr[A])(using Quotes): Expr[Unit] = { + val formatedArgs = LoggerMacro.formatArgs(args) + if (formatedArgs.length == 1) + '{if ($underlying.isWarnEnabled($marker)) { + $underlying.warn($marker, $canLogEv.logMessage($message, $a), ${formatedArgs.head}) + $canLogEv.afterLog($a) + }} + else + '{if ($underlying.isWarnEnabled($marker)) { + $underlying.warn($marker, $canLogEv.logMessage($message, $a), ${Expr.ofSeq(formatedArgs)}*) + $canLogEv.afterLog($a) + }} + } + + + + + // Info + + def infoMessage[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if($underlying.isInfoEnabled){ + $underlying.info($canLogEv.logMessage($message, $a)) + $canLogEv.afterLog($a) + }} + + def infoMessageCause[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String], cause: Expr[Throwable])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isInfoEnabled) { + $underlying.info($canLogEv.logMessage($message, $a), $cause) + $canLogEv.afterLog($a) + }} + + def infoMessageArgs[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String], args: Expr[Seq[Any]])(a: Expr[A])(using Quotes): Expr[Unit] = { + val formatedArgs = LoggerMacro.formatArgs(args) + if (formatedArgs.length == 1) + '{if ($underlying.isInfoEnabled) { + $underlying.info($canLogEv.logMessage($message, $a), ${formatedArgs.head}) + $canLogEv.afterLog($a) + }} + else + '{if ($underlying.isInfoEnabled) { + $underlying.info($canLogEv.logMessage($message, $a), ${Expr.ofSeq(formatedArgs)}*) + $canLogEv.afterLog($a) + }} + } + + def infoMessageMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isInfoEnabled($marker)) { + $underlying.info($marker, $canLogEv.logMessage($message, $a)) + $canLogEv.afterLog($a) + }} + + def infoMessageCauseMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String], cause: Expr[Throwable])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isInfoEnabled($marker)) { + $underlying.info($marker, $canLogEv.logMessage($message, $a), $cause) + $canLogEv.afterLog($a) + }} + + def infoMessageArgsMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String], args: Expr[Seq[Any]])(a: Expr[A])(using Quotes): Expr[Unit] = { + val formatedArgs = LoggerMacro.formatArgs(args) + if (formatedArgs.length == 1) + '{if ($underlying.isInfoEnabled($marker)) { + $underlying.info($marker, $canLogEv.logMessage($message, $a), ${formatedArgs.head}) + $canLogEv.afterLog($a) + }} + else + '{if ($underlying.isInfoEnabled($marker)) { + $underlying.info($marker, $canLogEv.logMessage($message, $a), ${Expr.ofSeq(formatedArgs)}*) + $canLogEv.afterLog($a) + }} + } + + + + + // Debug + + def debugMessage[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if($underlying.isDebugEnabled){ + $underlying.debug($canLogEv.logMessage($message, $a)) + $canLogEv.afterLog($a) + }} + + def debugMessageCause[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String], cause: Expr[Throwable])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isDebugEnabled) { + $underlying.debug($canLogEv.logMessage($message, $a), $cause) + $canLogEv.afterLog($a) + }} + + def debugMessageArgs[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String], args: Expr[Seq[Any]])(a: Expr[A])(using Quotes): Expr[Unit] = { + val formatedArgs = LoggerMacro.formatArgs(args) + if (formatedArgs.length == 1) + '{if ($underlying.isDebugEnabled) { + $underlying.debug($canLogEv.logMessage($message, $a), ${formatedArgs.head}) + $canLogEv.afterLog($a) + }} + else + '{if ($underlying.isDebugEnabled) { + $underlying.debug($canLogEv.logMessage($message, $a), ${Expr.ofSeq(formatedArgs)}*) + $canLogEv.afterLog($a) + }} + } + + def debugMessageMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isDebugEnabled($marker)) { + $underlying.debug($marker, $canLogEv.logMessage($message, $a)) + $canLogEv.afterLog($a) + }} + + def debugMessageCauseMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String], cause: Expr[Throwable])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isDebugEnabled($marker)) { + $underlying.debug($marker, $canLogEv.logMessage($message, $a), $cause) + $canLogEv.afterLog($a) + }} + + def debugMessageArgsMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String], args: Expr[Seq[Any]])(a: Expr[A])(using Quotes): Expr[Unit] = { + val formatedArgs = LoggerMacro.formatArgs(args) + if (formatedArgs.length == 1) + '{if ($underlying.isDebugEnabled($marker)) { + $underlying.debug($marker, $canLogEv.logMessage($message, $a), ${formatedArgs.head}) + $canLogEv.afterLog($a) + }} + else + '{if ($underlying.isDebugEnabled($marker)) { + $underlying.debug($marker, $canLogEv.logMessage($message, $a), ${Expr.ofSeq(formatedArgs)}*) + $canLogEv.afterLog($a) + }} + } + + + + + // Trace + + def traceMessage[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if($underlying.isTraceEnabled){ + $underlying.trace($canLogEv.logMessage($message, $a)) + $canLogEv.afterLog($a) + }} + + def traceMessageCause[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String], cause: Expr[Throwable])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isTraceEnabled) { + $underlying.trace($canLogEv.logMessage($message, $a), $cause) + $canLogEv.afterLog($a) + }} + + def traceMessageArgs[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], message: Expr[String], args: Expr[Seq[Any]])(a: Expr[A])(using Quotes): Expr[Unit] = { + val formatedArgs = LoggerMacro.formatArgs(args) + if (formatedArgs.length == 1) + '{if ($underlying.isTraceEnabled) { + $underlying.trace($canLogEv.logMessage($message, $a), ${formatedArgs.head}) + $canLogEv.afterLog($a) + }} + else + '{if ($underlying.isTraceEnabled) { + $underlying.trace($canLogEv.logMessage($message, $a), ${Expr.ofSeq(formatedArgs)}*) + $canLogEv.afterLog($a) + }} + } + + def traceMessageMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isTraceEnabled($marker)) { + $underlying.trace($marker, $canLogEv.logMessage($message, $a)) + $canLogEv.afterLog($a) + }} + + def traceMessageCauseMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String], cause: Expr[Throwable])(a: Expr[A])(using Quotes): Expr[Unit] = + '{if ($underlying.isTraceEnabled($marker)) { + $underlying.trace($marker, $canLogEv.logMessage($message, $a), $cause) + $canLogEv.afterLog($a) + }} + + def traceMessageArgsMarker[A: Type](underlying: Expr[Underlying], canLogEv: Expr[CanLog[A]], marker: Expr[Marker], message: Expr[String], args: Expr[Seq[Any]])(a: Expr[A])(using Quotes): Expr[Unit] = { + val formatedArgs = LoggerMacro.formatArgs(args) + if (formatedArgs.length == 1) + '{if ($underlying.isTraceEnabled($marker)) { + $underlying.trace($marker, $canLogEv.logMessage($message, $a), ${formatedArgs.head}) + $canLogEv.afterLog($a) + }} + else + '{if ($underlying.isTraceEnabled($marker)) { + $underlying.trace($marker, $canLogEv.logMessage($message, $a), ${Expr.ofSeq(formatedArgs)}*) + $canLogEv.afterLog($a) + }} + } +} \ No newline at end of file diff --git a/src/main/scala/com/typesafe/scalalogging/Logger.scala b/src/main/scala/com/typesafe/scalalogging/Logger.scala index b47adfc..c1310ce 100644 --- a/src/main/scala/com/typesafe/scalalogging/Logger.scala +++ b/src/main/scala/com/typesafe/scalalogging/Logger.scala @@ -1,6 +1,6 @@ package com.typesafe.scalalogging -import org.slf4j.{ LoggerFactory, Marker, Logger => Underlying } +import org.slf4j.{ LoggerFactory, Logger => Underlying } import scala.reflect.ClassTag /** @@ -79,86 +79,4 @@ object Logger { * Implementation of a fast logger based on macros and an underlying `org.slf4j.Logger`. */ @SerialVersionUID(538248225L) -final class Logger private (val underlying: Underlying) extends Serializable { - - // Error - - def error(message: String): Unit = macro LoggerMacro.errorMessage - - def error(message: String, cause: Throwable): Unit = macro LoggerMacro.errorMessageCause - - def error(message: String, args: Any*): Unit = macro LoggerMacro.errorMessageArgs - - def error(marker: Marker, message: String): Unit = macro LoggerMacro.errorMessageMarker - - def error(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.errorMessageCauseMarker - - def error(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.errorMessageArgsMarker - - def whenErrorEnabled(body: Unit): Unit = macro LoggerMacro.errorCode - - // Warn - - def warn(message: String): Unit = macro LoggerMacro.warnMessage - - def warn(message: String, cause: Throwable): Unit = macro LoggerMacro.warnMessageCause - - def warn(message: String, args: Any*): Unit = macro LoggerMacro.warnMessageArgs - - def warn(marker: Marker, message: String): Unit = macro LoggerMacro.warnMessageMarker - - def warn(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.warnMessageCauseMarker - - def warn(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.warnMessageArgsMarker - - def whenWarnEnabled(body: Unit): Unit = macro LoggerMacro.warnCode - - // Info - - def info(message: String): Unit = macro LoggerMacro.infoMessage - - def info(message: String, cause: Throwable): Unit = macro LoggerMacro.infoMessageCause - - def info(message: String, args: Any*): Unit = macro LoggerMacro.infoMessageArgs - - def info(marker: Marker, message: String): Unit = macro LoggerMacro.infoMessageMarker - - def info(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.infoMessageCauseMarker - - def info(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.infoMessageArgsMarker - - def whenInfoEnabled(body: Unit): Unit = macro LoggerMacro.infoCode - - // Debug - - def debug(message: String): Unit = macro LoggerMacro.debugMessage - - def debug(message: String, cause: Throwable): Unit = macro LoggerMacro.debugMessageCause - - def debug(message: String, args: Any*): Unit = macro LoggerMacro.debugMessageArgs - - def debug(marker: Marker, message: String): Unit = macro LoggerMacro.debugMessageMarker - - def debug(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.debugMessageCauseMarker - - def debug(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.debugMessageArgsMarker - - def whenDebugEnabled(body: Unit): Unit = macro LoggerMacro.debugCode - - // Trace - - def trace(message: String): Unit = macro LoggerMacro.traceMessage - - def trace(message: String, cause: Throwable): Unit = macro LoggerMacro.traceMessageCause - - def trace(message: String, args: Any*): Unit = macro LoggerMacro.traceMessageArgs - - def trace(marker: Marker, message: String): Unit = macro LoggerMacro.traceMessageMarker - - def trace(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.traceMessageCauseMarker - - def trace(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.traceMessageArgsMarker - - def whenTraceEnabled(body: Unit): Unit = macro LoggerMacro.traceCode - -} +final class Logger private[scalalogging] (val underlying: Underlying) extends LoggerImpl with Serializable \ No newline at end of file diff --git a/src/main/scala/com/typesafe/scalalogging/LoggerTakingImplicit.scala b/src/main/scala/com/typesafe/scalalogging/LoggerTakingImplicit.scala index 873651e..12faaef 100644 --- a/src/main/scala/com/typesafe/scalalogging/LoggerTakingImplicit.scala +++ b/src/main/scala/com/typesafe/scalalogging/LoggerTakingImplicit.scala @@ -1,6 +1,6 @@ package com.typesafe.scalalogging -import org.slf4j.{ Marker, Logger => Underlying } +import org.slf4j.{ Logger => Underlying } trait CanLog[A] { def logMessage(originalMsg: String, a: A): String @@ -10,76 +10,4 @@ trait CanLog[A] { } @SerialVersionUID(957385465L) -class LoggerTakingImplicit[A] private[scalalogging] (val underlying: Underlying)(implicit val canLogEv: CanLog[A]) extends Serializable { - - // Error - - def error(message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessage[A] - - def error(message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessageCause[A] - - def error(message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessageArgs[A] - - def error(marker: Marker, message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessageMarker[A] - - def error(marker: Marker, message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessageCauseMarker[A] - - def error(marker: Marker, message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.errorMessageArgsMarker[A] - - // Warn - - def warn(message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessage[A] - - def warn(message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessageCause[A] - - def warn(message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessageArgs[A] - - def warn(marker: Marker, message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessageMarker[A] - - def warn(marker: Marker, message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessageCauseMarker[A] - - def warn(marker: Marker, message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.warnMessageArgsMarker[A] - - // Info - - def info(message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessage[A] - - def info(message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessageCause[A] - - def info(message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessageArgs[A] - - def info(marker: Marker, message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessageMarker[A] - - def info(marker: Marker, message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessageCauseMarker[A] - - def info(marker: Marker, message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.infoMessageArgsMarker[A] - - // Debug - - def debug(message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessage[A] - - def debug(message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessageCause[A] - - def debug(message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessageArgs[A] - - def debug(marker: Marker, message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessageMarker[A] - - def debug(marker: Marker, message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessageCauseMarker[A] - - def debug(marker: Marker, message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.debugMessageArgsMarker[A] - - // Trace - - def trace(message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessage[A] - - def trace(message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessageCause[A] - - def trace(message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessageArgs[A] - - def trace(marker: Marker, message: String)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessageMarker[A] - - def trace(marker: Marker, message: String, cause: Throwable)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessageCauseMarker[A] - - def trace(marker: Marker, message: String, args: Any*)(implicit a: A): Unit = macro LoggerTakingImplicitMacro.traceMessageArgsMarker[A] - -} +class LoggerTakingImplicit[A] private[scalalogging] (val underlying: Underlying)(implicit val canLogEv: CanLog[A]) extends LoggerTakingImplicitImpl[A] with Serializable \ No newline at end of file diff --git a/src/test/scala/com/typesafe/scalalogging/LoggerSpec.scala b/src/test/scala/com/typesafe/scalalogging/LoggerSpec.scala index 42ad8bc..6fd90b4 100644 --- a/src/test/scala/com/typesafe/scalalogging/LoggerSpec.scala +++ b/src/test/scala/com/typesafe/scalalogging/LoggerSpec.scala @@ -1,11 +1,12 @@ package com.typesafe.scalalogging -import org.mockito.scalatest.MockitoSugar - import java.io._ import org.slf4j.{ Logger => Underlying } import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec +import org.scalatestplus.mockito.MockitoSugar +import org.mockito.ArgumentMatchers._ +import org.mockito.Mockito._ trait Varargs { // TODO: we used to wrap in List(...): _*, which I assume was to force the varags method to be chosen. @@ -573,21 +574,21 @@ class LoggerSpec extends AnyWordSpec with Matchers with Varargs with MockitoSuga } } - def fixture(p: Underlying => Boolean, isEnabled: Boolean) = - new { - val msg = "msg" - val cause = new RuntimeException("cause") - val arg1 = "arg1" - val arg2 = Integer.valueOf(1) - val arg3 = "arg3" - val arg4 = 4 - val arg4ref = arg4.asInstanceOf[AnyRef] - val arg5 = true - val arg5ref = arg5.asInstanceOf[AnyRef] - val arg6 = 6L - val arg6ref = arg6.asInstanceOf[AnyRef] - val underlying = mock[org.slf4j.Logger] - when(p(underlying)).thenReturn(isEnabled) - val logger = Logger(underlying) - } + private def fixture(p: Underlying => Boolean, isEnabled: Boolean) = new LoggerF(p, isEnabled) + private class LoggerF(p: Underlying => Boolean, isEnabled: Boolean) { + val msg = "msg" + val cause = new RuntimeException("cause") + val arg1 = "arg1" + val arg2 = Integer.valueOf(1) + val arg3 = "arg3" + val arg4 = 4 + val arg4ref = arg4.asInstanceOf[AnyRef] + val arg5 = true + val arg5ref = arg5.asInstanceOf[AnyRef] + val arg6 = 6L + val arg6ref = arg6.asInstanceOf[AnyRef] + val underlying = mock[org.slf4j.Logger] + when(p(underlying)).thenReturn(isEnabled) + val logger = Logger(underlying) + } } diff --git a/src/test/scala/com/typesafe/scalalogging/LoggerTakingImplicitSpec.scala b/src/test/scala/com/typesafe/scalalogging/LoggerTakingImplicitSpec.scala index 55335a7..0c21cea 100644 --- a/src/test/scala/com/typesafe/scalalogging/LoggerTakingImplicitSpec.scala +++ b/src/test/scala/com/typesafe/scalalogging/LoggerTakingImplicitSpec.scala @@ -1,6 +1,8 @@ package com.typesafe.scalalogging -import org.mockito.scalatest.MockitoSugar +import org.mockito.ArgumentMatchers._ +import org.mockito.Mockito._ +import org.scalatestplus.mockito.MockitoSugar import org.slf4j.{ Logger => Underlying } import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec @@ -374,19 +376,19 @@ class LoggerTakingImplicitSpec extends AnyWordSpec with Matchers with Varargs wi } } - def fixture(p: Underlying => Boolean, isEnabled: Boolean, stubCanLog: Boolean = true) = - new { - implicit val correlationId = CorrelationId("corrId") - implicit val canLogCorrelationId = mock[CanLog[CorrelationId]] - val msg = "msg" - val cause = new RuntimeException("cause") - val arg1 = "arg1" - val arg2 = Integer.valueOf(1) - val arg3 = "arg3" - val logMsg = "corrId - msg" - val underlying = mock[org.slf4j.Logger] - when(p(underlying)).thenReturn(isEnabled) - if (stubCanLog) when(canLogCorrelationId.logMessage(any[String], any[CorrelationId])).thenReturn(logMsg) - val logger = Logger.takingImplicit[CorrelationId](underlying) - } + private def fixture(p: Underlying => Boolean, isEnabled: Boolean, stubCanLog: Boolean = true) = new LoggerF(p, isEnabled, stubCanLog) + private class LoggerF(p: Underlying => Boolean, isEnabled: Boolean, stubCanLog: Boolean = true) { + implicit val correlationId: CorrelationId = CorrelationId("corrId") + implicit val canLogCorrelationId: CanLog[CorrelationId] = mock[CanLog[CorrelationId]] + val msg = "msg" + val cause = new RuntimeException("cause") + val arg1 = "arg1" + val arg2 = Integer.valueOf(1) + val arg3 = "arg3" + val logMsg = "corrId - msg" + val underlying = mock[org.slf4j.Logger] + when(p(underlying)).thenReturn(isEnabled) + if (stubCanLog) when(canLogCorrelationId.logMessage(any[String], any[CorrelationId])).thenReturn(logMsg) + val logger = Logger.takingImplicit[CorrelationId](underlying) + } } diff --git a/src/test/scala/com/typesafe/scalalogging/LoggerWithMarkerSpec.scala b/src/test/scala/com/typesafe/scalalogging/LoggerWithMarkerSpec.scala index e15d696..fc88855 100644 --- a/src/test/scala/com/typesafe/scalalogging/LoggerWithMarkerSpec.scala +++ b/src/test/scala/com/typesafe/scalalogging/LoggerWithMarkerSpec.scala @@ -1,12 +1,13 @@ package com.typesafe.scalalogging -import org.mockito.scalatest.MockitoSugar - import java.util.NoSuchElementException import org.slf4j.{ Logger => Underlying } import org.slf4j.Marker import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec +import org.scalatestplus.mockito.MockitoSugar +import org.mockito.ArgumentMatchers._ +import org.mockito.Mockito._ object DummyMarker extends Marker { def add(childMarker: Marker): Unit = {} @@ -365,16 +366,16 @@ class LoggerWithMarkerSpec extends AnyWordSpec with Matchers with Varargs with M } } - def fixture(p: Underlying => Marker => Boolean, isEnabled: Boolean) = - new { - val marker = DummyMarker - val msg = "msg" - val cause = new RuntimeException("cause") - val arg1 = "arg1" - val arg2 = Integer.valueOf(1) - val arg3 = "arg3" - val underlying = mock[org.slf4j.Logger] - when(p(underlying)(marker)).thenReturn(isEnabled) - val logger = Logger(underlying) - } + private def fixture(p: Underlying => Marker => Boolean, isEnabled: Boolean) = new LoggerF(p, isEnabled) + private class LoggerF(p: Underlying => Marker => Boolean, isEnabled: Boolean) { + val marker = DummyMarker + val msg = "msg" + val cause = new RuntimeException("cause") + val arg1 = "arg1" + val arg2 = Integer.valueOf(1) + val arg3 = "arg3" + val underlying = mock[org.slf4j.Logger] + when(p(underlying)(marker)).thenReturn(isEnabled) + val logger = Logger(underlying) + } } diff --git a/src/test/scala/com/typesafe/scalalogging/LoggerWithTaggedArgsSpec.scala b/src/test/scala/com/typesafe/scalalogging/LoggerWithTaggedArgsSpec.scala index 8ade42a..0877682 100644 --- a/src/test/scala/com/typesafe/scalalogging/LoggerWithTaggedArgsSpec.scala +++ b/src/test/scala/com/typesafe/scalalogging/LoggerWithTaggedArgsSpec.scala @@ -1,20 +1,19 @@ package com.typesafe.scalalogging -import org.mockito.scalatest.MockitoSugar import org.slf4j.{ Logger => Underlying } import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec +import org.scalatestplus.mockito.MockitoSugar +import org.mockito.ArgumentMatchers._ +import org.mockito.Mockito._ object tag { - - def apply[U] = new Tagger[U] - trait Tagged[U] type @@[+T, U] = T with Tagged[U] - class Tagger[U] { - def apply[T](t: T): T @@ U = t.asInstanceOf[T @@ U] - } + def taggedString[T](s: String): String @@ T = s.asInstanceOf[String @@ T] + def taggedInteger[T](i: Integer): Integer @@ T = i.asInstanceOf[Integer @@ T] + def taggedBoolean[T](b: Boolean): Boolean @@ T = b.asInstanceOf[Boolean @@ T] } class LoggerWithTaggedArgsSpec extends AnyWordSpec with Matchers with Varargs with MockitoSugar { @@ -29,7 +28,7 @@ class LoggerWithTaggedArgsSpec extends AnyWordSpec with Matchers with Varargs wi noException shouldBe thrownBy { logger.error("This should not throw: {}, {} - {}", arg1, arg2, arg3) } - verify(underlying).error(any[String], *, *, *) + verify(underlying).error(any[String], any, any, any) } "not throw ClassCastException when interpolated message is passed" in { @@ -38,7 +37,7 @@ class LoggerWithTaggedArgsSpec extends AnyWordSpec with Matchers with Varargs wi noException shouldBe thrownBy { logger.error(s"This should not throw: $arg1, $arg2, $arg3") } - verify(underlying).error(any[String], *, *, *) + verify(underlying).error(any[String], any, any, any) } } @@ -50,7 +49,7 @@ class LoggerWithTaggedArgsSpec extends AnyWordSpec with Matchers with Varargs wi noException shouldBe thrownBy { logger.trace("This should not throw: {}, {} - {}", arg1, arg2, arg3) } - verify(underlying).trace(any[String], *, *, *) + verify(underlying).trace(any[String], any, any, any) } "not throw ClassCastException when interpolated message is passed" in { @@ -59,7 +58,7 @@ class LoggerWithTaggedArgsSpec extends AnyWordSpec with Matchers with Varargs wi noException shouldBe thrownBy { logger.trace(s"This should not throw: $arg1, $arg2, $arg3") } - verify(underlying).trace(any[String], *, *, *) + verify(underlying).trace(any[String], any, any, any) } } @@ -71,7 +70,7 @@ class LoggerWithTaggedArgsSpec extends AnyWordSpec with Matchers with Varargs wi noException shouldBe thrownBy { logger.debug("This should not throw: {}, {} - {}", arg1, arg2, arg3) } - verify(underlying).debug(any[String], *, *, *) + verify(underlying).debug(any[String], any, any, any) } "not throw ClassCastException when interpolated message is passed" in { @@ -80,7 +79,7 @@ class LoggerWithTaggedArgsSpec extends AnyWordSpec with Matchers with Varargs wi noException shouldBe thrownBy { logger.debug(s"This should not throw: $arg1, $arg2, $arg3") } - verify(underlying).debug(any[String], *, *, *) + verify(underlying).debug(any[String], any, any, any) } } @@ -92,7 +91,7 @@ class LoggerWithTaggedArgsSpec extends AnyWordSpec with Matchers with Varargs wi noException shouldBe thrownBy { logger.info("This should not throw: {}, {} - {}", arg1, arg2, arg3) } - verify(underlying).info(any[String], *, *, *) + verify(underlying).info(any[String], any, any, any) } "not throw ClassCastException when interpolated message is passed" in { @@ -101,17 +100,17 @@ class LoggerWithTaggedArgsSpec extends AnyWordSpec with Matchers with Varargs wi noException shouldBe thrownBy { logger.info(s"This should not throw: $arg1, $arg2, $arg3") } - verify(underlying).info(any[String], *, *, *) + verify(underlying).info(any[String], any, any, any) } } - def fixture(p: Underlying => Boolean, isEnabled: Boolean = true) = - new { - val arg1 = tag[Tag][String]("arg1") - val arg2 = tag[Tag][Integer](Integer.valueOf(1)) - val arg3 = tag[Tag][Boolean](true) - val underlying = mock[org.slf4j.Logger] - when(p(underlying)).thenReturn(isEnabled) - val logger = Logger(underlying) - } + private def fixture(p: Underlying => Boolean, isEnabled: Boolean = true) = new LoggerF(p, isEnabled) + private class LoggerF(p: Underlying => Boolean, isEnabled: Boolean = true) { + val arg1 = tag.taggedString[Tag]("arg1") + val arg2 = tag.taggedInteger[Tag](Integer.valueOf(1)) + val arg3 = tag.taggedBoolean[Boolean](true) + val underlying = mock[org.slf4j.Logger] + when(p(underlying)).thenReturn(isEnabled) + val logger = Logger(underlying) + } }