Skip to content

Commit a5e76ba

Browse files
Add support for scala 2/3 compatible macros
A lot of things were removed that the original scala-logging repo was leveraging heavily: - Build/deploy definitions (these can easily be restored) - LoggerTakingImplicits (couldn't get the version-unifying project to build with implicits being involved in the macros for some reason) - Scala 2.11 and 2.12 support (cross-version macro support is limited to very specific versions of Scala 2.13 and Scala 3) This commit represents the beginning of the Lucid Software branch of the scala-logging library. Due to the major changes, it should never be merged back into the scala-logging library, but it can serve as a starting point for those interested in attempting to bridge the compatibility gap between this library and Scala 2 + 3 in a less destructive way.
1 parent d78215d commit a5e76ba

File tree

26 files changed

+284
-1664
lines changed

26 files changed

+284
-1664
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.typesafe.scalalogging
2+
3+
import org.mockito.Mockito._
4+
import org.scalatest.wordspec.AnyWordSpec
5+
import org.scalatestplus.mockito.MockitoSugar
6+
import org.slf4j.{ Logger => Underlying }
7+
8+
class Scala2 extends AnyWordSpec with MockitoSugar {
9+
10+
"Calling Logger from Scala 2" should {
11+
"work" in {
12+
val f = fixture(_.isInfoEnabled, isEnabled = true)
13+
import f._
14+
15+
logger.info("message")
16+
verify(underlying).info("message")
17+
}
18+
}
19+
20+
private def fixture(p: Underlying => Boolean, isEnabled: Boolean) = new LoggerF(p, isEnabled)
21+
private class LoggerF(p: Underlying => Boolean, isEnabled: Boolean) {
22+
val msg = "msg"
23+
val cause = new RuntimeException("cause")
24+
val arg1 = "arg1"
25+
val arg2 = Integer.valueOf(1)
26+
val arg3 = "arg3"
27+
val arg4 = 4
28+
val arg4ref = arg4.asInstanceOf[AnyRef]
29+
val arg5 = true
30+
val arg5ref = arg5.asInstanceOf[AnyRef]
31+
val arg6 = 6L
32+
val arg6ref = arg6.asInstanceOf[AnyRef]
33+
val arg7 = new Throwable
34+
val arg7ref = arg7.asInstanceOf[AnyRef]
35+
val underlying = mock[org.slf4j.Logger]
36+
when(p(underlying)).thenReturn(isEnabled)
37+
val logger = Logger(underlying)
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.typesafe.scalalogging
2+
3+
import org.mockito.Mockito._
4+
import org.scalatest.wordspec.AnyWordSpec
5+
import org.scalatestplus.mockito.MockitoSugar
6+
import org.slf4j.{ Logger => Underlying }
7+
8+
class Scala3 extends AnyWordSpec with MockitoSugar {
9+
10+
"Calling Logger from Scala 3" should {
11+
"work" in {
12+
val f = fixture(_.isInfoEnabled, isEnabled = true)
13+
import f._
14+
15+
logger.info("message")
16+
verify(underlying).info("message")
17+
}
18+
}
19+
20+
private def fixture(p: Underlying => Boolean, isEnabled: Boolean) = new LoggerF(p, isEnabled)
21+
private class LoggerF(p: Underlying => Boolean, isEnabled: Boolean) {
22+
val msg = "msg"
23+
val cause = new RuntimeException("cause")
24+
val arg1 = "arg1"
25+
val arg2 = Integer.valueOf(1)
26+
val arg3 = "arg3"
27+
val arg4 = 4
28+
val arg4ref = arg4.asInstanceOf[AnyRef]
29+
val arg5 = true
30+
val arg5ref = arg5.asInstanceOf[AnyRef]
31+
val arg6 = 6L
32+
val arg6ref = arg6.asInstanceOf[AnyRef]
33+
val arg7 = new Throwable
34+
val arg7ref = arg7.asInstanceOf[AnyRef]
35+
val underlying = mock[org.slf4j.Logger]
36+
when(p(underlying)).thenReturn(isEnabled)
37+
val logger = Logger(underlying)
38+
}
39+
}

build.sbt

+37-50
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,42 @@
1-
// basics
1+
ThisBuild / scalaVersion := "3.0.2"
2+
val scala213 = "2.13.8"
23

3-
name := "scala-logging"
4-
crossScalaVersions := Seq("3.0.2", "2.11.12", "2.12.15", "2.13.8")
5-
scalaVersion := crossScalaVersions.value.head
6-
ThisBuild / versionScheme := Some("early-semver")
7-
scalacOptions ++= Seq(
8-
"-unchecked",
9-
"-deprecation",
10-
"-language:_",
11-
"-encoding", "UTF-8",
12-
"-Ywarn-unused"
13-
)
14-
incOptions := incOptions.value.withLogRecompileOnMacro(false)
15-
val isScala3 = Def.setting {
16-
CrossVersion.partialVersion(scalaVersion.value).exists(_._1 != 2)
17-
}
18-
libraryDependencies ++= Dependencies.scalaLogging(scalaVersion.value, isScala3.value)
19-
initialCommands := """|import com.typesafe.scalalogging._
20-
|import org.slf4j.{ Logger => Underlying, _ }""".stripMargin
21-
22-
// OSGi
4+
lazy val scalalogging2 = project
5+
.settings(
6+
name := "scala-logging2",
7+
scalaVersion := scala213,
8+
libraryDependencies ++= Dependencies.scalaLogging(scala213, false)
9+
)
2310

24-
import com.typesafe.sbt.osgi.SbtOsgi
25-
enablePlugins(SbtOsgi)
26-
osgiSettings
27-
OsgiKeys.bundleSymbolicName := "com.typesafe.scala-logging"
28-
OsgiKeys.privatePackage := Seq()
29-
OsgiKeys.exportPackage := Seq("com.typesafe.scalalogging*")
11+
lazy val scalalogging3 = project
12+
.settings(
13+
name := "scala-logging3",
14+
scalaVersion := "3.0.2",
15+
libraryDependencies ++= Dependencies.scalaLogging("3.0.2", true)
16+
)
3017

31-
// publishing
18+
lazy val scalalogging = project
19+
.dependsOn(scalalogging2, scalalogging3)
20+
.settings(
21+
name := "scala-logging",
22+
scalaVersion := "3.0.2",
23+
libraryDependencies ++= Dependencies.scalaLogging("3.0.2", true),
24+
)
3225

33-
organization := "com.typesafe.scala-logging"
34-
sonatypeProfileName := "com.typesafe"
35-
licenses := Seq("Apache 2.0 License" -> url("http://www.apache.org/licenses/LICENSE-2.0.html"))
36-
homepage := Some(url("https://github.com/lightbend/scala-logging"))
37-
Test / publishArtifact := false
38-
pomIncludeRepository := (_ => false)
39-
scmInfo := Some(
40-
ScmInfo(url("https://github.com/lightbend/scala-logging"), "scm:git:[email protected]:lightbend/scala-logging.git")
41-
)
42-
developers := List(
43-
Developer(
44-
id = "hseeberger",
45-
name = "Heiko Seeberger",
46-
email = "",
47-
url = url("http://heikoseeberger.de")
48-
),
49-
Developer(
50-
id = "analytically",
51-
name = "Mathias Bogaert",
52-
email = "",
53-
url = url("http://twitter.com/analytically")
26+
lazy val app2 = project
27+
.dependsOn(scalalogging)
28+
.settings(
29+
name := "app2",
30+
scalaVersion := scala213,
31+
scalacOptions := Seq("-Ytasty-reader"),
32+
libraryDependencies ++= Dependencies.scalaLogging(scala213, false),
33+
libraryDependencies += Library.logbackClassic
5434
)
55-
)
35+
36+
lazy val app3 = project
37+
.dependsOn(scalalogging)
38+
.settings(
39+
name := "app3",
40+
libraryDependencies ++= Dependencies.scalaLogging("3.0.2", true),
41+
libraryDependencies += Library.logbackClassic
42+
)

project/Dependencies.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import sbt._
33
object Version {
44
val logback = "1.2.10"
55
val mockito = "3.2.10.0"
6-
val scalaTest = "3.2.11"
7-
val slf4j = "1.7.36"
6+
val scalaTest = "3.2.10"
7+
val slf4j = "1.7.33"
88
}
99

1010
object Library {

project/build.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=1.6.2
1+
sbt.version=1.6.1

project/plugins.sbt

-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
11
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.3")
2-
addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.9.6")
3-
addSbtPlugin("com.scalapenos" % "sbt-prompt" % "1.0.2")
4-
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.10")

src/main/scala/com/typesafe/scalalogging/Logger.scala renamed to scalalogging/src/main/scala/com/typesafe/scalalogging/Logger.scala

+8-8
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ object Logger {
1717
/**
1818
* Create a [[LoggerTakingImplicit]] wrapping the given underlying `org.slf4j.Logger`.
1919
*/
20-
def takingImplicit[A](underlying: Underlying)(implicit ev: CanLog[A]): LoggerTakingImplicit[A] =
21-
new LoggerTakingImplicit[A](underlying)
20+
// def takingImplicit[A](underlying: Underlying)(implicit ev: CanLog[A]): LoggerTakingImplicit[A] =
21+
// new LoggerTakingImplicit[A](underlying)
2222

2323
/**
2424
* Create a [[Logger]] for the given name.
@@ -37,8 +37,8 @@ object Logger {
3737
* val logger = Logger.takingImplicit[CorrelationId]("application")
3838
* }}}
3939
*/
40-
def takingImplicit[A](name: String)(implicit ev: CanLog[A]): LoggerTakingImplicit[A] =
41-
new LoggerTakingImplicit[A](LoggerFactory.getLogger(name))
40+
// def takingImplicit[A](name: String)(implicit ev: CanLog[A]): LoggerTakingImplicit[A] =
41+
// new LoggerTakingImplicit[A](LoggerFactory.getLogger(name))
4242

4343
/**
4444
* Create a [[Logger]] wrapping the created underlying `org.slf4j.Logger`.
@@ -49,8 +49,8 @@ object Logger {
4949
/**
5050
* Create a [[LoggerTakingImplicit]] wrapping the created underlying `org.slf4j.Logger`.
5151
*/
52-
def takingImplicit[A](clazz: Class[_])(implicit ev: CanLog[A]): LoggerTakingImplicit[A] =
53-
new LoggerTakingImplicit[A](LoggerFactory.getLogger(clazz.getName))
52+
// def takingImplicit[A](clazz: Class[_])(implicit ev: CanLog[A]): LoggerTakingImplicit[A] =
53+
// new LoggerTakingImplicit[A](LoggerFactory.getLogger(clazz.getName))
5454

5555
/**
5656
* Create a [[Logger]] for the runtime class wrapped by the implicit class
@@ -71,8 +71,8 @@ object Logger {
7171
* val logger = Logger.takingImplicit[MyClass, CorrelationId]
7272
* }}}
7373
*/
74-
def takingImplicit[T, A](implicit ct: ClassTag[T], ev: CanLog[A]): LoggerTakingImplicit[A] =
75-
new LoggerTakingImplicit[A](LoggerFactory.getLogger(ct.runtimeClass.getName.stripSuffix("$")))
74+
// def takingImplicit[T, A](implicit ct: ClassTag[T], ev: CanLog[A]): LoggerTakingImplicit[A] =
75+
// new LoggerTakingImplicit[A](LoggerFactory.getLogger(ct.runtimeClass.getName.stripSuffix("$")))
7676
}
7777

7878
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package com.typesafe.scalalogging
2+
3+
import com.typesafe.scalalogging.{LoggerMacro2, LoggerMacro3}
4+
5+
import org.slf4j.{Marker, Logger as Underlying }
6+
7+
trait LoggerImpl {
8+
def underlying: Underlying
9+
10+
import scala.language.experimental.macros
11+
12+
// Error
13+
14+
def error(message: String): Unit = macro LoggerMacro2.errorMessage
15+
inline def error(inline message: String): Unit = ${LoggerMacro3.errorMessage('underlying, 'message)}
16+
17+
def error(message: String, cause: Throwable): Unit = macro LoggerMacro2.errorMessageCause
18+
inline def error(inline message: String, inline cause: Throwable): Unit = ${LoggerMacro3.errorMessageCause('underlying, 'message, 'cause)}
19+
20+
def error(message: String, args: Any*): Unit = macro LoggerMacro2.errorMessageArgs
21+
inline def error(inline message: String, inline args: Any*): Unit = ${LoggerMacro3.errorMessageArgs('underlying, 'message, 'args)}
22+
23+
def error(marker: Marker, message: String): Unit = macro LoggerMacro2.errorMessageMarker
24+
inline def error(inline marker: Marker, inline message: String): Unit = ${LoggerMacro3.errorMessageMarker('underlying, 'marker, 'message)}
25+
26+
def error(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro2.errorMessageCauseMarker
27+
inline def error(inline marker: Marker, inline message: String, inline cause: Throwable): Unit = ${LoggerMacro3.errorMessageCauseMarker('underlying, 'marker, 'message, 'cause)}
28+
29+
def error(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro2.errorMessageArgsMarker
30+
inline def error(inline marker: Marker, inline message: String, inline args: Any*): Unit = ${LoggerMacro3.errorMessageArgsMarker('underlying, 'marker, 'message, 'args)}
31+
32+
def whenErrorEnabled(body: Unit): Unit = macro LoggerMacro2.errorCode
33+
inline def whenErrorEnabled(inline body: Unit): Unit = ${LoggerMacro3.errorCode('underlying, 'body)}
34+
35+
// Warn
36+
37+
def warn(message: String): Unit = macro LoggerMacro2.warnMessage
38+
inline def warn(inline message: String): Unit = ${LoggerMacro3.warnMessage('underlying, 'message)}
39+
40+
def warn(message: String, cause: Throwable): Unit = macro LoggerMacro2.warnMessageCause
41+
inline def warn(inline message: String, inline cause: Throwable): Unit = ${LoggerMacro3.warnMessageCause('underlying, 'message, 'cause)}
42+
43+
def warn(message: String, args: Any*): Unit = macro LoggerMacro2.warnMessageArgs
44+
inline def warn(inline message: String, inline args: Any*): Unit = ${LoggerMacro3.warnMessageArgs('underlying, 'message, 'args)}
45+
46+
def warn(marker: Marker, message: String): Unit = macro LoggerMacro2.warnMessageMarker
47+
inline def warn(inline marker: Marker, inline message: String): Unit = ${LoggerMacro3.warnMessageMarker('underlying, 'marker, 'message)}
48+
49+
def warn(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro2.warnMessageCauseMarker
50+
inline def warn(inline marker: Marker, inline message: String, inline cause: Throwable): Unit = ${LoggerMacro3.warnMessageCauseMarker('underlying, 'marker, 'message, 'cause)}
51+
52+
def warn(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro2.warnMessageArgsMarker
53+
inline def warn(inline marker: Marker, inline message: String, inline args: Any*): Unit = ${LoggerMacro3.warnMessageArgsMarker('underlying, 'marker, 'message, 'args)}
54+
55+
def whenWarnEnabled(body: Unit): Unit = macro LoggerMacro2.warnCode
56+
inline def whenWarnEnabled(inline body: Unit): Unit = ${LoggerMacro3.warnCode('underlying, 'body)}
57+
58+
// Info
59+
60+
def info(message: String): Unit = macro LoggerMacro2.infoMessage
61+
inline def info(inline message: String): Unit = ${LoggerMacro3.infoMessage('underlying, 'message)}
62+
63+
def info(message: String, cause: Throwable): Unit = macro LoggerMacro2.infoMessageCause
64+
inline def info(inline message: String, inline cause: Throwable): Unit = ${LoggerMacro3.infoMessageCause('underlying, 'message, 'cause)}
65+
66+
def info(message: String, args: Any*): Unit = macro LoggerMacro2.infoMessageArgs
67+
inline def info(inline message: String, inline args: Any*): Unit = ${LoggerMacro3.infoMessageArgs('underlying, 'message, 'args)}
68+
69+
def info(marker: Marker, message: String): Unit = macro LoggerMacro2.infoMessageMarker
70+
inline def info(inline marker: Marker, inline message: String): Unit = ${LoggerMacro3.infoMessageMarker('underlying, 'marker, 'message)}
71+
72+
def info(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro2.infoMessageCauseMarker
73+
inline def info(inline marker: Marker, inline message: String, inline cause: Throwable): Unit = ${LoggerMacro3.infoMessageCauseMarker('underlying, 'marker, 'message, 'cause)}
74+
75+
def info(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro2.infoMessageArgsMarker
76+
inline def info(inline marker: Marker, inline message: String, inline args: Any*): Unit = ${LoggerMacro3.infoMessageArgsMarker('underlying, 'marker, 'message, 'args)}
77+
78+
def whenInfoEnabled(body: Unit): Unit = macro LoggerMacro2.infoCode
79+
inline def whenInfoEnabled(inline body: Unit): Unit = ${LoggerMacro3.infoCode('underlying, 'body)}
80+
81+
// Debug
82+
83+
def debug(message: String): Unit = macro LoggerMacro2.debugMessage
84+
inline def debug(inline message: String): Unit = ${LoggerMacro3.debugMessage('underlying, 'message)}
85+
86+
def debug(message: String, cause: Throwable): Unit = macro LoggerMacro2.debugMessageCause
87+
inline def debug(inline message: String, inline cause: Throwable): Unit = ${LoggerMacro3.debugMessageCause('underlying, 'message, 'cause)}
88+
89+
def debug(message: String, args: Any*): Unit = macro LoggerMacro2.debugMessageArgs
90+
inline def debug(inline message: String, inline args: Any*): Unit = ${LoggerMacro3.debugMessageArgs('underlying, 'message, 'args)}
91+
92+
def debug(marker: Marker, message: String): Unit = macro LoggerMacro2.debugMessageMarker
93+
inline def debug(inline marker: Marker, inline message: String): Unit = ${LoggerMacro3.debugMessageMarker('underlying, 'marker, 'message)}
94+
95+
def debug(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro2.debugMessageCauseMarker
96+
inline def debug(inline marker: Marker, inline message: String, inline cause: Throwable): Unit = ${LoggerMacro3.debugMessageCauseMarker('underlying, 'marker, 'message, 'cause)}
97+
98+
def debug(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro2.debugMessageArgsMarker
99+
inline def debug(inline marker: Marker, inline message: String, inline args: Any*): Unit = ${LoggerMacro3.debugMessageArgsMarker('underlying, 'marker, 'message, 'args)}
100+
101+
def whenDebugEnabled(body: Unit): Unit = macro LoggerMacro2.debugCode
102+
inline def whenDebugEnabled(inline body: Unit): Unit = ${LoggerMacro3.debugCode('underlying, 'body)}
103+
104+
// Trace
105+
106+
def trace(message: String): Unit = macro LoggerMacro2.traceMessage
107+
inline def trace(inline message: String): Unit = ${LoggerMacro3.traceMessage('underlying, 'message)}
108+
109+
def trace(message: String, cause: Throwable): Unit = macro LoggerMacro2.traceMessageCause
110+
inline def trace(inline message: String, inline cause: Throwable): Unit = ${LoggerMacro3.traceMessageCause('underlying, 'message, 'cause)}
111+
112+
def trace(message: String, args: Any*): Unit = macro LoggerMacro2.traceMessageArgs
113+
inline def trace(inline message: String, inline args: Any*): Unit = ${LoggerMacro3.traceMessageArgs('underlying, 'message, 'args)}
114+
115+
def trace(marker: Marker, message: String): Unit = macro LoggerMacro2.traceMessageMarker
116+
inline def trace(inline marker: Marker, inline message: String): Unit = ${LoggerMacro3.traceMessageMarker('underlying, 'marker, 'message)}
117+
118+
def trace(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro2.traceMessageCauseMarker
119+
inline def trace(inline marker: Marker, inline message: String, inline cause: Throwable): Unit = ${LoggerMacro3.traceMessageCauseMarker('underlying, 'marker, 'message, 'cause)}
120+
121+
def trace(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro2.traceMessageArgsMarker
122+
inline def trace(inline marker: Marker, inline message: String, inline args: Any*): Unit = ${LoggerMacro3.traceMessageArgsMarker('underlying, 'marker, 'message, 'args)}
123+
124+
def whenTraceEnabled(body: Unit): Unit = macro LoggerMacro2.traceCode
125+
inline def whenTraceEnabled(inline body: Unit): Unit = ${LoggerMacro3.traceCode('underlying, 'body)}
126+
}

0 commit comments

Comments
 (0)