我有以下信息:
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源解析为Source
类型。 ScalaFix似乎将其解析为implicit SemanticDocument
。 SemanticDocument
具有字段tree
,该字段由ScalaMeta实现,导致产生可遍历的AST数据结构,就像将源文件解析为类型Source
所产生的那样。这显示了ScalaMeta和ScalaFix之间的关系。但是,我担心的是,我需要加载一个Scala源代码并在其上使用ScalaFix来访问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
?