From 95f38afe8a75ac9c41925c1aa0772752f4aab0fe Mon Sep 17 00:00:00 2001 From: gzoller Date: Wed, 5 Feb 2020 17:25:03 -0600 Subject: [PATCH 1/7] i8215 Add ability to detect attempted Tasty inspection of a Java class --- .../dotc/fromtasty/JavaCompilationUnit.scala | 13 ++++++++++ .../tools/dotc/fromtasty/ReadTasty.scala | 5 +++- .../ReflectionCompilerInterface.scala | 5 ++++ library/src/scala/tasty/Reflection.scala | 3 +++ .../tasty/reflect/CompilerInterface.scala | 3 +++ .../tasty-inspector/i8215.scala | 24 +++++++++++++++++++ 6 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala create mode 100644 tests/run-custom-args/tasty-inspector/i8215.scala diff --git a/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala b/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala new file mode 100644 index 000000000000..e7c501a2c8f9 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala @@ -0,0 +1,13 @@ +package dotty.tools.dotc.fromtasty + +import dotty.tools.dotc.CompilationUnit +import dotty.tools.dotc.util.NoSource + +/** + * A marker CompilationUnit to return up the call stack from ReadTasty. This will tell us that we've + * encountered, and attempted to inspect, a Java class file. We can't TASTy-inspect a Java class obviously, + * but we want to return the fact we found it so that higher-up we can take appropriate action if desired. + */ +class JavaCompilationUnit(val className: String) extends CompilationUnit(NoSource) { + override def toString: String = s"java class file $className" +} \ No newline at end of file diff --git a/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala b/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala index 837270504132..d5fe7c999f88 100644 --- a/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala +++ b/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala @@ -48,7 +48,10 @@ class ReadTasty extends Phase { Some(unit) } case tree: Tree[?] => - alreadyLoaded() + if( cls.flags.is(Flags.JavaDefined) ) // Is this a Java class we've tried to inspect? + Some(JavaCompilationUnit(cls.fullName.toString)) + else + alreadyLoaded() case _ => cannotUnpickle(s"its class file does not have a TASTY attribute") } diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index 201d18e558e9..0ce1b590eba3 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -65,6 +65,11 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Context_requiredClass(self: Context)(path: String): Symbol = self.requiredClass(path) def Context_requiredModule(self: Context)(path: String): Symbol = self.requiredModule(path) def Context_requiredMethod(self: Context)(path: String): Symbol = self.requiredMethod(path) + def Context_getJavaClassname(self: Context): Option[String] = + self.compilationUnit match { + case j: fromtasty.JavaCompilationUnit => Some(j.className) + case _ => None + } /////////////// diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index dfdf138bdb0c..6421cef395a4 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -473,6 +473,9 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => /** Get method symbol if method is either defined in current compilation run or present on classpath. Throws if the method has an overload. */ def requiredMethod(path: String): Symbol = internal.Context_requiredMethod(self)(path) + /** Get Java class name if we've accidentally tried to reflect on a Java class. None returned if TASTy class. */ + def getJavaClassname(): Option[String] = internal.Context_getJavaClassname(self) + } diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index b2f08fc65e30..6292f9deda09 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -162,6 +162,9 @@ trait CompilerInterface { /** Get method symbol if method is either defined in current compilation run or present on classpath. Throws if the method has an overload. */ def Context_requiredMethod(self: Context)(path: String): Symbol + /** Get Java class name if we've accidentally tried to reflect on a Java class. None returned if TASTy class. */ + def Context_getJavaClassname(self: Context): Option[String] + /////////////// // REPORTING // diff --git a/tests/run-custom-args/tasty-inspector/i8215.scala b/tests/run-custom-args/tasty-inspector/i8215.scala new file mode 100644 index 000000000000..edb4160f6c8e --- /dev/null +++ b/tests/run-custom-args/tasty-inspector/i8215.scala @@ -0,0 +1,24 @@ +import scala.tasty.Reflection +import scala.tasty.inspector._ + +case class I8215(id: String) + +object Test { + def main(args: Array[String]): Unit = { + val inspect1 = new TestInspector() + inspect1.inspect("", List("I8215")) + assert(inspect1.gotJava == None) + + val inspect2 = new TestInspector() + inspect2.inspect("", List("java.util.UUID")) + assert(inspect2.gotJava == Some("java.util.UUID")) + } +} + +class TestInspector() extends TastyInspector + + var gotJava: Option[String] = None + + protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = + import reflect.{given,_} + gotJava = reflect.rootContext.getJavaClassname() \ No newline at end of file From e870c41bc41126937ea3409be48db24ca83c2370 Mon Sep 17 00:00:00 2001 From: gzoller Date: Thu, 6 Feb 2020 10:19:41 -0600 Subject: [PATCH 2/7] changed method name to be more descriptive --- .../tools/dotc/tastyreflect/ReflectionCompilerInterface.scala | 2 +- library/src/scala/tasty/Reflection.scala | 2 +- library/src/scala/tasty/reflect/CompilerInterface.scala | 2 +- tests/run-custom-args/tasty-inspector/i8215.scala | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index 0ce1b590eba3..74baa3737202 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -65,7 +65,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Context_requiredClass(self: Context)(path: String): Symbol = self.requiredClass(path) def Context_requiredModule(self: Context)(path: String): Symbol = self.requiredModule(path) def Context_requiredMethod(self: Context)(path: String): Symbol = self.requiredMethod(path) - def Context_getJavaClassname(self: Context): Option[String] = + def Context_javaCompilationUnitClassname(self: Context): Option[String] = self.compilationUnit match { case j: fromtasty.JavaCompilationUnit => Some(j.className) case _ => None diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 6421cef395a4..8c2f4490b145 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -474,7 +474,7 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => def requiredMethod(path: String): Symbol = internal.Context_requiredMethod(self)(path) /** Get Java class name if we've accidentally tried to reflect on a Java class. None returned if TASTy class. */ - def getJavaClassname(): Option[String] = internal.Context_getJavaClassname(self) + def javaCompilationUnitClassname(): Option[String] = internal.Context_javaCompilationUnitClassname(self) } diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index 6292f9deda09..d2b4a9006ee0 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -163,7 +163,7 @@ trait CompilerInterface { def Context_requiredMethod(self: Context)(path: String): Symbol /** Get Java class name if we've accidentally tried to reflect on a Java class. None returned if TASTy class. */ - def Context_getJavaClassname(self: Context): Option[String] + def Context_javaCompilationUnitClassname(self: Context): Option[String] /////////////// diff --git a/tests/run-custom-args/tasty-inspector/i8215.scala b/tests/run-custom-args/tasty-inspector/i8215.scala index edb4160f6c8e..4f8292c0c789 100644 --- a/tests/run-custom-args/tasty-inspector/i8215.scala +++ b/tests/run-custom-args/tasty-inspector/i8215.scala @@ -21,4 +21,4 @@ class TestInspector() extends TastyInspector protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = import reflect.{given,_} - gotJava = reflect.rootContext.getJavaClassname() \ No newline at end of file + gotJava = reflect.rootContext.javaCompilationUnitClassname() \ No newline at end of file From 22cff0d6684d1e61ff76ec6ad88dba5d9c27e3cf Mon Sep 17 00:00:00 2001 From: gzoller Date: Fri, 7 Feb 2020 10:30:29 -0600 Subject: [PATCH 3/7] Fixed flags bug in ReadTasty --- .../dotc/fromtasty/JavaCompilationUnit.scala | 2 +- .../NonTastyScalaCompilationUnit.scala | 13 +++++++++ .../tools/dotc/fromtasty/ReadTasty.scala | 9 ++++--- .../ReflectionCompilerInterface.scala | 5 ++++ library/src/scala/tasty/Reflection.scala | 2 ++ .../tasty/reflect/CompilerInterface.scala | 3 +++ .../tasty-inspector/i8215.scala | 27 ++++++++++++++----- 7 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala diff --git a/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala b/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala index e7c501a2c8f9..e033ac0ae1d1 100644 --- a/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala +++ b/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala @@ -9,5 +9,5 @@ import dotty.tools.dotc.util.NoSource * but we want to return the fact we found it so that higher-up we can take appropriate action if desired. */ class JavaCompilationUnit(val className: String) extends CompilationUnit(NoSource) { - override def toString: String = s"java class file $className" + override def toString: String = s"Java class file $className" } \ No newline at end of file diff --git a/compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala b/compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala new file mode 100644 index 000000000000..a631c37aa4b1 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala @@ -0,0 +1,13 @@ +package dotty.tools.dotc.fromtasty + +import dotty.tools.dotc.CompilationUnit +import dotty.tools.dotc.util.NoSource + +/** + * A marker CompilationUnit to return up the call stack from ReadTasty. This will tell us that we've + * encountered, and attempted to inspect, a Java class file. We can't TASTy-inspect a Java class obviously, + * but we want to return the fact we found it so that higher-up we can take appropriate action if desired. + */ +class NonTastyScalaCompilationUnit(val className: String) extends CompilationUnit(NoSource) { + override def toString: String = s"Non-Tasty Scala class file $className" +} \ No newline at end of file diff --git a/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala b/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala index d5fe7c999f88..1f557cefe512 100644 --- a/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala +++ b/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala @@ -48,10 +48,11 @@ class ReadTasty extends Phase { Some(unit) } case tree: Tree[?] => - if( cls.flags.is(Flags.JavaDefined) ) // Is this a Java class we've tried to inspect? - Some(JavaCompilationUnit(cls.fullName.toString)) - else - alreadyLoaded() + cls.denot.infoOrCompleter match { + case _: NoLoader => Some(NonTastyScalaCompilationUnit(cls.fullName.toString)) + case _ if cls.flags.is(Flags.JavaDefined) => Some(JavaCompilationUnit(cls.fullName.toString)) + case _ => alreadyLoaded() + } case _ => cannotUnpickle(s"its class file does not have a TASTY attribute") } diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index 74baa3737202..ec6ac6c078f3 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -70,6 +70,11 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend case j: fromtasty.JavaCompilationUnit => Some(j.className) case _ => None } + def Context_nonTastyScalaCompilationUnitClassname(self: Context): Option[String] = + self.compilationUnit match { + case s: fromtasty.NonTastyScalaCompilationUnit => Some(s.className) + case _ => None + } /////////////// diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 8c2f4490b145..3be10d7ca4f7 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -476,6 +476,8 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => /** Get Java class name if we've accidentally tried to reflect on a Java class. None returned if TASTy class. */ def javaCompilationUnitClassname(): Option[String] = internal.Context_javaCompilationUnitClassname(self) + /** Get Scala class name if attempted reflection is performed on an older Scala file w/o Tasty information present. */ + def nonTastyScalaCompilationUnitClassname(): Option[String] = internal.Context_nonTastyScalaCompilationUnitClassname(self) } diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index d2b4a9006ee0..af4b4a22af70 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -165,6 +165,9 @@ trait CompilerInterface { /** Get Java class name if we've accidentally tried to reflect on a Java class. None returned if TASTy class. */ def Context_javaCompilationUnitClassname(self: Context): Option[String] + /** Get Scala class name if attempted reflection is performed on an older Scala file w/o Tasty information present. */ + def Context_nonTastyScalaCompilationUnitClassname(self: Context): Option[String] + /////////////// // REPORTING // diff --git a/tests/run-custom-args/tasty-inspector/i8215.scala b/tests/run-custom-args/tasty-inspector/i8215.scala index 4f8292c0c789..46bd3695aa28 100644 --- a/tests/run-custom-args/tasty-inspector/i8215.scala +++ b/tests/run-custom-args/tasty-inspector/i8215.scala @@ -5,20 +5,33 @@ case class I8215(id: String) object Test { def main(args: Array[String]): Unit = { - val inspect1 = new TestInspector() - inspect1.inspect("", List("I8215")) - assert(inspect1.gotJava == None) - val inspect2 = new TestInspector() - inspect2.inspect("", List("java.util.UUID")) - assert(inspect2.gotJava == Some("java.util.UUID")) + // Tasty Scala Class + val inspect1 = new TestInspector() + inspect1.inspect("", List("I8215")) + assert(inspect1.gotJava == None) + assert(inspect1.gotNonTastyScala == None) + + // Java Class + val inspect2 = new TestInspector() + inspect2.inspect("", List("java.util.UUID")) + assert(inspect2.gotJava == Some("java.util.UUID")) + assert(inspect2.gotNonTastyScala == None) + + // Legacy non-Tasty Scala class + val inspect3 = new TestInspector() + inspect3.inspect("", List("scala.collection.immutable.RedBlackTree")) + assert(inspect3.gotJava == None) + assert(inspect3.gotNonTastyScala == Some("scala.collection.immutable.RedBlackTree")) } } class TestInspector() extends TastyInspector var gotJava: Option[String] = None + var gotNonTastyScala: Option[String] = None protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = import reflect.{given,_} - gotJava = reflect.rootContext.javaCompilationUnitClassname() \ No newline at end of file + gotJava = reflect.rootContext.javaCompilationUnitClassname() + gotNonTastyScala = reflect.rootContext.nonTastyScalaCompilationUnitClassname() \ No newline at end of file From 0afdbcd0a96d81362c62ed9ca4dbc51d85cc5a90 Mon Sep 17 00:00:00 2001 From: gzoller Date: Fri, 7 Feb 2020 10:32:18 -0600 Subject: [PATCH 4/7] wording fix in comment --- .../tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala b/compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala index a631c37aa4b1..72a97ec356a5 100644 --- a/compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala +++ b/compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala @@ -5,8 +5,9 @@ import dotty.tools.dotc.util.NoSource /** * A marker CompilationUnit to return up the call stack from ReadTasty. This will tell us that we've - * encountered, and attempted to inspect, a Java class file. We can't TASTy-inspect a Java class obviously, - * but we want to return the fact we found it so that higher-up we can take appropriate action if desired. + * encountered, and attempted to inspect, a non-Tasty Scala class file (for example a legacy class pre-Scala 3). + * In this case we still want to return the fact we found it so that higher-up we can take appropriate + * action if desired. */ class NonTastyScalaCompilationUnit(val className: String) extends CompilationUnit(NoSource) { override def toString: String = s"Non-Tasty Scala class file $className" From 1e1a3a3de53f5a341a2322b17973699aba8b318d Mon Sep 17 00:00:00 2001 From: gzoller Date: Mon, 10 Feb 2020 11:43:36 -0600 Subject: [PATCH 5/7] implemented requested changes --- .../dotc/fromtasty/JavaCompilationUnit.scala | 7 +++--- .../NonTastyScalaCompilationUnit.scala | 14 ----------- .../tools/dotc/fromtasty/ReadTasty.scala | 2 +- .../fromtasty/Scala2CompilationUnit.scala | 13 ++++++++++ .../ReflectionCompilerInterface.scala | 14 +++++------ library/src/scala/tasty/Reflection.scala | 11 +++++--- .../tasty/reflect/CompilerInterface.scala | 11 +++++--- .../tasty-inspector/i8215.scala | 25 +++++++++++-------- 8 files changed, 52 insertions(+), 45 deletions(-) delete mode 100644 compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala create mode 100644 compiler/src/dotty/tools/dotc/fromtasty/Scala2CompilationUnit.scala diff --git a/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala b/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala index e033ac0ae1d1..de84b5c38561 100644 --- a/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala +++ b/compiler/src/dotty/tools/dotc/fromtasty/JavaCompilationUnit.scala @@ -3,10 +3,9 @@ package dotty.tools.dotc.fromtasty import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.util.NoSource -/** - * A marker CompilationUnit to return up the call stack from ReadTasty. This will tell us that we've - * encountered, and attempted to inspect, a Java class file. We can't TASTy-inspect a Java class obviously, - * but we want to return the fact we found it so that higher-up we can take appropriate action if desired. +/** A marker CompilationUnit to return up the call stack from ReadTasty. This will tell us that we've + * encountered, and attempted to inspect, a Java class file. We can't TASTy-inspect a Java class obviously, + * but we want to return the fact we found it so that higher-up we can take appropriate action if desired. */ class JavaCompilationUnit(val className: String) extends CompilationUnit(NoSource) { override def toString: String = s"Java class file $className" diff --git a/compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala b/compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala deleted file mode 100644 index 72a97ec356a5..000000000000 --- a/compiler/src/dotty/tools/dotc/fromtasty/NonTastyScalaCompilationUnit.scala +++ /dev/null @@ -1,14 +0,0 @@ -package dotty.tools.dotc.fromtasty - -import dotty.tools.dotc.CompilationUnit -import dotty.tools.dotc.util.NoSource - -/** - * A marker CompilationUnit to return up the call stack from ReadTasty. This will tell us that we've - * encountered, and attempted to inspect, a non-Tasty Scala class file (for example a legacy class pre-Scala 3). - * In this case we still want to return the fact we found it so that higher-up we can take appropriate - * action if desired. - */ -class NonTastyScalaCompilationUnit(val className: String) extends CompilationUnit(NoSource) { - override def toString: String = s"Non-Tasty Scala class file $className" -} \ No newline at end of file diff --git a/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala b/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala index 1f557cefe512..a909e12dcc2d 100644 --- a/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala +++ b/compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala @@ -49,7 +49,7 @@ class ReadTasty extends Phase { } case tree: Tree[?] => cls.denot.infoOrCompleter match { - case _: NoLoader => Some(NonTastyScalaCompilationUnit(cls.fullName.toString)) + case _: NoLoader => Some(Scala2CompilationUnit(cls.fullName.toString)) case _ if cls.flags.is(Flags.JavaDefined) => Some(JavaCompilationUnit(cls.fullName.toString)) case _ => alreadyLoaded() } diff --git a/compiler/src/dotty/tools/dotc/fromtasty/Scala2CompilationUnit.scala b/compiler/src/dotty/tools/dotc/fromtasty/Scala2CompilationUnit.scala new file mode 100644 index 000000000000..51ac0e52a3ed --- /dev/null +++ b/compiler/src/dotty/tools/dotc/fromtasty/Scala2CompilationUnit.scala @@ -0,0 +1,13 @@ +package dotty.tools.dotc.fromtasty + +import dotty.tools.dotc.CompilationUnit +import dotty.tools.dotc.util.NoSource + +/** A marker CompilationUnit to return up the call stack from ReadTasty. This will tell us that we've + * encountered, and attempted to inspect, a Scala2 class file (which has no .tasty file). + * In this case we still want to return the fact we found it so that higher-up we can take appropriate + * action if desired. + */ +class Scala2CompilationUnit(val className: String) extends CompilationUnit(NoSource) { + override def toString: String = s"Scala2 class file $className" +} \ No newline at end of file diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index ec6ac6c078f3..ab45d594f236 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -65,15 +65,13 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Context_requiredClass(self: Context)(path: String): Symbol = self.requiredClass(path) def Context_requiredModule(self: Context)(path: String): Symbol = self.requiredModule(path) def Context_requiredMethod(self: Context)(path: String): Symbol = self.requiredMethod(path) - def Context_javaCompilationUnitClassname(self: Context): Option[String] = + def Context_isJavaCompilationUnit(self: Context): Boolean = self.compilationUnit.isInstanceOf[fromtasty.JavaCompilationUnit] + def Context_isScala2CompilationUnit(self: Context): Boolean = self.compilationUnit.isInstanceOf[fromtasty.Scala2CompilationUnit] + def Context_compilationUnitClassname(self: Context): String = self.compilationUnit match { - case j: fromtasty.JavaCompilationUnit => Some(j.className) - case _ => None - } - def Context_nonTastyScalaCompilationUnitClassname(self: Context): Option[String] = - self.compilationUnit match { - case s: fromtasty.NonTastyScalaCompilationUnit => Some(s.className) - case _ => None + case cu: fromtasty.JavaCompilationUnit => cu.className + case cu: fromtasty.Scala2CompilationUnit => cu.className + case cu => "" } diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 3be10d7ca4f7..eda41fba1959 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -473,11 +473,14 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => /** Get method symbol if method is either defined in current compilation run or present on classpath. Throws if the method has an overload. */ def requiredMethod(path: String): Symbol = internal.Context_requiredMethod(self)(path) - /** Get Java class name if we've accidentally tried to reflect on a Java class. None returned if TASTy class. */ - def javaCompilationUnitClassname(): Option[String] = internal.Context_javaCompilationUnitClassname(self) + /** Returns true if we've tried to reflect on a Java class. */ + def isJavaCompilationUnit(): Boolean = internal Context_isJavaCompilationUnit(self) - /** Get Scala class name if attempted reflection is performed on an older Scala file w/o Tasty information present. */ - def nonTastyScalaCompilationUnitClassname(): Option[String] = internal.Context_nonTastyScalaCompilationUnitClassname(self) + /** Returns true if we've tried to reflect on a Scala2 (non-Tasty) class. */ + def isScala2CompilationUnit(): Boolean = internal Context_isScala2CompilationUnit(self) + + /** Class name of the current CompilationUnit */ + def compilationUnitClassname(): String = internal.Context_compilationUnitClassname(self) } diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index af4b4a22af70..4d8bde281daf 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -162,11 +162,14 @@ trait CompilerInterface { /** Get method symbol if method is either defined in current compilation run or present on classpath. Throws if the method has an overload. */ def Context_requiredMethod(self: Context)(path: String): Symbol - /** Get Java class name if we've accidentally tried to reflect on a Java class. None returned if TASTy class. */ - def Context_javaCompilationUnitClassname(self: Context): Option[String] + /** Returns true if we've tried to reflect on a Java class. */ + def Context_isJavaCompilationUnit(self: Context): Boolean - /** Get Scala class name if attempted reflection is performed on an older Scala file w/o Tasty information present. */ - def Context_nonTastyScalaCompilationUnitClassname(self: Context): Option[String] + /** Returns true if we've tried to reflect on a Scala2 (non-Tasty) class. */ + def Context_isScala2CompilationUnit(self: Context): Boolean + + /** Class name of the current CompilationUnit */ + def Context_compilationUnitClassname(self: Context): String /////////////// diff --git a/tests/run-custom-args/tasty-inspector/i8215.scala b/tests/run-custom-args/tasty-inspector/i8215.scala index 46bd3695aa28..98bb1d38505a 100644 --- a/tests/run-custom-args/tasty-inspector/i8215.scala +++ b/tests/run-custom-args/tasty-inspector/i8215.scala @@ -9,29 +9,34 @@ object Test { // Tasty Scala Class val inspect1 = new TestInspector() inspect1.inspect("", List("I8215")) - assert(inspect1.gotJava == None) - assert(inspect1.gotNonTastyScala == None) + assert(inspect1.isJava == false) + assert(inspect1.isScala2 == false) + assert(inspect1.className == "") // Java Class val inspect2 = new TestInspector() inspect2.inspect("", List("java.util.UUID")) - assert(inspect2.gotJava == Some("java.util.UUID")) - assert(inspect2.gotNonTastyScala == None) + assert(inspect2.isJava == true) + assert(inspect2.isScala2 == false) + assert(inspect2.className == "java.util.UUID") // Legacy non-Tasty Scala class val inspect3 = new TestInspector() inspect3.inspect("", List("scala.collection.immutable.RedBlackTree")) - assert(inspect3.gotJava == None) - assert(inspect3.gotNonTastyScala == Some("scala.collection.immutable.RedBlackTree")) + assert(inspect3.isJava == false) + assert(inspect3.isScala2 == true) + assert(inspect3.className == "scala.collection.immutable.RedBlackTree") } } class TestInspector() extends TastyInspector - var gotJava: Option[String] = None - var gotNonTastyScala: Option[String] = None + var isJava: Boolean = false + var isScala2: Boolean = false + var className: String = "" protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = import reflect.{given,_} - gotJava = reflect.rootContext.javaCompilationUnitClassname() - gotNonTastyScala = reflect.rootContext.nonTastyScalaCompilationUnitClassname() \ No newline at end of file + isJava = reflect.rootContext.isJavaCompilationUnit() + isScala2 = reflect.rootContext.isScala2CompilationUnit() + className = reflect.rootContext.compilationUnitClassname() From 5d7db95b7e715a964c940317f71bb03b37c71a51 Mon Sep 17 00:00:00 2001 From: gzoller Date: Mon, 10 Feb 2020 13:56:35 -0600 Subject: [PATCH 6/7] Attempt to fix build bug --- tests/run-custom-args/tasty-inspector/i8215.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/run-custom-args/tasty-inspector/i8215.scala b/tests/run-custom-args/tasty-inspector/i8215.scala index 98bb1d38505a..9ca64e8afca2 100644 --- a/tests/run-custom-args/tasty-inspector/i8215.scala +++ b/tests/run-custom-args/tasty-inspector/i8215.scala @@ -7,21 +7,21 @@ object Test { def main(args: Array[String]): Unit = { // Tasty Scala Class - val inspect1 = new TestInspector() + val inspect1 = new TestInspector_NonTasty() inspect1.inspect("", List("I8215")) assert(inspect1.isJava == false) assert(inspect1.isScala2 == false) assert(inspect1.className == "") // Java Class - val inspect2 = new TestInspector() + val inspect2 = new TestInspector_NonTasty() inspect2.inspect("", List("java.util.UUID")) assert(inspect2.isJava == true) assert(inspect2.isScala2 == false) assert(inspect2.className == "java.util.UUID") // Legacy non-Tasty Scala class - val inspect3 = new TestInspector() + val inspect3 = new TestInspector_NonTasty() inspect3.inspect("", List("scala.collection.immutable.RedBlackTree")) assert(inspect3.isJava == false) assert(inspect3.isScala2 == true) @@ -29,7 +29,7 @@ object Test { } } -class TestInspector() extends TastyInspector +class TestInspector_NonTasty() extends TastyInspector var isJava: Boolean = false var isScala2: Boolean = false From 22d56f31fa3d90925089f384cdf27eba8ca589c8 Mon Sep 17 00:00:00 2001 From: gzoller Date: Mon, 10 Feb 2020 15:58:20 -0600 Subject: [PATCH 7/7] second attempted fix --- tests/run-custom-args/tasty-inspector/i8215.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/run-custom-args/tasty-inspector/i8215.scala b/tests/run-custom-args/tasty-inspector/i8215.scala index 9ca64e8afca2..d244f720942e 100644 --- a/tests/run-custom-args/tasty-inspector/i8215.scala +++ b/tests/run-custom-args/tasty-inspector/i8215.scala @@ -29,14 +29,14 @@ object Test { } } -class TestInspector_NonTasty() extends TastyInspector +class TestInspector_NonTasty() extends TastyInspector: var isJava: Boolean = false var isScala2: Boolean = false var className: String = "" protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = - import reflect.{given,_} + import reflect.{_, given _} isJava = reflect.rootContext.isJavaCompilationUnit() isScala2 = reflect.rootContext.isScala2CompilationUnit() className = reflect.rootContext.compilationUnitClassname()