Сгенерированный исходный код с макросами в Scala 2.13 и проект Mill не найден в Intellij

Я использую zio-макросы в Scala 2.13 / Мельница Проект.

Вот пример:

@accessible
@mockable
trait AccountObserver {
  val accountObserver: AccountObserver.Service[Any]
}

object AccountObserver {
  trait Service[R] {
    def processEvent(event: String): ZIO[R, Nothing, Unit]
  }

  // autogenerated `object Service { ... }`
  // autogenerated `object > extends Service[AccountObserver] { ... }`
  // autogenerated `implicit val mockable: Mockable[AccountObserver] = ...`
}

Я могу запустить тест, и он найдет автоматически сгенерированный код.

Проблема в том, что в Intellij ссылки на автоматически сгенерированный код не компилируются.

Надо что-то настраивать или чего не хватает?


person pme    schedule 29.10.2019    source источник


Ответы (2)


Следующий проект компилируется

build.sc

import mill._, scalalib._

object root extends ScalaModule {
  def scalaVersion = "2.13.1"
  val zioMacrosV = "0.4.0"
  def ivyDeps = Agg(
    ivy"dev.zio::zio-macros-core:${zioMacrosV}",
    ivy"dev.zio::zio-macros-access:${zioMacrosV}",
    ivy"dev.zio::zio-macros-mock:${zioMacrosV}"
  )
  def scalacOptions = Seq(
    "-Ymacro-annotations",
    "-Ymacro-debug-lite"
  )
}

корень / src / App.scala

import zio.ZIO
import zio.macros.access.accessible
import zio.macros.mock.mockable

@accessible
@mockable
trait AccountObserver {
  val accountObserver: AccountObserver.Service[Any]
}

object AccountObserver {
  trait Service[R] {
    def processEvent(event: String): ZIO[R, Nothing, Unit]
  }
}

Команда mill root.compile компилирует проект

//{
//  abstract trait AccountObserver extends scala.AnyRef {
//    val accountObserver: AccountObserver.Service[Any]
//  };
//  object AccountObserver extends scala.AnyRef {
//    def <init>() = {
//      super.<init>();
//      ()
//    };
//    abstract trait Service[R] extends scala.AnyRef {
//      def processEvent(event: String): ZIO[R, Nothing, Unit]
//    };
//    object Service extends scala.AnyRef {
//      def <init>() = {
//        super.<init>();
//        ()
//      };
//      case object processEvent extends _root_.zio.test.mock.Method[String, Unit] with scala.Product with scala.Serializable {
//        def <init>() = {
//          super.<init>();
//          ()
//        }
//      }
//    };
//    implicit val mockable: _root_.zio.test.mock.Mockable[AccountObserver] = ((mock: _root_.zio.test.mock.Mock) => {
//      final class $anon extends AccountObserver {
//        def <init>() = {
//          super.<init>();
//          ()
//        };
//        val accountObserver = {
//          final class $anon extends Service[Any] {
//            def <init>() = {
//              super.<init>();
//              ()
//            };
//            def processEvent(event: String): _root_.zio.IO[Nothing, Unit] = mock(Service.processEvent, event)
//          };
//          new $anon()
//        }
//      };
//      new $anon()
//    });
//    object $greater extends Service[AccountObserver] {
//      def <init>() = {
//        super.<init>();
//        ()
//      };
//      def processEvent(event: String): _root_.zio.IO[Nothing, Unit] = _root_.zio.ZIO.accessM(<empty> match {
//        case (env @ (_: AccountObserver)) => env.accountObserver.processEvent(event)
//      })
//    }
//  };
//  ()
//}

Создавать файлы IntelliJ

mill mill.scalalib.GenIdea/idea

а затем откройте проект в IntelliJ (не импортируйте его).

Теперь Ctrl + Shift + F9 компилирует проект (аналогично описанному выше).

Вы можете использовать, например, ссылку на объект AccountObserver.Service (он компилируется). Конечно, IntelliJ выделяет Service красным, но это не имеет значения.

person Dmytro Mitin    schedule 29.10.2019
comment
Конечно, IntelliJ выделяет Сервис красным, но это не имеет значения.. Но это именно та проблема, которую трудно закодировать, если у вас есть исключение компиляции во всем исходном коде. - person pme; 30.10.2019
comment
@pme Это не исключение компиляции, это просто неправильное выделение. - person Dmytro Mitin; 30.10.2019
comment
@pme Вы должны привыкнуть, что IntelliJ иногда неправильно выделяет код Scala. Макросы слишком сложны для IntelliJ. Это не зависит от того, как вы строите свой проект, с помощью sbt или mill. - person Dmytro Mitin; 30.10.2019
comment
Но также не работает завершение кода и навигация по коду (такая же проблема с VS Code) - person pme; 30.10.2019
comment
Красный маркер был проблемой. Я исправил эту часть генератора проекта. Либо запустите последний снимок мельницы, либо дождитесь следующей версии мельницы ›0.5.2. - person Tobias Roeser; 14.11.2019

Обновление: этот ответ не решает проблему.


Это ошибка в генераторе проектов IntelliJ IDEA Mill 0.5.2 и ранее. Версии Mill, начиная с 0.5.2-9-ea4f04, будут содержать исправление для этой конкретной проблемы. (Для справки: # 729, # 728)

Чтобы обойти эту проблему: добавьте в проект .mill-version файл, содержащий этот номер версии (или любую более новую, конечно), и перезапустите генератор проекта IDEA.

$ echo -n "0.5.2-9-ea4f04" > .mill-version
$ mill mill.scalalib.GenIdea/idea
person Tobias Roeser    schedule 14.11.2019
comment
Это исправление не помогло. Но я также пробовал это с проектом sbt - такая же проблема. Вот класс, который компилируется, но показывает ошибки в intellij: github.com/pme123/zio-examples/blob/master/macros/src/pme123/ - person pme; 14.11.2019
comment
Я вижу, что это не сгенерированный исходный код, поэтому проблема, о которой я говорил в своем ответе, не совсем то же самое, потому что нет новых файлов, которые IntelliJ IDEA должна учитывать. - person Tobias Roeser; 16.11.2019