diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 34a0cd99c3f1..f94eac90f037 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -2747,6 +2747,9 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler given SourceFileMethods: SourceFileMethods with extension (self: SourceFile) def jpath: java.nio.file.Path = self.file.jpath + def getJPath: Option[java.nio.file.Path] = Option(self.file.jpath) + def name: String = self.name + def path: String = self.path def content: Option[String] = // TODO detect when we do not have a source and return None Some(new String(self.content())) diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index 4a0b2eae3817..d8f1c431a651 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -4151,9 +4151,23 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Extension methods of `SourceFile` */ trait SourceFileMethods { extension (self: SourceFile) - /** Path to this source file */ + /** Path to this source file. May be `null` for virtual files such as in the REPL. */ + @deprecated("Use getJPath, name, or path instead of jpath", "3.0.2") def jpath: java.nio.file.Path + /** Path to this source file. May be `None` for virtual files such as in the REPL. */ + def getJPath: Option[java.nio.file.Path] + + /** Name of the source file */ + def name: String + + /** Path of the source file. + * + * It does not necessarily point to a path in the filesystem, it could be the path of a virtual file. + * Use `getJPath` to get paths to the filesystem. + */ + def path: String + /** Content of this source file */ def content: Option[String] end extension diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index c7a71a2dd8dc..c4d52097eba8 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -4,5 +4,12 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object MiMaFilters { val Library: Seq[ProblemFilter] = Seq( + // New APIs that will be introduced in 3.1.0 + exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.getJPath"), + exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.name"), + exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.path"), + exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.getJPath"), + exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.name"), + exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.path"), ) } diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala index b98436a318c0..b8a4df3a39d1 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala @@ -40,7 +40,7 @@ object SymOps: else None def source = - val path = sym.pos.map(_.sourceFile.jpath).filter(_ != null).map(_.toAbsolutePath) + val path = sym.pos.flatMap(_.sourceFile.getJPath).map(_.toAbsolutePath) path.map(TastyMemberSource(_, sym.pos.get.startLine)) //TODO: Retrieve string that will match scaladoc anchors diff --git a/tests/run-macros/tasty-getfile-implicit-by-name-fun-context/Macro_1.scala b/tests/run-macros/tasty-getfile-implicit-by-name-fun-context/Macro_1.scala index bb478331aa64..e78f3b88fe87 100644 --- a/tests/run-macros/tasty-getfile-implicit-by-name-fun-context/Macro_1.scala +++ b/tests/run-macros/tasty-getfile-implicit-by-name-fun-context/Macro_1.scala @@ -9,6 +9,6 @@ object SourceFiles { def getThisFileImpl: Macro[String] = val q = quotes // Quotes is ByName and hence not stable (q stabilizes it) - Expr(q.reflect.SourceFile.current.jpath.getFileName.toString) + Expr(q.reflect.SourceFile.current.name) } diff --git a/tests/run-macros/tasty-macro-positions/quoted_1.scala b/tests/run-macros/tasty-macro-positions/quoted_1.scala index d53cd16088b9..c0765bf1cda3 100644 --- a/tests/run-macros/tasty-macro-positions/quoted_1.scala +++ b/tests/run-macros/tasty-macro-positions/quoted_1.scala @@ -30,6 +30,6 @@ object Macros { def posStr(using Quotes)(pos: quotes.reflect.Position): Expr[String] = { import quotes.reflect.* - Expr(s"${pos.sourceFile.jpath.getFileName.toString}:[${pos.start}..${pos.end}]") + Expr(s"${pos.sourceFile.name}:[${pos.start}..${pos.end}]") } } diff --git a/tests/run-macros/tasty-positioned/quoted_1.scala b/tests/run-macros/tasty-positioned/quoted_1.scala index e6664c6a1774..ff8a614a0ba9 100644 --- a/tests/run-macros/tasty-positioned/quoted_1.scala +++ b/tests/run-macros/tasty-positioned/quoted_1.scala @@ -13,7 +13,7 @@ object Positioned { import quotes.reflect.{Position as Pos, *} val pos = Pos.ofMacroExpansion - val path = Expr(pos.sourceFile.jpath.toString) + val path = Expr(pos.sourceFile.getJPath.get.toString) val start = Expr(pos.start) val end = Expr(pos.end) val startLine = Expr(pos.startLine)