You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:37:26