From 1df17bb7bf8eea99ae4e74027edb1bf0b3165202 Mon Sep 17 00:00:00 2001 From: Tom Grigg Date: Thu, 12 May 2022 20:33:10 -0700 Subject: [PATCH] Avoid overeager completion of annotations in classfile parser --- .../src/dotty/tools/dotc/core/Definitions.scala | 4 ---- .../dotc/core/classfile/ClassfileParser.scala | 16 +++++++++++----- .../i15166/InterfaceAudience_JAVA_ONLY_1.java | 8 ++++++++ .../i15166/InterfaceStability_JAVA_ONLY_1.java | 8 ++++++++ tests/pos/i15166/Test_2.scala | 4 ++++ 5 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 tests/pos/i15166/InterfaceAudience_JAVA_ONLY_1.java create mode 100644 tests/pos/i15166/InterfaceStability_JAVA_ONLY_1.java create mode 100644 tests/pos/i15166/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index e09b7ca98955..23eff2fa2acf 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -961,13 +961,9 @@ class Definitions { @tu lazy val NativeAnnot: ClassSymbol = requiredClass("scala.native") @tu lazy val RepeatedAnnot: ClassSymbol = requiredClass("scala.annotation.internal.Repeated") @tu lazy val SourceFileAnnot: ClassSymbol = requiredClass("scala.annotation.internal.SourceFile") - @tu lazy val ScalaSignatureAnnot: ClassSymbol = requiredClass("scala.reflect.ScalaSignature") - @tu lazy val ScalaLongSignatureAnnot: ClassSymbol = requiredClass("scala.reflect.ScalaLongSignature") @tu lazy val ScalaStrictFPAnnot: ClassSymbol = requiredClass("scala.annotation.strictfp") @tu lazy val ScalaStaticAnnot: ClassSymbol = requiredClass("scala.annotation.static") @tu lazy val SerialVersionUIDAnnot: ClassSymbol = requiredClass("scala.SerialVersionUID") - @tu lazy val TASTYSignatureAnnot: ClassSymbol = requiredClass("scala.annotation.internal.TASTYSignature") - @tu lazy val TASTYLongSignatureAnnot: ClassSymbol = requiredClass("scala.annotation.internal.TASTYLongSignature") @tu lazy val TailrecAnnot: ClassSymbol = requiredClass("scala.annotation.tailrec") @tu lazy val ThreadUnsafeAnnot: ClassSymbol = requiredClass("scala.annotation.threadUnsafe") @tu lazy val ConstructorOnlyAnnot: ClassSymbol = requiredClass("scala.annotation.constructorOnly") diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index a45ff756173a..0e9a8d24801c 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -51,6 +51,12 @@ object ClassfileParser { mapOver(tp) } } + + private inline def sigOfClassName(n: String) = s"L$n;" + val ScalaSignatureAnnot: String = sigOfClassName("scala.reflect.ScalaSignature") + val ScalaLongSignatureAnnot: String = sigOfClassName("scala.reflect.ScalaLongSignature") + val TASTYSignatureAnnot: String = sigOfClassName("scala.annotation.internal.TASTYSignature") + val TASTYLongSignatureAnnot: String = sigOfClassName("scala.annotation.internal.TASTYLongSignature") } class ClassfileParser( @@ -1033,19 +1039,19 @@ class ClassfileParser( val nAnnots = in.nextChar var i = 0 while (i < nAnnots) { - val attrClass = pool.getType(in.nextChar).typeSymbol + val attrSig = pool.getExternalName(in.nextChar).value val nArgs = in.nextChar var j = 0 while (j < nArgs) { val argName = pool.getName(in.nextChar) if (argName.name == nme.bytes) { - if (attrClass == defn.ScalaSignatureAnnot) + if attrSig == ScalaSignatureAnnot then return unpickleScala(parseScalaSigBytes) - else if (attrClass == defn.ScalaLongSignatureAnnot) + else if attrSig == ScalaLongSignatureAnnot then return unpickleScala(parseScalaLongSigBytes) - else if (attrClass == defn.TASTYSignatureAnnot) + else if attrSig == TASTYSignatureAnnot then return unpickleTASTY(parseScalaSigBytes) - else if (attrClass == defn.TASTYLongSignatureAnnot) + else if attrSig == TASTYLongSignatureAnnot then return unpickleTASTY(parseScalaLongSigBytes) } parseAnnotArg(skip = true) diff --git a/tests/pos/i15166/InterfaceAudience_JAVA_ONLY_1.java b/tests/pos/i15166/InterfaceAudience_JAVA_ONLY_1.java new file mode 100644 index 000000000000..2b6256620594 --- /dev/null +++ b/tests/pos/i15166/InterfaceAudience_JAVA_ONLY_1.java @@ -0,0 +1,8 @@ +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@InterfaceStability_JAVA_ONLY_1.Evolving(bytes="no") +public class InterfaceAudience_JAVA_ONLY_1 { + @Retention(RetentionPolicy.RUNTIME) + public @interface Public { String bytes(); } +} diff --git a/tests/pos/i15166/InterfaceStability_JAVA_ONLY_1.java b/tests/pos/i15166/InterfaceStability_JAVA_ONLY_1.java new file mode 100644 index 000000000000..5bdf9b90a0f3 --- /dev/null +++ b/tests/pos/i15166/InterfaceStability_JAVA_ONLY_1.java @@ -0,0 +1,8 @@ +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@InterfaceAudience_JAVA_ONLY_1.Public(bytes="yes") +public class InterfaceStability_JAVA_ONLY_1 { + @Retention(RetentionPolicy.RUNTIME) + public @interface Evolving { String bytes(); } +} diff --git a/tests/pos/i15166/Test_2.scala b/tests/pos/i15166/Test_2.scala new file mode 100644 index 000000000000..53e6da69a42c --- /dev/null +++ b/tests/pos/i15166/Test_2.scala @@ -0,0 +1,4 @@ +// scalac: -Xfatal-warnings +object Test { + val x: InterfaceAudience_JAVA_ONLY_1.Public = ??? +}