From 922885f7eb2bba251ee9b95173ef9633daf32eee Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 27 Jul 2021 14:03:30 +0100 Subject: [PATCH 1/2] Make accessing OriginalTree noop on Scala 2.12.0-2 --- .../src/main/scala-2.12/xsbt/Compat.scala | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/internal/compiler-bridge/src/main/scala-2.12/xsbt/Compat.scala b/internal/compiler-bridge/src/main/scala-2.12/xsbt/Compat.scala index 13c9d77249..49c35d79d6 100644 --- a/internal/compiler-bridge/src/main/scala-2.12/xsbt/Compat.scala +++ b/internal/compiler-bridge/src/main/scala-2.12/xsbt/Compat.scala @@ -22,10 +22,7 @@ abstract class Compat { /** If given tree contains object tree attachment calls func on tree from attachment. */ protected def processOriginalTreeAttachment(in: Tree)(func: Tree => Unit): Unit = { - import analyzer._ - in.attachments.get[OriginalTreeAttachment].foreach { a => - func(a.original) - } + Compat.OriginalTreeTraverser.Instance.traverseOriginal(in)(func) } } object Compat { @@ -34,6 +31,32 @@ object Compat { // IMain in 2.13 accepts ReplReporter def replReporter(settings: Settings, writer: PrintWriter) = writer + + sealed abstract class OriginalTreeTraverser private { + def traverseOriginal[T <: Global#Tree](t: T)(f: T => Unit): Unit + } + + object OriginalTreeTraverser { + private[this] val cls = try { + Class.forName("scala.tools.nsc.typechecker.StdAttachments$OriginalTreeAttachment") + } catch { case _: Throwable => null } + + private object Reflective extends OriginalTreeTraverser { + private[this] val ct = scala.reflect.ClassTag(cls) + private[this] val meth = cls.getMethod("original") + def traverseOriginal[T <: Global#Tree](t: T)(f: T => Unit): Unit = + t.attachments.get(ct) match { + case Some(attachment) => f(meth.invoke(attachment).asInstanceOf[T]) + case None => + } + } + + private object NoOp extends OriginalTreeTraverser { + def traverseOriginal[T <: Global#Tree](t: T)(f: T => Unit): Unit = () + } + + val Instance = if (cls == null) NoOp else Reflective + } } /** Defines compatibility utils for [[ZincCompiler]]. */ From 97ae167a669ee8c6b8414a64a17cd72bf9b631fb Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 28 Jul 2021 10:52:13 +1000 Subject: [PATCH 2/2] Fix ClassCastException in reflective original tree lookup --- internal/compiler-bridge/src/main/scala-2.12/xsbt/Compat.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/compiler-bridge/src/main/scala-2.12/xsbt/Compat.scala b/internal/compiler-bridge/src/main/scala-2.12/xsbt/Compat.scala index 49c35d79d6..48a691e6f8 100644 --- a/internal/compiler-bridge/src/main/scala-2.12/xsbt/Compat.scala +++ b/internal/compiler-bridge/src/main/scala-2.12/xsbt/Compat.scala @@ -42,7 +42,7 @@ object Compat { } catch { case _: Throwable => null } private object Reflective extends OriginalTreeTraverser { - private[this] val ct = scala.reflect.ClassTag(cls) + private[this] val ct = scala.reflect.ClassTag[AnyRef](cls) private[this] val meth = cls.getMethod("original") def traverseOriginal[T <: Global#Tree](t: T)(f: T => Unit): Unit = t.attachments.get(ct) match {