diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt b/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt index 87c7b8242b9..9aacb7dec04 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt +++ b/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt @@ -30,8 +30,7 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode import java.util.* object InlineTestUtil { - private val KOTLIN_MULTIFILE_CLASS_DESC = - AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS) + private val KOTLIN_METADATA_DESC = AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.METADATA) fun checkNoCallsToInline(files: Iterable, sourceFiles: List) { val inlineInfo = obtainInlineInfo(files) @@ -87,14 +86,20 @@ object InlineTestUtil { val notInlined = ArrayList() files.forEach { file -> - val cr = ClassReader(file.asByteArray()) - cr.accept(object : ClassVisitorWithName() { + ClassReader(file.asByteArray()).accept(object : ClassVisitorWithName() { private var skipMethodsOfThisClass = false override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? { - if (desc == KOTLIN_MULTIFILE_CLASS_DESC) { - skipMethodsOfThisClass = true + if (desc == KOTLIN_METADATA_DESC) { + return object : AnnotationVisitor(Opcodes.ASM5) { + override fun visit(name: String?, value: Any) { + if (name == JvmAnnotationNames.KIND_FIELD_NAME && value == KotlinClassHeader.Kind.MULTIFILE_CLASS.id) { + skipMethodsOfThisClass = true + } + } + } } + return null } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/KotlinSyntheticClassAnnotationTest.java b/compiler/tests/org/jetbrains/kotlin/codegen/KotlinSyntheticClassAnnotationTest.java index 9d6e8c9a514..cfc9a3cef5c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/KotlinSyntheticClassAnnotationTest.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/KotlinSyntheticClassAnnotationTest.java @@ -29,7 +29,8 @@ import java.lang.annotation.Annotation; import java.util.Collection; import java.util.List; -import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.*; +import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.METADATA; +import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.METADATA_VERSION_FIELD_NAME; public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase { public static final FqName PACKAGE_NAME = new FqName("test"); @@ -112,14 +113,14 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase { } private void doTestKotlinSyntheticClass(@NotNull String code, @NotNull String classFilePart) { - doTest(code, classFilePart, KOTLIN_SYNTHETIC_CLASS); + doTest(code, classFilePart); } private void doTestKotlinClass(@NotNull String code, @NotNull String classFilePart) { - doTest(code, classFilePart, KOTLIN_CLASS); + doTest(code, classFilePart); } - private void doTest(@NotNull String code, @NotNull final String classFilePart, @NotNull FqName annotationFqName) { + private void doTest(@NotNull String code, @NotNull final String classFilePart) { loadText("package " + PACKAGE_NAME + "\n\n" + code); List output = generateClassesInFile().asList(); Collection files = Collections2.filter(output, new Predicate() { @@ -134,16 +135,17 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase { String path = files.iterator().next().getRelativePath(); String fqName = path.substring(0, path.length() - ".class".length()).replace('/', '.'); Class aClass = generateClass(fqName); - assertAnnotatedWith(aClass, annotationFqName.asString()); + assertAnnotatedWithMetadata(aClass); } - private void assertAnnotatedWith(@NotNull Class aClass, @NotNull String annotationFqName) { + private void assertAnnotatedWithMetadata(@NotNull Class aClass) { + String annotationFqName = METADATA.asString(); Class annotationClass = loadAnnotationClassQuietly(annotationFqName); assertTrue("No annotation " + annotationFqName + " found in " + aClass, aClass.isAnnotationPresent(annotationClass)); Annotation annotation = aClass.getAnnotation(annotationClass); - int[] version = (int[]) CodegenTestUtil.getAnnotationAttribute(annotation, VERSION_FIELD_NAME); + int[] version = (int[]) CodegenTestUtil.getAnnotationAttribute(annotation, METADATA_VERSION_FIELD_NAME); assertNotNull(version); assertTrue("Annotation " + annotationFqName + " is written with an unsupported format", new JvmMetadataVersion(version).isCompatible()); diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/AbstractLocalClassProtoTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/AbstractLocalClassProtoTest.kt index 5aadb77303c..3d924e25cfb 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/AbstractLocalClassProtoTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/AbstractLocalClassProtoTest.kt @@ -79,7 +79,7 @@ abstract class AbstractLocalClassProtoTest : TestCaseWithTmpdir() { @Suppress("UNCHECKED_CAST") private fun assertHasAnnotationData(clazz: Class<*>) { checkNotNull(clazz.getAnnotation( - clazz.classLoader.loadClass(JvmAnnotationNames.KOTLIN_CLASS.asString()) as Class - )) { "KotlinClass annotation is not found for class $clazz" } + clazz.classLoader.loadClass(JvmAnnotationNames.METADATA.asString()) as Class + )) { "Metadata annotation is not found for class $clazz" } } } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/ReflectJvmMapping.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/ReflectJvmMapping.kt index fb55786ab16..57053636e72 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/ReflectJvmMapping.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/ReflectJvmMapping.kt @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil import java.lang.reflect.* import java.util.* -import kotlin.jvm.internal.KotlinFileFacade import kotlin.jvm.internal.Reflection import kotlin.reflect.* import kotlin.reflect.jvm.internal.KTypeImpl @@ -104,20 +103,18 @@ val Field.kotlinProperty: KProperty<*>? private fun Member.getKPackage(): KDeclarationContainer? { // TODO: support multifile classes - return if (declaringClass.getAnnotation(KotlinFileFacade::class.java) != null) { - val header = ReflectKotlinClass.create(declaringClass)?.classHeader - if (header != null && header.kind == KotlinClassHeader.Kind.FILE_FACADE && header.metadataVersion.isCompatible()) { - // TODO: avoid reading and parsing metadata twice (here and later in KPackageImpl#descriptor) - val (nameResolver, proto) = JvmProtoBufUtil.readPackageDataFrom(header.data!!, header.strings!!) - val moduleName = - if (proto.hasExtension(JvmProtoBuf.packageModuleName)) - nameResolver.getString(proto.getExtension(JvmProtoBuf.packageModuleName)) - else JvmAbi.DEFAULT_MODULE_NAME - Reflection.getOrCreateKotlinPackage(declaringClass, moduleName) - } - else null + val header = ReflectKotlinClass.create(declaringClass)?.classHeader + if (header != null && header.kind == KotlinClassHeader.Kind.FILE_FACADE && header.metadataVersion.isCompatible()) { + // TODO: avoid reading and parsing metadata twice (here and later in KPackageImpl#descriptor) + val (nameResolver, proto) = JvmProtoBufUtil.readPackageDataFrom(header.data!!, header.strings!!) + val moduleName = + if (proto.hasExtension(JvmProtoBuf.packageModuleName)) + nameResolver.getString(proto.getExtension(JvmProtoBuf.packageModuleName)) + else JvmAbi.DEFAULT_MODULE_NAME + return Reflection.getOrCreateKotlinPackage(declaringClass, moduleName) } - else null + + return null } /** diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/AllClassesCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/AllClassesCompletion.kt index e83f58ed20a..758f6c22d29 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/AllClassesCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/AllClassesCompletion.kt @@ -94,12 +94,7 @@ class AllClassesCompletion(private val parameters: CompletionParameters, private fun PsiClass.isSyntheticKotlinClass(): Boolean { if ('$' !in name!!) return false // optimization to not analyze annotations of all classes val metadata = modifierList?.findAnnotation(JvmAnnotationNames.METADATA.asString()) - if (metadata != null && - (metadata.findAttributeValue(JvmAnnotationNames.KIND_FIELD_NAME) as? PsiLiteral)?.value == - KotlinClassHeader.Kind.SYNTHETIC_CLASS.id) { - return true - } - - return modifierList?.findAnnotation(JvmAnnotationNames.KOTLIN_SYNTHETIC_CLASS.asString()) != null + return (metadata?.findAttributeValue(JvmAnnotationNames.KIND_FIELD_NAME) as? PsiLiteral)?.value == + KotlinClassHeader.Kind.SYNTHETIC_CLASS.id } } diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinMetadataVersionIndex.kt b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinMetadataVersionIndex.kt index 891f63a54fa..f8bd4bdb236 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinMetadataVersionIndex.kt +++ b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinMetadataVersionIndex.kt @@ -23,6 +23,7 @@ import com.intellij.util.indexing.FileContent import org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses import org.jetbrains.kotlin.load.java.JvmAnnotationNames.* import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion +import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion import org.jetbrains.org.objectweb.asm.AnnotationVisitor import org.jetbrains.org.objectweb.asm.ClassReader @@ -38,30 +39,37 @@ object KotlinMetadataVersionIndex : KotlinAbiVersionIndexBase() { inputData: FileContent -> var version: BinaryVersion? = null var annotationPresent = false + var kind: KotlinClassHeader.Kind? = null tryBlock(inputData) { val classReader = ClassReader(inputData.content) classReader.accept(object : ClassVisitor(Opcodes.ASM5) { override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? { - if (!kotlinAnnotationsDesc.contains(desc)) { - return null - } + if (desc != METADATA_DESC) return null + annotationPresent = true return object : AnnotationVisitor(Opcodes.ASM5) { override fun visit(name: String, value: Any) { - if (name == VERSION_FIELD_NAME && value is IntArray) { - version = JvmMetadataVersion(*value) + when (name) { + METADATA_VERSION_FIELD_NAME -> if (value is IntArray) { + version = JvmMetadataVersion(*value) + } + KIND_FIELD_NAME -> if (value is Int) { + kind = KotlinClassHeader.Kind.getById(value) + } } } } @@ -69,7 +77,11 @@ object KotlinMetadataVersionIndex : KotlinAbiVersionIndexBase