Не удается разрешить символ apply с использованием макроса в Scala 2.13

Вопрос или проблема

Я пытаюсь обновить свою кодовую базу с 2.11.8 до 2.13.15. У меня есть ошибка в моем трейте HandsOnSuite.

trait HandsOnSuite extends AnyFunSpec with Matchers with ScalaFutures {
  def exercice(testName: String)(testFun: Unit)(implicit suite: HandsOnSuite): Unit = macro ExerciceMacro.apply
}

Не удается найти метод apply, который определяется макросом.

package support

import scala.reflect.macros.blackbox
import scala.reflect.macros.blackbox.Context

class ExerciceMacro[C <: Context](val c: C) {
  import c.universe._

  def apply(testName: c.Expr[String])(testFun: c.Expr[Unit])(suite: c.Expr[HandsOnSuite]): c.Expr[Unit] = {
    val code = testFun.tree.pos.source.content.mkString
    val (start, end) = testFun.tree match {
      case Block(xs, expr) => (testFun.tree.pos.line, expr.pos.line)
      case _ => (testFun.tree.pos.line, testFun.tree.pos.line)
    }
    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.type](c).apply(testName)(testFun)(suite)
  }
}

Есть ли какие-либо советы по поводу того, как я могу это обновить? Я не могу найти документации по макросам.

Используя Intellij, я очистил кеш, но это не сработало.

Ответ или решение

Ошибка "Cannot resolve symbol apply" при использовании макросов в Scala 2.13 может возникнуть по нескольким причинам, связанным с изменением реализации макросов в Scala с версии 2.11 до 2.13. Рассмотрим способы решения этой проблемы, учитывая контекст вашего кода и типичные изменения, произошедшие в Scala.

Причины проблемы

  1. Изменения в реализации макросов: В версиях Scala 2.13 было введено несколько изменений в библиотеке макросов, которые могут влиять на способ объявления и использования макросов. Например, изменения в типах контекста могут вызвать проблемы с разрешением символов.

  2. Синхронизация кода: Возможно, что ваш макрос не был скомпилирован корректно или был неправильно импортирован.

  3. Внутреннее представление кода: Начиная с версии 2.13, может измениться способ обработки AST (абстрактного синтаксического дерева), что может вызвать несоответствие в вашем коде.

Шаги по устранению ошибки

  1. Обновите синтаксис макроса: Убедитесь, что ваш макрос соответствует обновленным требованиям Scala. Вот адаптированный пример вашего кода с учетом изменений, необходимых для работы с макросами в Scala 2.13:

    import scala.quoted.*
    
    trait HandsOnSuite extends AnyFunSpec with Matchers with ScalaFutures {
     inline def exercice(testName: String)(inline testFun: Unit): Unit = 
       ${ ExerciceMacro.exerciceImpl('testName, 'testFun, 'this) }
    }
    
    object ExerciceMacro {
     def exerciceImpl(testName: Expr[String], testFun: Expr[Unit], suite: Expr[HandsOnSuite])(using Quotes): Expr[Unit] = {
       val code = testFun.valueOrError.toString // Необходимо корректно получить значение.
       val (start, end) = (0, 0) // Заглушка, здесь нужно извлечь строки из testFun.
    
       '{ $suite.testExercice($testName)($testFun)(new support.TestContext($code, $start, $end)) }
     }
    }

    Здесь мы используем inline и Expr для обработки макроса в контексте Scala 2.13.

  2. Проверьте зависимости: Убедитесь, что все ваши зависимости (включая библиотеку макросов, если используется) обновлены. Проверьте свой build.sbt файл на наличие соответствующих зависимостей:

    libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.9" % Test
  3. Пересоберите проект: После внесения изменений, выполните полную пересборку вашего проекта. Это можно сделать с помощью команды sbt clean compile.

  4. Проверка IDE: Если вы используете IntelliJ, убедитесь, что у вас установлены правильные плагины для поддержки Scala и макросов. Иногда доступ к функционалу может быть ограничен настройками IDE.

  5. Обратная совместимость: Если вы используете какие-то специфические фреймворки или библиотеки, убедитесь, что они также обновлены и совместимы с Scala 2.13.

  6. Изучение документации: Макросы в Scala являются сложной темой, и лучше обратиться к официальной документации и руководствам по макросам в Scala 2.13. Этот ресурс будет полезен для детального изучения новых возможностей и ограничений.

Заключение

Обратите внимание на изменения в реализации макросов при переходе на новую версию Scala, и протестируйте решение в небольших частях, чтобы быстро отследить и исправить возможные ошибки. Работая с макросами, важно учитывать и обновления языка, и потенциальные изменения в экосистемах библиотек. Если проблема сохраняется, стоит обратиться к сообществу Scala для получения дальнейшей помощи.

Оцените материал
Добавить комментарий

Капча загружается...