Skip to content

Commit d01ffc6

Browse files
adriaanmanalytically
authored andcommitted
Upgrade 2.13 (#162)
* RC2 * go to original tree for string interpolator * clarify when varargs should be called Given an overload with options like `(a: A, x: T)` and `(a: A, xs: T*)`, you'll get the first alternative when supplying two arguments: ``` scala> object O { def o(x: Int, y: String) = "1"; def o(x: Int, y: String*) = "multi" } defined object O scala> O.o(1, "a") res0: String = 1 ``` This is true on 2.12 and 2.13. I don't understand what the original code was testing, so I hope I fixed it correctly... * Also use 2.13.0-RC2 in .travis.yml...
1 parent a99abe3 commit d01ffc6

File tree

8 files changed

+106
-80
lines changed

8 files changed

+106
-80
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ language: scala
44
scala:
55
- 2.12.8
66
- 2.11.12
7-
- 2.13.0-M5
7+
- 2.13.0-RC2
88
env:
99
- JDK=oraclejdk8
1010
- JDK=openjdk8

build.sbt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ scalacOptions ++= List(
1717
"-encoding", "UTF-8"
1818
)
1919

20+
// TODO: drop when RC2 artifacts are available for mockito (or 2.13.0 final)
21+
conflictWarning := ConflictWarning.disable
22+
2023
osgiSettings
2124

2225
OsgiKeys.bundleSymbolicName := "com.typesafe.scala-logging"

project/Dependencies.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@ import sbt._
22

33
object Version {
44
val logback = "1.2.3"
5-
val mockito = "1.10.19"
5+
val mockito = "1.4.6"
66
val scala = "2.12.8"
7-
val crossScala = List(scala, "2.11.12", "2.13.0-M5")
8-
val scalaTest = "3.0.6-SNAP6" // only version available for 2.13.0-M4
7+
val crossScala = List(scala, "2.11.12", "2.13.0-RC2")
8+
val scalaTest = "3.0.8-RC4"
99
val slf4j = "1.7.26"
1010
}
1111

1212
object Library {
1313
val logbackClassic = "ch.qos.logback" % "logback-classic" % Version.logback
14-
val mockitoAll = "org.mockito" % "mockito-all" % Version.mockito
14+
def mockitoScala(v: String) =
15+
if (v == "2.13.0-RC2") "org.mockito" % "mockito-scala_2.13.0-RC1" % Version.mockito // TODO: drop when RC2 artifacts are available (or 2.13.0 final)
16+
else "org.mockito" %% "mockito-scala" % Version.mockito
1517
def scalaReflect(scalaVersion: String) = "org.scala-lang" % "scala-reflect" % scalaVersion
1618
val scalaTest = "org.scalatest" %% "scalatest" % Version.scalaTest
1719
val slf4jApi = "org.slf4j" % "slf4j-api" % Version.slf4j
@@ -24,7 +26,7 @@ object Dependencies {
2426
scalaReflect(scalaVersion),
2527
slf4jApi,
2628
logbackClassic % "test",
27-
mockitoAll % "test",
29+
mockitoScala(scalaVersion) % "test",
2830
scalaTest % "test"
2931
)
3032
}

src/main/scala/com/typesafe/scalalogging/LoggerMacro.scala

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,23 @@ private object LoggerMacro {
275275

276276
/** Checks whether `message` is an interpolated string and transforms it into SLF4J string interpolation. */
277277
private def deconstructInterpolatedMessage(c: LoggerContext)(message: c.Expr[String]) = {
278-
import c.universe._
278+
val u: c.universe.type = c.universe
279+
// Eww; gross! In 2.13, the `s` interpolator on StringContext became a macro, so we have to look at the pre-macro
280+
// expansion tree to recover what the user wrote...
281+
val tree: u.Tree = {
282+
// ... but there's no way to do that within scala.reflect.api!
283+
// Worse, MacroExpansionAttachment is in scala-compiler, not scala-reflect, so we don't even have it on the compilation classpath.
284+
// Hence, getClass.getSimplename....
285+
val uInternal = u.asInstanceOf[scala.reflect.internal.SymbolTable]
286+
import uInternal._
287+
message.tree.asInstanceOf[uInternal.Tree].attachments.all.collect {
288+
case orig if orig.getClass.getSimpleName == "MacroExpansionAttachment" => orig.asInstanceOf[{ def expandee: Tree }].expandee.asInstanceOf[u.Tree]
289+
}.headOption.getOrElse(message.tree)
290+
}
291+
292+
import u._
279293

280-
message.tree match {
294+
tree match {
281295
case q"scala.StringContext.apply(..$parts).s(..$args)" =>
282296
val format = parts.iterator.map({ case Literal(Constant(str: String)) => str })
283297
// Emulate standard interpolator escaping

src/main/scala/com/typesafe/scalalogging/package.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ package object scalalogging {
2323
type Seq[+A] = scala.collection.immutable.Seq[A]
2424

2525
type IndexedSeq[+A] = scala.collection.immutable.IndexedSeq[A]
26+
2627
}

src/test/scala/com/typesafe/scalalogging/LoggerSpec.scala

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@ package com.typesafe.scalalogging
1818

1919
import java.io._
2020

21-
import org.mockito.Matchers._
21+
import org.mockito.ArgumentMatchers._
2222
import org.mockito.Mockito._
2323
import org.slf4j.{ Logger => Underlying }
2424
import org.scalatest.{ Matchers, WordSpec }
2525
import org.scalatest.mockito.MockitoSugar
2626

27-
class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
27+
trait Varargs {
28+
// TODO: we used to wrap in List(...): _*, which I assume was to force the varags method to be chosen.
29+
// I encapsulated that here in something that works across 2.12/2.13.
30+
def forceVarargs[T](xs: T*): scala.Seq[T] = scala.Seq(xs: _*)
31+
}
32+
33+
class LoggerSpec extends WordSpec with Matchers with MockitoSugar with Varargs {
2834

2935
// Error
3036

@@ -58,7 +64,7 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
5864
val f = fixture(_.isErrorEnabled, isEnabled = true)
5965
import f._
6066
logger.error(s"msg $arg1 $arg2")
61-
verify(underlying).error("msg {} {}", List(arg1, arg2): _*)
67+
verify(underlying).error("msg {} {}", forceVarargs(arg1, arg2): _*)
6268
}
6369

6470
}
@@ -86,9 +92,9 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
8692
val f = fixture(_.isErrorEnabled, isEnabled = true)
8793
import f._
8894
logger.error(msg, arg1)
89-
verify(underlying).error(msg, List(arg1): _*)
95+
verify(underlying).error(msg, arg1)
9096
logger.error(msg, arg1, arg2)
91-
verify(underlying).error(msg, List(arg1, arg2): _*)
97+
verify(underlying).error(msg, forceVarargs(arg1, arg2): _*)
9298
logger.error(msg, arg1, arg2, arg3)
9399
verify(underlying).error(msg, arg1, arg2, arg3)
94100
}
@@ -97,9 +103,9 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
97103
val f = fixture(_.isErrorEnabled, isEnabled = false)
98104
import f._
99105
logger.error(msg, arg1)
100-
verify(underlying, never).error(msg, List(arg1): _*)
106+
verify(underlying, never).error(msg, arg1)
101107
logger.error(msg, arg1, arg2)
102-
verify(underlying, never).error(msg, List(arg1, arg2): _*)
108+
verify(underlying, never).error(msg, forceVarargs(arg1, arg2): _*)
103109
logger.error(msg, arg1, arg2, arg3)
104110
verify(underlying, never).error(msg, arg1, arg2, arg3)
105111
}
@@ -137,7 +143,7 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
137143
val f = fixture(_.isWarnEnabled, isEnabled = true)
138144
import f._
139145
logger.warn(s"msg $arg1 $arg2")
140-
verify(underlying).warn("msg {} {}", List(arg1, arg2): _*)
146+
verify(underlying).warn("msg {} {}", forceVarargs(arg1, arg2): _*)
141147
}
142148
}
143149

