Ответ 1
Хорошо, одна неделя из 100 щедрот и до сих пор нет ответов, поэтому я попробую сам... Редактирование очень приветствуется!
Ключевым классом для компилятора представления является scala.tools.nsc.interactive.Global
. Поэтому для начала нам нужно создать экземпляр компилятора.
import scala.tools.nsc.interactive.Global
class PresentationCompiler { // мы хотим, чтобы выход компилятора был виртуальным val target = новый VirtualDirectory ( ", None)
// необходимо настроить для работы с //sbt. См. этот вопрос. val settings = new Настройки() // вывод на виртуальную цель settings.outputDirs.setSingleOutput(цель)
// может быть заменен специальным экземпляром //AbstractReporter для получения контроля. val reporter = new ConsoleReporter (настройки)
val compiler = new Глобальный (настройки, репортер)
... }
Для настроек ссылка, предоставленная Abhishek, очень ценна.
Но теперь для интересной части:
1. скомпилировать один виртуальный исходный файл
Чтобы скомпилировать String, существует возможность создать BatchSourceFile
с базовым VirtualFile
. Здесь api отмечен экспериментально и кажется неоднородным.
def compile(code: String) {
val source = new BatchSourceFile("<virtual>", code)
val response = new Response[Unit]
compiler.askReload(List(source), response)
response.get.left.foreach { _ =>
// success
}
}
2. получить полученную информацию для всех фаз из компилятора
Это сложная часть. Из-за многопоточной природы компилятора и того факта, что флаги повторно используются с разными значениями в разных фазах, невозможно сразу получить все сразу. В основном вам придется прибегнуть к методам askSomething
, которые описаны в API. Например:
val tcompletion = new Response[List[global.Member]]
val pos = compiler.ask(() => new OffsetPosition(source, p))
global.askTypeCompletion(pos, tcompletion)
tcompletion.get(5000).get match {
case Left(members) => // do something with members
case Right(e) =>
e.printStackTrace
}
3. распространить изменение исходного файла на компилятор
Это интересная часть, о которой я хотел узнать по этому вопросу. Я действительно не понимаю этого, потому что BatchSourceFile
описывается как файл, содержимое которого не изменяется со временем. Таким образом, потребуется выполнить пользовательскую реализацию SourceFile
? Почему это не должно быть в пакете interactive
. Я уверен, что я просто ничего не поймал.
Итак, теперь мое решение - снова вызвать метод компиляции.