@@ -6,7 +6,7 @@ title: Porting a Macro Library
6
6
In this tutorial we will learn two different approaches to migrate a macro library to Scala 3.0:
7
7
- [ Cross-Building] ( #cross-building )
8
8
- [ Mixing Macro Definitions in Scala 3.0] ( #mixing-macro-definitions )
9
- -
9
+
10
10
Each approach makes the library available in Scala 3.0 while maintaining Scala 2.13 compatibility.
11
11
12
12
## A Scala 2 Macro Definition
@@ -249,15 +249,16 @@ We eventually come up with this implementation:
249
249
250
250
package location
251
251
252
- import scala .quoted .{QuoteContext , Expr }
252
+ import scala .quoted .{Quotes , Expr }
253
253
254
254
object Macros :
255
255
inline def location : Location = $ {locationImpl}
256
256
257
- def locationImpl (using ctx : QuoteContext ): Expr [Location ] =
258
- import ctx .reflect .rootPosition
259
- val file = Expr (rootPosition.sourceFile.jpath.toString)
260
- val line = Expr (rootPosition.startLine + 1 )
257
+ private def locationImpl (using ctx : Quotes ): Expr [Location ] =
258
+ import ctx .reflect .Position
259
+ val pos = Position .ofMacroExpansion
260
+ val file = Expr (pos.sourceFile.jpath.toString)
261
+ val line = Expr (pos.startLine + 1 )
261
262
' {new Location ($file, $line)}
262
263
```
263
264
@@ -288,6 +289,8 @@ Then the Scala 2.13 compiler would be able to find that definition in the Scala
288
289
This idea sets the ground to the mixing macros technique that we detail further below using the ` location ` example.
289
290
It is compatible with any build tool that can mix Scala 2.13 and Scala 3.0 modules.
290
291
292
+ > This part of the tutorial is written for @scala3M1 @ because it is the only Tasty Reader compatible version at the time of writing.
293
+
291
294
### 1 - Creating the Scala 3 module
292
295
293
296
Going back to the initial state of our ` location ` library we have:
@@ -319,7 +322,7 @@ We call it `macroLib`.
319
322
lazy val macroLib = project
320
323
.in(file(" macro-lib" ))
321
324
.settings(
322
- scalaVersion := " @scala30 @"
325
+ scalaVersion := " @scala3M1 @"
323
326
)
324
327
.dependsOn(lib)
325
328
```
@@ -331,7 +334,11 @@ lazy val app = project
331
334
.in(file(" app" ))
332
335
.settings(
333
336
scalaVersion := " @scala213@" ,
334
- crossScalaVersion := Seq (" @scala213@" , " @scala30@" )
337
+ crossScalaVersion := Seq (" @scala213@" , " @scala3M1@" ) ,
338
+ scalacOptions ++= {
339
+ if (isDotty.value) Seq ()
340
+ else Seq (" -Ytasty-reader" )
341
+ }
335
342
)
336
343
.dependsOn(macroLib)
337
344
```
@@ -353,6 +360,7 @@ Note that we moved it to a `Scala2Macros` object because we cannot have two `Mac
353
360
354
361
``` scala
355
362
// lib/src/main/scala/location/Macros.scala
363
+
356
364
package location
357
365
358
366
import scala .reflect .macros .blackbox .Context
@@ -418,8 +426,8 @@ Here the Scala 3.0 implementation throws a `NotImplementedError`, hence the answ
418
426
We can try and see the exception being thrown at compile-time.
419
427
420
428
``` shell
421
- sbt: location> ++@scala30 @; app / run
422
- [info] compiling 1 Scala source to /loaction/app/target/scala-@scala30Binary @/classes ...
429
+ sbt: location> ++@scala3M1 @; app / run
430
+ [info] compiling 1 Scala source to /loaction/app/target/scala-@scala3M1Binary @/classes ...
423
431
[error] -- Error: /location/app/src/main/scala/app/Main.scala:6:10
424
432
[error] 6 | println(location)
425
433
[error] | ^^^^^^^^
@@ -460,7 +468,7 @@ object Macros:
460
468
The `app` module can now be compiled and executed in Scala 3:
461
469
462
470
```
463
- sbt: location> ++@scala30 @; app / run
471
+ sbt: location> ++@scala3M1 @; app / run
464
472
[info] running app.Main
465
473
Line 6 in /location/app/src/main/scala/app/Main.scala
466
474
[info] app / run completed
0 commit comments