Skip to content

Commit b80319c

Browse files
Merge pull request #8559 from gzoller/fix8558
Fix issue 8558 expose AlreadyLoaded via Reflection
2 parents f387762 + 8405259 commit b80319c

File tree

6 files changed

+42
-6
lines changed

6 files changed

+42
-6
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package dotty.tools.dotc.fromtasty
2+
3+
import dotty.tools.dotc.CompilationUnit
4+
import dotty.tools.dotc.util.NoSource
5+
6+
/** A marker CompilationUnit to return up the call stack from ReadTasty. This will tell us that we've
7+
* encountered, and attempted to inspect, something that has already been loaded, for example a Scala primitive or a
8+
* library class like Option.
9+
*/
10+
class AlreadyLoadedCompilationUnit(val className: String) extends CompilationUnit(NoSource)

compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@ class ReadTasty extends Phase {
3232
None
3333
}
3434

35-
def alreadyLoaded(): None.type = {
36-
ctx.warning(s"class $className cannot be unpickled because it is already loaded")
37-
None
38-
}
39-
4035
def compilationUnit(cls: Symbol): Option[CompilationUnit] = cls match {
4136
case cls: ClassSymbol =>
4237
(cls.rootTreeOrProvider: @unchecked) match {
@@ -51,7 +46,7 @@ class ReadTasty extends Phase {
5146
cls.denot.infoOrCompleter match {
5247
case _: NoLoader => Some(Scala2CompilationUnit(cls.fullName.toString))
5348
case _ if cls.flags.is(Flags.JavaDefined) => Some(JavaCompilationUnit(cls.fullName.toString))
54-
case _ => alreadyLoaded()
49+
case _ => Some(AlreadyLoadedCompilationUnit(cls.denot.fullName.toString))
5550
}
5651
case _ =>
5752
cannotUnpickle(s"its class file does not have a TASTY attribute")

compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
6767
def Context_requiredMethod(self: Context)(path: String): Symbol = self.requiredMethod(path)
6868
def Context_isJavaCompilationUnit(self: Context): Boolean = self.compilationUnit.isInstanceOf[fromtasty.JavaCompilationUnit]
6969
def Context_isScala2CompilationUnit(self: Context): Boolean = self.compilationUnit.isInstanceOf[fromtasty.Scala2CompilationUnit]
70+
def Context_isAlreadyLoadedCompilationUnit(self: Context): Boolean = self.compilationUnit.isInstanceOf[fromtasty.AlreadyLoadedCompilationUnit]
7071
def Context_compilationUnitClassname(self: Context): String =
7172
self.compilationUnit match {
7273
case cu: fromtasty.JavaCompilationUnit => cu.className
7374
case cu: fromtasty.Scala2CompilationUnit => cu.className
75+
case cu: fromtasty.AlreadyLoadedCompilationUnit => cu.className
7476
case cu => ""
7577
}
7678

library/src/scala/tasty/Reflection.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,9 @@ class Reflection(private[scala] val internal: CompilerInterface) { self =>
448448
/** Returns true if we've tried to reflect on a Scala2 (non-Tasty) class. */
449449
def isScala2CompilationUnit(): Boolean = internal Context_isScala2CompilationUnit(self)
450450

451+
/** Returns true if we've tried to reflect on a class that's already loaded (e.g. Option). */
452+
def isAlreadyLoadedCompilationUnit(): Boolean = internal.Context_isAlreadyLoadedCompilationUnit(self)
453+
451454
/** Class name of the current CompilationUnit */
452455
def compilationUnitClassname(): String = internal.Context_compilationUnitClassname(self)
453456
}

library/src/scala/tasty/reflect/CompilerInterface.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ trait CompilerInterface {
168168
/** Returns true if we've tried to reflect on a Scala2 (non-Tasty) class. */
169169
def Context_isScala2CompilationUnit(self: Context): Boolean
170170

171+
/** Returns true if we've tried to reflect on a class that's already loaded (e.g. Option). */
172+
def Context_isAlreadyLoadedCompilationUnit(self: Context): Boolean
173+
171174
/** Class name of the current CompilationUnit */
172175
def Context_compilationUnitClassname(self: Context): String
173176

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import scala.tasty.Reflection
2+
import scala.tasty.inspector._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
7+
// Tasty Scala Class
8+
val inspector = new TestInspector_NonTasty()
9+
inspector.inspect("", List("scala.Option"))
10+
assert(inspector.isAlreadyLoaded)
11+
assert(inspector.className == "scala.Option")
12+
}
13+
}
14+
15+
class TestInspector_NonTasty() extends TastyInspector:
16+
17+
var isAlreadyLoaded: Boolean = false
18+
var className: String = ""
19+
20+
protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit =
21+
import reflect.{_, given _}
22+
isAlreadyLoaded = reflect.rootContext.isAlreadyLoadedCompilationUnit()
23+
className = reflect.rootContext.compilationUnitClassname()

0 commit comments

Comments
 (0)