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

什么与Scala宏的位置有关?

发布时间:2020-12-16 18:35:28 所属栏目:安全 来源:网络整理
导读:我正在尝试将参数的原始输入字符串获取到宏,但返回的位置似乎有点偏.考虑这个宏,例如: object M { import scala.reflect.macros.Context import language.experimental.macros def f[T](v: = T) = macro fImpl[T] def fImpl[T : c.WeakTypeTag](c: Context)
我正在尝试将参数的原始输入字符串获取到宏,但返回的位置似乎有点偏.考虑这个宏,例如:

object M {
  import scala.reflect.macros.Context
  import language.experimental.macros
  def f[T](v: => T) = macro fImpl[T]
  def fImpl[T : c.WeakTypeTag](c: Context)(v: c.Expr[T]): c.Expr[Unit] = {
    import c.universe._
    val pos = v.tree.pos
    println(pos.lineContent)
    println(" " * pos.column + "^")
    println(" " * pos.point + "^")
    c.literalUnit 
  }
}

当我尝试使用此文件时:

object N extends App {
  val x = 1
  val y = 2
  println(M.f(x + y))
}

我得到这个输出:

println(M.f(x + y))
                 ^
                                                                  ^

这对我没有意义.我希望它指向x,或者一个接一个.那是怎么回事?

解决方法

从Position.column和Position.line是基于1的意义上讲,这是一个一个一个错误的错误.

这是一个文档错误,因为他们不愿意记录API,但没有提到这一点.

您可以使用-Yrangepos进行编译并:

val n = pos.column - (pos.point - pos.startOrPoint) - 1
println(" " * n + "^")

或类似的表示树中最早的位置.

println(M.f(x + y))
            ^

更新:

让宏返回它给出的表达式,并使用-Xprint:typer -Yshow-trees进行编译,树是内部Apply节点,它位于:

Apply( // def println(x: Any): Unit in object Predef,tree.tpe=Unit
        scala.this."Predef"."println" // def println(x: Any): Unit in object Predef,tree.tpe=(x: Any)Unit
        Apply( // def +(x: Int): Int in class Int,tree.tpe=Int
          "x"."$plus" // def +(x: Int): Int in class Int,tree.tpe=(x: Int)Int
          "y" // val y: Int,tree.tpe=Int
        )
      )

在“范围”位置,树顶部的位置包括它下面的所有东西.因此,虽然点是在哪里,但是范围位置的开始是由范围位置包围的所有内容的最早位置,即树中较低的一切.在这种情况下,左叶是x.

所以差异点 – 开始告诉你要备份多远.

(由于字符编码的不同,我没有考虑如果源文件中的偏移量与列偏移量不同,会怎样.)

(编辑:李大同)

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

    推荐文章
      热点阅读