2

我有以下信息:

  • 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 将源文件解析为 type 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 源解析为 type Source。ScalaFix 似乎将其解析为implicit SemanticDocument. SemanticDocumenthas 字段由 ScalaMeta 实现,tree它生成一个可遍历的 AST 数据结构,就像将源文件解析为 type 所产生的一样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呢?

4

0 回答 0