Scala 2.13升级遇宏报错:无法解析apply符号
Scala 2.13宏代码升级方案
针对你从Scala 2.11.8升级到2.13.15时遇到的宏apply方法找不到的问题,核心是Scala 2.13对宏API做了多处调整,以下是具体的修改方案:
核心修改点
1. 修正HandsOnSuite中的方法参数
原代码中testFun: Unit会导致代码块被提前求值,宏无法捕获完整语法树,需改为传名参数:
trait HandsOnSuite extends AnyFunSpec with Matchers with ScalaFutures { def exercice(testName: String)(testFun: => Unit)(implicit suite: HandsOnSuite): Unit = macro ExerciceMacro.apply }
2. 适配Scala 2.13宏API
修改宏类定义和源代码获取逻辑,适配2.13的API变化:
package support import scala.reflect.macros.blackbox class ExerciceMacro(val c: blackbox.Context) { import c.universe._ def apply(testName: c.Expr[String])(testFun: c.Expr[Unit])(suite: c.Expr[HandsOnSuite]): c.Expr[Unit] = { // 替换弃用的content,使用text直接获取源代码文本 val code = testFun.tree.pos.source.text // 修正行号计数:Scala 2.13行号从0开始,原2.11从1开始,需+1对齐 val (start, end) = testFun.tree match { case Block(_, expr) => (testFun.tree.pos.startLine + 1, expr.pos.endLine + 1) case _ => (testFun.tree.pos.startLine + 1, testFun.tree.pos.endLine + 1) } c.Expr(q"""$suite.testExercice($testName)($testFun)(new support.TestContext($code, $start, $end))""") } } object ExerciceMacro { def apply(c: blackbox.Context)(testName: c.Expr[String])(testFun: c.Expr[Unit])(suite: c.Expr[HandsOnSuite]): c.Expr[Unit] = { new ExerciceMacro(c).apply(testName)(testFun)(suite) } }
3. 关键API变更说明
- 宏类简化:移除原泛型参数
[C <: Context],直接使用blackbox.Context作为构造参数,符合2.13宏的标准写法。 - 源代码获取:
pos.source.content在2.13中被弃用,改用pos.source.text直接返回字符串,无需手动拼接。 - 行号修正:Scala 2.13中
startLine/endLine从0开始计数,原2.11从1开始,因此需要加1保持原有行号逻辑一致。
构建配置检查
确保项目依赖和版本对齐:
- 设置正确的Scala版本:
scalaVersion := "2.13.15" - 添加对应版本的
scala-reflect依赖:libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value
内容的提问来源于stack exchange,提问作者NoobZik
相关产品推荐
相关产品推荐

