У меня есть следующая информация:
Scalameta: имеет возможность создавать AST из исходного файла
SemanticDB: содержит информацию осимволы из проанализированного источника
файл
ScalaFix: основан на ScalaMeta и SemanticDB, поэтому он имеет возможность доступа к символьной информации и обходу AST.
Загрузка исходного файла с использованием ScalaMeta так же проста, как показано ниже:
val path = java.nio.file.Paths.get("path to source file")
val bytes = java.nio.file.Files.readAllBytes(path)
val text = new String(bytes, "UTF-8")
val input = Input.VirtualFile(path.toString, text)
val tree = input.parse[Source].get
Как видно из приведенного выше фрагмента кода, ScalaMeta анализирует исходный файл как тип Source
.
Теперь рассмотрим приведенный ниже фрагмент кода, где ScalaFix использует дерево типа SemanticDocument
:
class NamedLiteralArguments extends SemanticRule("NamedLiteralArguments") {
override def fix(implicit doc: SemanticDocument): Patch = {
doc.tree
.collect {
case Term.Apply(fun, args) =>
args.zipWithIndex.collect {
case (t @ Lit.Boolean(_), i) =>
fun.symbol.info match {
case Some(info) =>
info.signature match {
case method: MethodSignature
if method.parameterLists.nonEmpty =>
val parameter = method.parameterLists.head(i)
val parameterName = parameter.displayName
Patch.addLeft(t, s"$parameterName = ")
case _ =>
// Do nothing, the symbol is not a method
Patch.empty
}
case None =>
// Do nothing, we don't have information about this symbol.
Patch.empty
}
}
}
.flatten
.asPatch
}
}
Изучение двух приведенных выше фрагментов кода показывает, что ScalaMeta может анализировать источник Scala в тип * 1028.*.ScalaFix, кажется, анализирует то же самое в implicit SemanticDocument
.У SemanticDocument
есть поле tree
, которое реализовано ScalaMeta, что приводит к структуре данных AST с возможностью прохождения, аналогичной той, которая создается путем синтаксического анализа исходного файла типа Source
.Это показывает отношения между ScalaMeta и ScalaFix.Однако меня беспокоит то, что мне нужно загрузить исходный код Scala и использовать его для доступа к symbol.info
, но документация ScalaFix
не показывает, как это сделать.
Когда я пытаюсь загрузить исходный кодФайл как SemanticDocument
, как это в первом фрагменте кода вместо Source
:
val tree = input.parse[SemanticDocument].get
Я получаю ошибку, no parameters found for parameter parse in parse[SemanticDocument]
.Также обратите внимание, что попытка использовать symbol.info
в первом фрагменте кода также приводит к ошибкам неявных типов.Это не относится ко второму фрагменту кода, поскольку загруженный параметр doc
представляет собой implicit parameter of type SemanticDocument
.
Так как же ScalaFix загружает исходные файлы как SemanticDocument
?