从SBT内部向Scala编译器提供服务
我有一个Scala宏,它(有时)需要与外部服务对话。我们可以假设此服务托管在同一台机器上。启动此服务非常昂贵(第一次运行约3分钟,在同一台机器上后续运行约5秒),这就是为什么它应该以某种方式“共享”的原因。仅仅查询服务是非常便宜的。该服务提供了一个Scala API 简单的解决方案是将库添加到编译器类路径中,并执行以下操作从SBT内部向Scala编译器提供服务,scala,sbt,scala-macros,Scala,Sbt,Scala Macros,我有一个Scala宏,它(有时)需要与外部服务对话。我们可以假设此服务托管在同一台机器上。启动此服务非常昂贵(第一次运行约3分钟,在同一台机器上后续运行约5秒),这就是为什么它应该以某种方式“共享”的原因。仅仅查询服务是非常便宜的。该服务提供了一个Scala API 简单的解决方案是将库添加到编译器类路径中,并执行以下操作 val instance = service.start(...) val tree = if (instance.query(...)) q"""new me
val instance = service.start(...)
val tree =
if (instance.query(...))
q"""new meep { ... }"""
else
context.abort("no can do")
instance.teardown()
tree
当然,如果有许多宏调用,这是非常缓慢的
我的想法是在SBT中启动服务,并以某种方式将其提供给Scala编译器。这提出了一些有趣的问题
设置键
命令
,该命令检查服务是否已激活,如果未激活,则根据设置启动服务。但是它会把引用放在哪里呢?在状态下
,使用属性键
?[0][0]旁注:由于宏并不总是需要与服务对话,因此让SBT按需启动宏也是有意义的(除非这会使问题复杂化)。是否允许使用编译器插件?好的老式系统属性如何?编译器插件不是一个选项。我不明白系统属性会有什么帮助——它们允许我传递字符串,而不是任意对象。但是如果你得到任意字符串,你不能将其用作,例如jdbc连接吗?正如我所说,将此服务想象为数据库有点简单。实际上,我需要向宏公开Scala API。或者,自己实现一些其他的通信层。