2013-09-10 33 views
5

Tôi đang cố gắng lấy chuỗi đầu vào ban đầu của tham số vào macro, nhưng vị trí được trả lại có vẻ hơi lệch. Cân nhắc macro này, ví dụ:Có gì với vị trí trên các macro Scala?

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 
    } 
} 

Khi tôi thử nó với tập tin này:

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

tôi nhận được kết quả này:

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

mà không có ý nghĩa đối với tôi. Tôi hy vọng nó sẽ trỏ đến x hoặc bị tắt một. Có chuyện gì thế?

+0

Nếu bạn thay đổi nó cho 'println (Mf (x. + (Y))) 'điểm dịch chuyển qua một điểm tại điểm y, và với' println (Mf (nếu (đúng) {x + y})) 'nó trỏ tới điểm f nếu. Tôi nghi ngờ nó đang cố gắng để trỏ ở trên cùng của cây, lời kêu gọi của + hoặc nếu, mặc dù cho dù đó là vụ phải hay không là một câu hỏi khác. Có thể có ít nhất một lỗi từng người một. Điều này có vẻ thích hợp cho một báo cáo lỗi cho tôi. – wingedsubmariner

+0

Sẽ thú vị hơn nếu đọc câu hỏi, Vị trí của bạn trên macro là gì? –

Trả lời

3

Đây là lỗi theo từng loại theo nghĩa là Position.columnPosition.line là 1 dựa trên.

Đó là lỗi tài liệu theo nghĩa là họ đã bận tâm ghi lại API nhưng không bận tâm đề cập đến điều đó.

Bạn có thể biên dịch với -Yrangepos và:

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

hoặc tương tự để chỉ ra vị trí đầu tiên trong cây.

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

Cập nhật:

Cho sự trở lại vĩ mô biểu thức nó đưa ra, và biên soạn với -Xprint:typer -Yshow-trees, cây là khu vực nội Apply nút, mà là vị trí ở +:

 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 
     ) 
    ) 

Với một vị trí "phạm vi", vị trí của đỉnh của cây bao gồm mọi thứ bên dưới nó. Vì vậy, trong khi point là nơi các + là, start của một vị trí phạm vi là vị trí sớm nhất của tất cả mọi thứ kèm theo vị trí phạm vi, tức là, tất cả mọi thứ thấp hơn trong cây. Trong trường hợp này, lá bên trái là x.

Vì vậy, sự khác biệt point - start cho bạn biết cách sao lưu.

(Tôi đã không được coi là những gì nếu offsets vào file nguồn khác với offsets cột vì những khác biệt trong mã hóa ký tự.)

+0

Nhưng _what_ là 'cột' trỏ đến? Và ý nghĩa của 'pos.point - pos.startOrPoint' (cả hai đều vô nghĩa đối với tôi)? –

+0

@ DanielC.Sobral Tôi chỉ biết đủ về các vị trí phạm vi đã giới thiệu một lỗi khi người IDE phải sửa chữa. Ít nhất tôi cũng đang sửa một lỗi, nên đó là một lần rửa. Ngoài ra, tôi nghĩ -Yrangepos sẽ trở thành mặc định? Cập nhật kiến ​​thức hạn chế của tôi. –

+0

@ DanielC.Sobral Có những ý kiến ​​cải tiến (và mã) tại https://github.com/scala/scala/pull/2936 –

Các vấn đề liên quan