@@ -164,9 +170,9 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
164170
val f = fixture(_.isWarnEnabled, isEnabled = true)
165171
import f._
166172
logger.warn(msg, arg1)
167-
verify(underlying).warn(msg, List(arg1): _*)
173+
verify(underlying).warn(msg, arg1)
168174
logger.warn(msg, arg1, arg2)
169-
verify(underlying).warn(msg, List(arg1, arg2): _*)
175+
verify(underlying).warn(msg, forceVarargs(arg1, arg2): _*)
170176
logger.warn(msg, arg1, arg2, arg3)
171177
verify(underlying).warn(msg, arg1, arg2, arg3)
172178
}
@@ -175,9 +181,9 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
175181
val f = fixture(_.isWarnEnabled, isEnabled = false)
176182
import f._
177183
logger.warn(msg, arg1)
178-
verify(underlying, never).warn(msg, List(arg1): _*)
184+
verify(underlying, never).warn(msg, arg1)
179185
logger.warn(msg, arg1, arg2)
180-
verify(underlying, never).warn(msg, List(arg1, arg2): _*)
186+
verify(underlying, never).warn(msg, forceVarargs(arg1, arg2): _*)
181187
logger.warn(msg, arg1, arg2, arg3)
182188
verify(underlying, never).warn(msg, arg1, arg2, arg3)
183189
}
@@ -215,7 +221,7 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
215221
val f = fixture(_.isInfoEnabled, isEnabled = true)
216222
import f._
217223
logger.info(s"msg $arg1 $arg2")
218-
verify(underlying).info("msg {} {}", List(arg1, arg2): _*)
224+
verify(underlying).info("msg {} {}", forceVarargs(arg1, arg2): _*)
219225
}
220226
}
221227

