From 12152c445725563fe24142fab90730eac9f51902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 12 Dec 2023 10:53:05 +0100 Subject: [PATCH] Do not crash when reading a Scala 2 `macro` definition. It contains an annotation with a subtree that is an `IDENTtree` without prefix nor symbol, with the name `macro`. That is then `Apply`ed and `TypeApply`ed in ways that make no semantic sense. We define a special symbol in `Definitions`, which we attach to such fake identifiers. --- .../shared/src/main/scala/tastyquery/Definitions.scala | 9 +++++++++ .../shared/src/main/scala/tastyquery/Names.scala | 2 ++ .../main/scala/tastyquery/reader/ReaderContext.scala | 2 ++ .../scala/tastyquery/reader/pickles/PickleReader.scala | 10 ++++++---- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/tasty-query/shared/src/main/scala/tastyquery/Definitions.scala b/tasty-query/shared/src/main/scala/tastyquery/Definitions.scala index a347e83e..6f924ee7 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Definitions.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Definitions.scala @@ -145,6 +145,15 @@ final class Definitions private[tastyquery] (ctx: Context, rootPackage: PackageS .checkCompleted() end scala2FakeOwner + private[tastyquery] val scala2MacroInfoFakeMethod: TermSymbol = + TermSymbol + .createNotDeclaration(nme.m_macro, scalaPackage) + .withFlags(Synthetic, None) + .withDeclaredType(NothingType) + .setAnnotations(Nil) + .checkCompleted() + end scala2MacroInfoFakeMethod + private def createSpecialTypeAlias( name: TypeName, owner: DeclaringSymbol, diff --git a/tasty-query/shared/src/main/scala/tastyquery/Names.scala b/tasty-query/shared/src/main/scala/tastyquery/Names.scala index 2a89882d..1c30fa34 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Names.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Names.scala @@ -63,6 +63,8 @@ object Names { val m_apply: SimpleName = termName("apply") val m_unapply: SimpleName = termName("unapply") + + private[tastyquery] val m_macro: SimpleName = termName("macro") } object tpnme { diff --git a/tasty-query/shared/src/main/scala/tastyquery/reader/ReaderContext.scala b/tasty-query/shared/src/main/scala/tastyquery/reader/ReaderContext.scala index 2b2b3875..d1a4f7dc 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/reader/ReaderContext.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/reader/ReaderContext.scala @@ -45,6 +45,8 @@ private[reader] final class ReaderContext(underlying: Context): def scala2FakeOwner: TermSymbol = underlying.defn.scala2FakeOwner + def scala2MacroInfoFakeMethod: TermSymbol = underlying.defn.scala2MacroInfoFakeMethod + def findPackageFromRootOrCreate(fullyQualifiedName: PackageFullName): PackageSymbol = underlying.findPackageFromRootOrCreate(fullyQualifiedName) diff --git a/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala b/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala index 17ebace9..9a69b8f5 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala @@ -1006,10 +1006,12 @@ private[pickles] class PickleReader { val designator = readMaybeExternalSymbolRef() val name = readTermNameRef() val tpe: TermReferenceType = designator match - case sym: TermSymbol => sym.localRef - case sym: PackageSymbol => sym.packageRef - case external: ExternalSymbolRef => external.toTermRef(NoPrefix) - case _ => errorBadSignature(s"illegal $designator for IDENTtree (name '$name')") + case sym: TermSymbol => sym.localRef + case sym: PackageSymbol => sym.packageRef + case external: ExternalSymbolRef => external.toTermRef(NoPrefix) + case _: NoExternalSymbolRef if name == nme.m_macro => rctx.scala2MacroInfoFakeMethod.localRef + case _ => + errorBadSignature(s"illegal $designator for IDENTtree (name '$name')") Ident(name)(tpe)(pos) case LITERALtree =>