Skip to content

Add a way to construct custom position in TASTy Reflect #6148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,9 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util.
def Position_sourceCode(self: Position): String =
new String(self.source.content(), self.start, self.end - self.start)

def Position_withOffset(self: Position)(start: Int, end: Int): Position =
util.SourcePosition(self.source, util.Spans.Span(start, end))

//
// COMMENTS
//
Expand Down
6 changes: 6 additions & 0 deletions library/src/scala/tasty/reflect/Kernel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,12 @@ trait Kernel {
/** Source code within the position */
def Position_sourceCode(self: Position): String

/** Create a position that ranges from start to end (exclusive) in the given source
* @param start index of the start of the range (0 <= start < end)
* @param end index of the end of the range (start < end <= sizeOf(pos.sourceFile))
*/
def Position_withOffset(self: Position)(start: Int, end: Int): Position
Copy link
Contributor

@liufengyun liufengyun Mar 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I see this API, the first guess is that the offset is relative to the given position self. But in the implementation, only the source file is used. It seems this is better to be defined as a constructor for Position which takes sourceFile directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be terrible, each source position will try to reload the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should have the source file abstraction in TASTy reflect


//
// COMMENTS
//
Expand Down
7 changes: 7 additions & 0 deletions library/src/scala/tasty/reflect/PositionOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ trait PositionOps extends Core {
/** Source code within the position */
def sourceCode: String = kernel.Position_sourceCode(pos)

/** Create a position that ranges from start to end (exclusive) in the given source
* @param start index of the start of the range (0 <= start < end)
* @param end index of the end of the range (start < end <= sizeOf(pos.sourceFile))
*/
def withOffset(start: Int = pos.start, end: Int = pos.end): Position =
kernel.Position_withOffset(pos)(start, end)

}

}
4 changes: 4 additions & 0 deletions tests/neg/tasty-macro-positions.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<122..125> in quoted_2.scala
here (+5) is the the argument is foo
[117..120] in quoted_2.scala
here is the the argument is foo
17 changes: 17 additions & 0 deletions tests/neg/tasty-macro-positions/quoted_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import scala.quoted._

import scala.tasty._

object Macros {

inline def fun(x: Any): Unit = ${ impl('x) }

def impl(x: Expr[Any])(implicit reflect: Reflection): Expr[Unit] = {
import reflect._
val pos = x.unseal.underlyingArgument.pos
error("here is the the argument is " + x.unseal.underlyingArgument.showCode, pos)
error("here (+5) is the the argument is " + x.unseal.underlyingArgument.showCode, pos.withOffset(start = pos.start + 5, end = pos.end + 5))
'{}
}

}
11 changes: 11 additions & 0 deletions tests/neg/tasty-macro-positions/quoted_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

import Macros._

object Test {
def main(args: Array[String]): Unit = {
def foo: String = "abc"
fun(
foo // error // error
)
}
}