@@ -242,9 +248,9 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
242248
val f = fixture(_.isInfoEnabled, isEnabled = true)
243249
import f._
244250
logger.info(msg, arg1)
245-
verify(underlying).info(msg, List(arg1): _*)
251+
verify(underlying).info(msg, arg1)
246252
logger.info(msg, arg1, arg2)
247-
verify(underlying).info(msg, List(arg1, arg2): _*)
253+
verify(underlying).info(msg, forceVarargs(arg1, arg2): _*)
248254
logger.info(msg, arg1, arg2, arg3)
249255
verify(underlying).info(msg, arg1, arg2, arg3)
250256
}
@@ -253,9 +259,9 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
253259
val f = fixture(_.isInfoEnabled, isEnabled = false)
254260
import f._
255261
logger.info(msg, arg1)
256-
verify(underlying, never).info(msg, List(arg1): _*)
262+
verify(underlying, never).info(msg, arg1)
257263
logger.info(msg, arg1, arg2)
258-
verify(underlying, never).info(msg, List(arg1, arg2): _*)
264+
verify(underlying, never).info(msg, forceVarargs(arg1, arg2): _*)
259265
logger.info(msg, arg1, arg2, arg3)
260266
verify(underlying, never).info(msg, arg1, arg2, arg3)
261267
}
@@ -292,7 +298,7 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
292298
val f = fixture(_.isDebugEnabled, isEnabled = true)
293299
import f._
294300
logger.debug(s"msg $arg1 $arg2")
295-
verify(underlying).debug("msg {} {}", List(arg1, arg2): _*)
301+
verify(underlying).debug("msg {} {}", forceVarargs(arg1, arg2): _*)
296302
}
297303
}
298304

@@ -319,9 +325,9 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
319325
val f = fixture(_.isDebugEnabled, isEnabled = true)
320326
import f._
321327
logger.debug(msg, arg1)
322-
verify(underlying).debug(msg, List(arg1): _*)
328+
verify(underlying).debug(msg, arg1)
323329
logger.debug(msg, arg1, arg2)
324-
verify(underlying).debug(msg, List(arg1, arg2): _*)
330+
verify(underlying).debug(msg, forceVarargs(arg1, arg2): _*)
325331
logger.debug(msg, arg1, arg2, arg3)
326332
verify(underlying).debug(msg, arg1, arg2, arg3)
327333
}
@@ -330,9 +336,9 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
330336
val f = fixture(_.isDebugEnabled, isEnabled = false)
331337
import f._
332338
logger.debug(msg, arg1)
333-
verify(underlying, never).debug(msg, List(arg1): _*)
339+
verify(underlying, never).debug(msg, arg1)
334340
logger.debug(msg, arg1, arg2)
335-
verify(underlying, never).debug(msg, List(arg1, arg2): _*)
341+
verify(underlying, never).debug(msg, forceVarargs(arg1, arg2): _*)
336342
logger.debug(msg, arg1, arg2, arg3)
337343
verify(underlying, never).debug(msg, arg1, arg2, arg3)
338344
}
@@ -370,7 +376,7 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
370376
val f = fixture(_.isTraceEnabled, isEnabled = true)
371377
import f._
372378
logger.trace(s"msg $arg1 $arg2")
373-
verify(underlying).trace("msg {} {}", List(arg1, arg2): _*)
379+
verify(underlying).trace("msg {} {}", forceVarargs(arg1, arg2): _*)
374380
}
375381
}
376382

@@ -397,9 +403,9 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
397403
val f = fixture(_.isTraceEnabled, isEnabled = true)
398404
import f._
399405
logger.trace(msg, arg1)
400-
verify(underlying).trace(msg, List(arg1): _*)
406+
verify(underlying).trace(msg, arg1)
401407
logger.trace(msg, arg1, arg2)
402-
verify(underlying).trace(msg, List(arg1, arg2): _*)
408+
verify(underlying).trace(msg, forceVarargs(arg1, arg2): _*)
403409
logger.trace(msg, arg1, arg2, arg3)
404410
verify(underlying).trace(msg, arg1, arg2, arg3)
405411
}
@@ -408,9 +414,9 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
408414
val f = fixture(_.isTraceEnabled, isEnabled = false)
409415
import f._
410416
logger.trace(msg, arg1)
411-
verify(underlying, never).trace(msg, List(arg1): _*)
417+
verify(underlying, never).trace(msg, arg1)
412418
logger.trace(msg, arg1, arg2)
413-
verify(underlying, never).trace(msg, List(arg1, arg2): _*)
419+
verify(underlying, never).trace(msg, forceVarargs(arg1, arg2): _*)
414420
logger.trace(msg, arg1, arg2, arg3)
415421
verify(underlying, never).trace(msg, arg1, arg2, arg3)
416422
}
@@ -468,7 +474,7 @@ class LoggerSpec extends WordSpec with Matchers with MockitoSugar {
468474
val f = fixture(_.isErrorEnabled, isEnabled = true)
469475
import f._
470476
logger.error("foo {}, bar {}", arg4, arg5)
471-
verify(underlying).error("foo {}, bar {}", Array(arg4ref, arg5ref): _*)
477+
verify(underlying).error("foo {}, bar {}", forceVarargs(arg4ref, arg5ref): _*)
472478
}
473479

474480
"map args to AnyRef for non 2 args" in {

0 commit comments

Comments
 (0)