From 818baea2d8c344608e41592f1e956604688bc3cb Mon Sep 17 00:00:00 2001 From: James Hamilton Date: Thu, 6 Jan 2022 15:33:42 +0100 Subject: [PATCH] Add test for incorrect handling of Record.Signature attribute (#28) --- docs/md/releasenotes.md | 1 + ...ClassReferenceInitializerJavaRecordTest.kt | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/test/kotlin/proguard/classfile/util/ClassReferenceInitializerJavaRecordTest.kt diff --git a/docs/md/releasenotes.md b/docs/md/releasenotes.md index 9ee3f0934..e883d943b 100644 --- a/docs/md/releasenotes.md +++ b/docs/md/releasenotes.md @@ -11,6 +11,7 @@ - Make the `DominatorCalculator` skip methods with an empty `CodeAttribute`. - Prevent updating Kotlin function names with mangled JVM method names in `ClassReferenceFixer`. (`PGD-208`) - Initialize Kotlin default implementation classes of annotation classes correctly in `ClassReferenceInitializer`. +- Correctly initialize Java Record component attributes in `ClassReferenceInitializer`. (`PGC-28`, `PGD-194`) ### API changes diff --git a/src/test/kotlin/proguard/classfile/util/ClassReferenceInitializerJavaRecordTest.kt b/src/test/kotlin/proguard/classfile/util/ClassReferenceInitializerJavaRecordTest.kt new file mode 100644 index 000000000..19a10eaec --- /dev/null +++ b/src/test/kotlin/proguard/classfile/util/ClassReferenceInitializerJavaRecordTest.kt @@ -0,0 +1,95 @@ +/* + * ProGuardCORE -- library to process Java bytecode. + * + * Copyright (c) 2002-2022 Guardsquare NV + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package proguard.classfile.util + +import io.kotest.core.spec.style.FreeSpec +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe +import io.mockk.spyk +import io.mockk.verify +import proguard.classfile.attribute.RecordComponentInfo +import testutils.ClassPoolBuilder +import testutils.JavaSource +import testutils.RequiresJavaVersion + +@RequiresJavaVersion(15) +class ClassReferenceInitializerJavaRecordTest : FreeSpec({ + "Given a Java record class with a signature attribute" - { + val (programClassPool, libraryClassPool) = ClassPoolBuilder.fromSource( + JavaSource( + "Record.java", + """ + public record Record(Key key) {} + """.trimIndent() + ), + JavaSource( + "Key.java", + """ + public interface Key {} + """.trimIndent() + ), + initialize = false, + javacArguments = if (testutils.currentJavaVersion == 15) + listOf("--enable-preview", "--release", "15") else emptyList() + ) + + val recordClazz = programClassPool.getClass("Record") + + "Then the record class should not be null" { + recordClazz shouldNotBe null + } + + "Then initializing should visit the signature attributes correctly" { + val initializer = spyk(ClassReferenceInitializer(programClassPool, libraryClassPool)) + + programClassPool.classesAccept(initializer) + + verify(exactly = 1) { + // The class attribute should be visited. + initializer.visitSignatureAttribute( + recordClazz, + withArg { + it.getSignature(recordClazz) shouldBe "Ljava/lang/Record;" + } + ) + + // The record component attribute should be visited. + initializer.visitSignatureAttribute( + recordClazz, + ofType(), + withArg { + it.getSignature(recordClazz) shouldBe "LKey;" + } + ) + } + + verify(exactly = 0) { + // The record component attribute should not be visited as generic attribute. + // This happens if the ClassReferenceInitializer does not override + // the RecordComponentInfo specific method. + initializer.visitSignatureAttribute( + recordClazz, + withArg { + it.getSignature(recordClazz) shouldBe "LKey;" + } + ) + } + } + } +})