加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 在宏上下文中查找隐式方法定义

发布时间:2020-12-16 18:48:57 所属栏目:安全 来源:网络整理
导读:我理解 Scala中宏的基本概念,但目前无法做到这一点(简单?)的工作: 查找编译器当前可见的所有隐式defs / val,以便从给定类型转换为另一个类型. 我期望得到的是一个方法列表或类似的东西.我已经玩过enclosingInmplicits,但总是得到一个空列表,并不知道接下来
我理解 Scala中宏的基本概念,但目前无法做到这一点(简单?)的工作:

>查找编译器当前可见的所有隐式defs / val,以便从给定类型转换为另一个类型.

我期望得到的是一个方法列表或类似的东西.我已经玩过enclosingInmplicits,但总是得到一个空列表,并不知道接下来要去哪里看.

我需要做什么才能获得我想要的列表?

解决方法

在上下文中只能有一个从A到B隐式的内容(或者你得到隐含的ambigious),所以如果你想找到它:

import reflect.macros.Context,scala.language.experimental.macros

def fImpl(c: Context): c.Expr[Unit] = {
  import c.mirror._         
  println(c.inferImplicitValue(typeOf[Int]))
  c.universe.reify( () )
}
def f = macro fImpl

scala> f
<empty>

scala> implicit val a = 5
a: Int = 5

scala> f
$line24.$read.$iw.$iw.$iw.$iw.a

scala> implicit val b = 5
b: Int = 5

scala> f //result will be empty,but error printed to the log
error: ambiguous implicit values:
 both value a of type => Int
 and value b of type => Int
 match expected type Int
<empty>

要找到隐式方法:

def fImpl(c: Context): c.Expr[Unit] = {
      import c.mirror._       
      println(c.inferImplicitValue(typeOf[String => Int]))        
      c.universe.reify( () )
 }
def f = macro fImpl

scala> f
<empty>

scala> implicit def aaa(a: String) = 5
warning: there was one feature warning; re-run with -feature for details
aaa: (a: String)Int

scala> "A" : Int
res10: Int = 5

scala> f
{
  ((a: String) => $line47.$read.$iw.$iw.$iw.$iw.$iw.$iw.aaa(a))
}

如果silent参数为false(默认为true),则在推理错误的情况下将抛出TypecheckException.因此,您可以对其进行分析以查找具有暧昧意义的列表.

附:如果类型B是未知的 – 没有(记录)方法来查找使用宏的所有含义:openImplicits / enclosingImplicits只是寻找在宏扩展的上下文中实现的含义 – 不是所有,在上下文中存在.编译器插件可能有所帮助,但它并不那么容易.

如果你真的决定尝试“编译器 – 插件”的方式 – 找到隐含的逻辑是here. Here你可以找到编译器的上下文(与宏不同)及其隐含字段,它包含上下文中的所有含义(但它不是如此微不足道,以获得适当的背景).

我不应该告诉你,但是从宏上下文升级到编译器级别并且做你想做的事情有一个棘手和不安全的黑客攻击:

scala>  def fImpl(c: Context): c.Expr[Unit] = {
 |       val cc = c.asInstanceOf[reflect.macros.contexts.Context]
 |       println(cc.callsiteTyper.context.implicitss.flatten)
 |       c.universe.reify( () )
 |  }
fImpl: (c: reflect.macros.Context)c.Expr[Unit]

scala> def f = macro fImpl

scala> f //I've defined aaaaaaaa etc. implicits while playing with that
List(aaaaaaaa: ?,lllllllllllllllllllllzzzz: ?,lllllllllllllllllllll: ?,aaa: ?,b: ?,a: ?,macros: ?,RuntimeClassTag:

无论如何,你必须分析一个ImplicitInfo的列表以获得你正在寻找的暗示,这可能不是微不足道的,正如你从Analizer的资料中看到的那样,但至少可以得到近似的结果,这可能对你的需求很好.但同样,最好非常小心地做到这一点,因为你使用的结构是可变的,方法并不纯粹.并且,正如@Eugene Burmako注意到的,这个解决方案并没有给你伴侣对象的暗示.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读