使用scalameta

时间:2018-03-03 23:07:23

标签: scala metaprogramming scala-meta

我正在尝试编写一个简单的程序,使用scalameta从给定方法开始遍历所有引用的代码。

我能够跟踪调用,但无法解析方法引用。

analyzeme / SRC /主/阶/程式码实验室/ FindMe.scala

package codelab

object FindMe {
  def main(args: Array[String]): Unit = {
    val x = someRecognizeableName(1, 2)
    val y = List(1, 2, 3)
    y.foldLeft(0)(someRecognizeableName)
  }
  def someRecognizeableName(a: Int, b: Int): Int = a + b
}

生成并加载FindMe.scala的semanticdb并检查someRecognizeableName方法的用法。

我可以在db.names列表中看到第一个电话:

[87..108): someRecognizeableName => _root_.codelab.FindMe.someRecognizeableName(Int,Int).

第二个,但是,当我不调用该方法时,只是传递引用显示为:

[159..180): someRecognizeableName => local2_src_main_scala_codelab_FindMe_scala

因此,当我尝试从main关注引用startin时,在第二种情况下,我没有获得someRecognizeableName引用的完全限定名称。

问题:有没有办法从semanticdb获取该参考的完全限定名称?

重现上述

的完整资源

运行说明

analyzeme $ sbt compile
analyzer $ sbt "run ../analyzeme"

analyzeme / SRC /主/阶/程式码实验室/ FindMe.scala

package codelab

object FindMe {
  def main(args: Array[String]): Unit = {
    val x = someRecognizeableName(1, 2)
    val y = List(1, 2, 3)
    y.foldLeft(0)(someRecognizeableName)
  }
  def someRecognizeableName(a: Int, b: Int): Int = a + b
}

分析器/ SRC /主/阶/ Main.scala

import org.langmeta.io.{Classpath, Sourcepath}

import scala.meta._

object Main {
  def main(args: Array[String]): Unit = {

    println(s"Loading from [${ args(0) }]")
    println()

    val cp = Classpath(s"${ args(0) }/target/scala-2.12/classes")
    val sp = Sourcepath(s"${ args(0) }/src/main/scala")

    val db = Database.load(cp, sp)

    println("* names:")
    db.names foreach println
    println()
    println("* symbols:")
    db.symbols foreach println
    println()
    println("* synthetics:")
    db.synthetics foreach println
    println()
    println("* messages:")
    db.messages foreach println
    println()
  }

}

analyzeme / build.sbt

name := "analyzee"
version := "0.1"
scalaVersion := "2.12.4"

addCompilerPlugin("org.scalameta" % "semanticdb-scalac" % "3.4.0" cross CrossVersion.full)
scalacOptions += "-Yrangepos"

分析器/ build.sbt

name := "analyzer"
version := "0.1"
scalaVersion := "2.12.4"

libraryDependencies += "org.scalameta" %% "scalameta" % "3.4.0"
libraryDependencies += "org.scalameta" %% "contrib" % "3.4.0"

1 个答案:

答案 0 :(得分:1)

package codelab

object FindMe {
  def main(args: Array[String]): Unit = {
  val x = someRecognizeableName(1, 2)

  y.foldLeft(0)(someRecognizeableName)
  // same as
  y.foldLeft(0){ a, b => someRecognizeableName(a, b) }
}

我调试代码并在第二种情况下发现,编译器传递了一个匿名符号,该符号无法从当前的semanticdb访问,它可能应该出现在syhthetics分区,但我无法在内部找到它。

所以我猜在当前的semanticdb中缺少编译器生成的匿名。