[stubs] fix `PSI and index do not match` exception when opening a class with repeatable annotation definition from a library The corresponding code was removed during the KTIJ-27464 fix, now it's restored ^KTIJ-31162 fixed
diff --git a/analysis/decompiled/decompiler-native/tests/org/jetbrains/kotlin/analysis/decompiler/konan/DecompiledKnmStubConsistencyFe10TestGenerated.java b/analysis/decompiled/decompiler-native/tests/org/jetbrains/kotlin/analysis/decompiler/konan/DecompiledKnmStubConsistencyFe10TestGenerated.java index f41e54f..74054d7 100644 --- a/analysis/decompiled/decompiler-native/tests/org/jetbrains/kotlin/analysis/decompiler/konan/DecompiledKnmStubConsistencyFe10TestGenerated.java +++ b/analysis/decompiled/decompiler-native/tests/org/jetbrains/kotlin/analysis/decompiler/konan/DecompiledKnmStubConsistencyFe10TestGenerated.java
@@ -240,6 +240,12 @@ } @Test + @TestMetadata("RepeatableAnnotationClass") + public void testRepeatableAnnotationClass() { + runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/"); + } + + @Test @TestMetadata("Sealed") public void testSealed() { runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/Sealed/");
diff --git a/analysis/decompiled/decompiler-native/tests/org/jetbrains/kotlin/analysis/decompiler/konan/DecompiledKnmStubConsistencyK2TestGenerated.java b/analysis/decompiled/decompiler-native/tests/org/jetbrains/kotlin/analysis/decompiler/konan/DecompiledKnmStubConsistencyK2TestGenerated.java index 313461c..8ad4758 100644 --- a/analysis/decompiled/decompiler-native/tests/org/jetbrains/kotlin/analysis/decompiler/konan/DecompiledKnmStubConsistencyK2TestGenerated.java +++ b/analysis/decompiled/decompiler-native/tests/org/jetbrains/kotlin/analysis/decompiler/konan/DecompiledKnmStubConsistencyK2TestGenerated.java
@@ -240,6 +240,12 @@ } @Test + @TestMetadata("RepeatableAnnotationClass") + public void testRepeatableAnnotationClass() { + runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/"); + } + + @Test @TestMetadata("Sealed") public void testSealed() { runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/Sealed/");
diff --git a/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/KotlinClsStubBuilder.kt b/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/KotlinClsStubBuilder.kt index 4fcd9fd..4ef04b1 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/KotlinClsStubBuilder.kt +++ b/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/KotlinClsStubBuilder.kt
@@ -169,13 +169,26 @@ ): KotlinJvmBinaryClass.AnnotationArgumentVisitor { return object : AnnotationMemberDefaultValueVisitor() { override fun visitEnd() { - if (!isImplicitRepeatableContainer(annotationClassId)) { - result.add(AnnotationWithArgs(annotationClassId, args)) - } else { - extractRepeatableAnnotationsFromRepeatableContainer() + when { + isRepeatableWithImplicitContainer(annotationClassId, args) -> { + // do not add `java.lang.annotation.Repeatable` to stub for a repeatable annotation class + } + !isImplicitRepeatableContainer(annotationClassId) -> { + result.add(AnnotationWithArgs(annotationClassId, args)) + } + else -> { + extractRepeatableAnnotationsFromRepeatableContainer() + } } } + private fun isRepeatableWithImplicitContainer(annotationClassId: ClassId, arguments: Map<Name, ConstantValue<*>>): Boolean { + if (annotationClassId != SpecialJvmAnnotations.JAVA_LANG_ANNOTATION_REPEATABLE) return false + + val containerKClassValue = arguments[JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME] as? KClassValue ?: return false + return isImplicitRepeatableContainer((containerKClassValue.value as KClassValue.Value.NormalClass).classId) + } + private fun extractRepeatableAnnotationsFromRepeatableContainer() { val arrayValue = args[Name.identifier("value")] as? ArrayValue ?: return for (annotationValue in arrayValue.value) {
diff --git a/analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/RepeatableAnnotationClass.kt b/analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/RepeatableAnnotationClass.kt new file mode 100644 index 0000000..e1ebe02 --- /dev/null +++ b/analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/RepeatableAnnotationClass.kt
@@ -0,0 +1,4 @@ +// FIR_IDENTICAL +@Repeatable +annotation class RepeatableAnnotationClass +
diff --git a/analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/RepeatableAnnotationClass.txt b/analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/RepeatableAnnotationClass.txt new file mode 100644 index 0000000..f4bdd85 --- /dev/null +++ b/analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/RepeatableAnnotationClass.txt
@@ -0,0 +1,25 @@ +PsiJetFileStubImpl[package=] + PACKAGE_DIRECTIVE + IMPORT_LIST + CLASS[classId=/RepeatableAnnotationClass, fqName=RepeatableAnnotationClass, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=true, name=RepeatableAnnotationClass, superNames=[Annotation]] + MODIFIER_LIST[public final annotation] + ANNOTATION_ENTRY[hasValueArguments=false, shortName=Repeatable] + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + USER_TYPE + USER_TYPE + REFERENCE_EXPRESSION[referencedName=kotlin] + REFERENCE_EXPRESSION[referencedName=annotation] + REFERENCE_EXPRESSION[referencedName=Repeatable] + PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExplicitDelegationCall=false, isExtension=false, isTopLevel=false, name=RepeatableAnnotationClass] + MODIFIER_LIST[public] + VALUE_PARAMETER_LIST + SUPER_TYPE_LIST + SUPER_TYPE_ENTRY + TYPE_REFERENCE + USER_TYPE + USER_TYPE + REFERENCE_EXPRESSION[referencedName=kotlin] + REFERENCE_EXPRESSION[referencedName=Annotation] + CLASS_BODY
diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/ClsStubBuilderK2CompilerTestGenerated.java b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/ClsStubBuilderK2CompilerTestGenerated.java index 362e0b5..58e64f7 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/ClsStubBuilderK2CompilerTestGenerated.java +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/ClsStubBuilderK2CompilerTestGenerated.java
@@ -240,6 +240,12 @@ } @Test + @TestMetadata("RepeatableAnnotationClass") + public void testRepeatableAnnotationClass() { + runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/"); + } + + @Test @TestMetadata("Sealed") public void testSealed() { runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/Sealed/");
diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/ClsStubBuilderTestGenerated.java b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/ClsStubBuilderTestGenerated.java index 878de0b..2f2126d 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/ClsStubBuilderTestGenerated.java +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/ClsStubBuilderTestGenerated.java
@@ -240,6 +240,12 @@ } @Test + @TestMetadata("RepeatableAnnotationClass") + public void testRepeatableAnnotationClass() { + runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/"); + } + + @Test @TestMetadata("Sealed") public void testSealed() { runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/Sealed/");
diff --git a/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/ByDecompiledPsiStubBuilderK2CompilerTestGenerated.java b/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/ByDecompiledPsiStubBuilderK2CompilerTestGenerated.java index 2a2bbf4..9e11a85 100644 --- a/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/ByDecompiledPsiStubBuilderK2CompilerTestGenerated.java +++ b/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/ByDecompiledPsiStubBuilderK2CompilerTestGenerated.java
@@ -240,6 +240,12 @@ } @Test + @TestMetadata("RepeatableAnnotationClass") + public void testRepeatableAnnotationClass() { + runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/"); + } + + @Test @TestMetadata("Sealed") public void testSealed() { runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/Sealed/");
diff --git a/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/ByDecompiledPsiStubBuilderTestGenerated.java b/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/ByDecompiledPsiStubBuilderTestGenerated.java index 351fa0c..4256540 100644 --- a/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/ByDecompiledPsiStubBuilderTestGenerated.java +++ b/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/ByDecompiledPsiStubBuilderTestGenerated.java
@@ -240,6 +240,12 @@ } @Test + @TestMetadata("RepeatableAnnotationClass") + public void testRepeatableAnnotationClass() { + runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/RepeatableAnnotationClass/"); + } + + @Test @TestMetadata("Sealed") public void testSealed() { runTest("analysis/decompiled/decompiler-to-file-stubs/testData/clsFileStubBuilder/Sealed/");
diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt index 6f0e86d..a18381f 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt
@@ -17,7 +17,7 @@ // Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed // or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder). // Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files). - private const val BINARY_STUB_VERSION = 104 + private const val BINARY_STUB_VERSION = 105 // Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile) // Increasing this version will lead to reindexing of all classfiles.