Scalafix:解析对象应用方法
Scalafix: resolving object apply method
我有一个定义了一些应用方法的对象,然后使用它
object Ob {
def apply(i: Int) = ()
def apply(s: String) = ()
}
object Use {
def someMethod(i: Int) = ()
Ob(1)
someMethod(1)
}
使用 scalafix/scalameta 时,我无法找到获取实际 apply
方法句柄的方法(在我的例子中,我正在尝试检查参数名称和类型scalafix 规则)
当我匹配并打印已解析的 SymbolInformation 时,我获得了对该对象的引用。
所以这个
import scalafix.v1._
import scala.meta._
class NamedLiteralArguments extends SemanticRule("NamedLiteralArguments") {
val minParam = 2
override def fix(implicit doc: SemanticDocument): Patch = {
doc.tree
.collect {
case Term.Apply(fun, args) =>
println(fun.symbol.info)
Patch.empty
}
}
打印
Some(test/Ob. => final object Ob extends AnyRef { +2 decls })
Some(test/Use.someMethod(). => method someMethod(i: Int): Unit)
但我希望它解析确切的 apply
方法。
(Scalafix 版本 0.9.20)
在 build.sbt
中开启 "-P:semanticdb:synthetics:on"
scalacOptions ++= List(
"-Yrangepos",
"-P:semanticdb:synthetics:on",
)
然后
import scalafix.v1._
import scala.meta._
class MyRule extends SemanticRule("MyRule") {
override def fix(implicit doc: SemanticDocument): Patch = {
doc.tree
.collect {
case t: Term =>
println(s"t=$t=${t.structure}, t.symbol.info=${t.symbol.info}, t.synthetics=${t.synthetics.map(_.symbol.map(_.info))}")
Patch.empty
}.asPatch
}
}
打印
t=Ob=Term.Name("Ob"), t.symbol.info=Some(_empty_/Ob. => final object Ob extends AnyRef { +2 decls }), t.synthetics=List()
t=apply=Term.Name("apply"), t.symbol.info=Some(_empty_/Ob.apply(). => method apply(i: Int): Unit), t.synthetics=List()
t=i=Term.Name("i"), t.symbol.info=Some(_empty_/Ob.apply().(i) => param i: Int), t.synthetics=List()
t=()=Lit.Unit, t.symbol.info=None, t.synthetics=List()
t=apply=Term.Name("apply"), t.symbol.info=Some(_empty_/Ob.apply(+1). => method apply(s: String): Unit), t.synthetics=List()
t=s=Term.Name("s"), t.symbol.info=Some(_empty_/Ob.apply(+1).(s) => param s: String), t.synthetics=List()
t=()=Lit.Unit, t.symbol.info=None, t.synthetics=List()
t=Use=Term.Name("Use"), t.symbol.info=Some(_empty_/Use. => final object Use extends AnyRef { +1 decls }), t.synthetics=List()
t=someMethod=Term.Name("someMethod"), t.symbol.info=Some(_empty_/Use.someMethod(). => method someMethod(i: Int): Unit), t.synthetics=List()
t=i=Term.Name("i"), t.symbol.info=Some(_empty_/Use.someMethod().(i) => param i: Int), t.synthetics=List()
t=()=Lit.Unit, t.symbol.info=None, t.synthetics=List()
t=Ob(1)=Term.Apply(Term.Name("Ob"), List(Lit.Int(1))), t.symbol.info=Some(_empty_/Ob. => final object Ob extends AnyRef { +2 decls }), t.synthetics=List()
t=Ob=Term.Name("Ob"), t.symbol.info=Some(_empty_/Ob. => final object Ob extends AnyRef { +2 decls }), t.synthetics=List(Some(Some(_empty_/Ob.apply(). => method apply(i: Int): Unit)))
t=1=Lit.Int(1), t.symbol.info=None, t.synthetics=List()
t=someMethod(1)=Term.Apply(Term.Name("someMethod"), List(Lit.Int(1))), t.symbol.info=Some(_empty_/Use.someMethod(). => method someMethod(i: Int): Unit), t.synthetics=List()
t=someMethod=Term.Name("someMethod"), t.symbol.info=Some(_empty_/Use.someMethod(). => method someMethod(i: Int): Unit), t.synthetics=List()
t=1=Lit.Int(1), t.symbol.info=None, t.synthetics=List()
注意行
t=Ob=Term.Name("Ob"), ..., t.synthetics=List(Some(Some(_empty_/Ob.apply(). => method apply(i: Int): Unit)))
参见:
https://scalameta.org/docs/semanticdb/specification.html#synthetic
https://scalameta.org/docs/semanticdb/specification.html#synthetic-1
所以
class MyRule extends SemanticRule("MyRule") {
override def fix(implicit doc: SemanticDocument): Patch = {
doc.tree
.collect {
case Term.Apply(fun, args) =>
println(fun.symbol.info + ", " + fun.synthetics.map(_.symbol.map(_.info)))
Patch.empty
}.asPatch
}
}
将打印
Some(_empty_/Ob. => final object Ob extends AnyRef { +2 decls }), List(Some(Some(_empty_/Ob.apply(). => method apply(i: Int): Unit)))
Some(_empty_/Use.someMethod(). => method someMethod(i: Int): Unit), List()
我有一个定义了一些应用方法的对象,然后使用它
object Ob {
def apply(i: Int) = ()
def apply(s: String) = ()
}
object Use {
def someMethod(i: Int) = ()
Ob(1)
someMethod(1)
}
使用 scalafix/scalameta 时,我无法找到获取实际 apply
方法句柄的方法(在我的例子中,我正在尝试检查参数名称和类型scalafix 规则)
当我匹配并打印已解析的 SymbolInformation 时,我获得了对该对象的引用。 所以这个
import scalafix.v1._
import scala.meta._
class NamedLiteralArguments extends SemanticRule("NamedLiteralArguments") {
val minParam = 2
override def fix(implicit doc: SemanticDocument): Patch = {
doc.tree
.collect {
case Term.Apply(fun, args) =>
println(fun.symbol.info)
Patch.empty
}
}
打印
Some(test/Ob. => final object Ob extends AnyRef { +2 decls })
Some(test/Use.someMethod(). => method someMethod(i: Int): Unit)
但我希望它解析确切的 apply
方法。
(Scalafix 版本 0.9.20)
在 build.sbt
"-P:semanticdb:synthetics:on"
scalacOptions ++= List(
"-Yrangepos",
"-P:semanticdb:synthetics:on",
)
然后
import scalafix.v1._
import scala.meta._
class MyRule extends SemanticRule("MyRule") {
override def fix(implicit doc: SemanticDocument): Patch = {
doc.tree
.collect {
case t: Term =>
println(s"t=$t=${t.structure}, t.symbol.info=${t.symbol.info}, t.synthetics=${t.synthetics.map(_.symbol.map(_.info))}")
Patch.empty
}.asPatch
}
}
打印
t=Ob=Term.Name("Ob"), t.symbol.info=Some(_empty_/Ob. => final object Ob extends AnyRef { +2 decls }), t.synthetics=List()
t=apply=Term.Name("apply"), t.symbol.info=Some(_empty_/Ob.apply(). => method apply(i: Int): Unit), t.synthetics=List()
t=i=Term.Name("i"), t.symbol.info=Some(_empty_/Ob.apply().(i) => param i: Int), t.synthetics=List()
t=()=Lit.Unit, t.symbol.info=None, t.synthetics=List()
t=apply=Term.Name("apply"), t.symbol.info=Some(_empty_/Ob.apply(+1). => method apply(s: String): Unit), t.synthetics=List()
t=s=Term.Name("s"), t.symbol.info=Some(_empty_/Ob.apply(+1).(s) => param s: String), t.synthetics=List()
t=()=Lit.Unit, t.symbol.info=None, t.synthetics=List()
t=Use=Term.Name("Use"), t.symbol.info=Some(_empty_/Use. => final object Use extends AnyRef { +1 decls }), t.synthetics=List()
t=someMethod=Term.Name("someMethod"), t.symbol.info=Some(_empty_/Use.someMethod(). => method someMethod(i: Int): Unit), t.synthetics=List()
t=i=Term.Name("i"), t.symbol.info=Some(_empty_/Use.someMethod().(i) => param i: Int), t.synthetics=List()
t=()=Lit.Unit, t.symbol.info=None, t.synthetics=List()
t=Ob(1)=Term.Apply(Term.Name("Ob"), List(Lit.Int(1))), t.symbol.info=Some(_empty_/Ob. => final object Ob extends AnyRef { +2 decls }), t.synthetics=List()
t=Ob=Term.Name("Ob"), t.symbol.info=Some(_empty_/Ob. => final object Ob extends AnyRef { +2 decls }), t.synthetics=List(Some(Some(_empty_/Ob.apply(). => method apply(i: Int): Unit)))
t=1=Lit.Int(1), t.symbol.info=None, t.synthetics=List()
t=someMethod(1)=Term.Apply(Term.Name("someMethod"), List(Lit.Int(1))), t.symbol.info=Some(_empty_/Use.someMethod(). => method someMethod(i: Int): Unit), t.synthetics=List()
t=someMethod=Term.Name("someMethod"), t.symbol.info=Some(_empty_/Use.someMethod(). => method someMethod(i: Int): Unit), t.synthetics=List()
t=1=Lit.Int(1), t.symbol.info=None, t.synthetics=List()
注意行
t=Ob=Term.Name("Ob"), ..., t.synthetics=List(Some(Some(_empty_/Ob.apply(). => method apply(i: Int): Unit)))
参见:
https://scalameta.org/docs/semanticdb/specification.html#synthetic
https://scalameta.org/docs/semanticdb/specification.html#synthetic-1
所以
class MyRule extends SemanticRule("MyRule") {
override def fix(implicit doc: SemanticDocument): Patch = {
doc.tree
.collect {
case Term.Apply(fun, args) =>
println(fun.symbol.info + ", " + fun.synthetics.map(_.symbol.map(_.info)))
Patch.empty
}.asPatch
}
}
将打印
Some(_empty_/Ob. => final object Ob extends AnyRef { +2 decls }), List(Some(Some(_empty_/Ob.apply(). => method apply(i: Int): Unit)))
Some(_empty_/Use.someMethod(). => method someMethod(i: Int): Unit), List()