From a230c85fe2d751d1f0fda6566318db0c083c07c4 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 28 Dec 2015 20:01:00 +0300 Subject: [PATCH] Split JVM binary version into two: metadata and bytecode interface Currently all code only uses the first one (JvmMetadataVersion), later the bytecode interface version (JvmBytecodeBinaryVersion) will be used only in codegen and reflection to avoid compiling against or calling methods with unsupported conventions like default method naming and signature, getters/setters naming etc. Original commit: bd47e9d47b5f6aa33d5af4c1ab18996ee8572a38 --- .../jps/incremental/IncrementalCacheImpl.kt | 19 +++++++++-------- .../classFilesComparison.kt | 21 ++++++++++--------- .../AbstractProtoComparisonTest.kt | 19 +++++++++-------- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt index 21537fd9d34..afb9f5032c7 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt @@ -30,10 +30,7 @@ import org.jetbrains.kotlin.jps.build.GeneratedJvmClass import org.jetbrains.kotlin.jps.build.KotlinBuilder import org.jetbrains.kotlin.jps.incremental.storage.* import org.jetbrains.kotlin.load.kotlin.ModuleMapping -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassKind -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassPartKind +import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto import org.jetbrains.kotlin.name.FqName @@ -147,8 +144,12 @@ open class IncrementalCacheImpl( } val header = kotlinClass.classHeader - val changesInfo = when { - header.isCompatibleFileFacadeKind() -> { + if (header.isLocalClass) { + return CompilationResult.NO_CHANGES + } + + val changesInfo = when (header.kind) { + KotlinClassHeader.Kind.FILE_FACADE -> { assert(sourceFiles.size == 1) { "Package part from several source files: $sourceFiles" } packagePartMap.addPackagePart(className) @@ -156,7 +157,7 @@ open class IncrementalCacheImpl( constantsMap.process(kotlinClass) + additionalProcessChangedClass(kotlinClass, isPackage = true) } - header.isCompatibleMultifileClassKind() -> { + KotlinClassHeader.Kind.MULTIFILE_CLASS -> { val partNames = kotlinClass.classHeader.filePartClassNames?.toList() ?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}") multifileClassFacadeMap.add(className, partNames) @@ -165,7 +166,7 @@ open class IncrementalCacheImpl( constantsMap.process(kotlinClass) + additionalProcessChangedClass(kotlinClass, isPackage = true) } - header.isCompatibleMultifileClassPartKind() -> { + KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> { assert(sourceFiles.size == 1) { "Multifile class part from several source files: $sourceFiles" } packagePartMap.addPackagePart(className) multifileClassPartMap.add(className.internalName, header.multifileClassName!!) @@ -174,7 +175,7 @@ open class IncrementalCacheImpl( constantsMap.process(kotlinClass) + additionalProcessChangedClass(kotlinClass, isPackage = true) } - header.isCompatibleClassKind() && !header.isLocalClass -> { + KotlinClassHeader.Kind.CLASS -> { addToClassStorage(kotlinClass) protoMap.process(kotlinClass, isPackage = false) + diff --git a/jps/jps-plugin/test/org/jetbrains/kotlin/jps/build/classFilesComparison/classFilesComparison.kt b/jps/jps-plugin/test/org/jetbrains/kotlin/jps/build/classFilesComparison/classFilesComparison.kt index 4fa17591046..a9e51f5b98d 100644 --- a/jps/jps-plugin/test/org/jetbrains/kotlin/jps/build/classFilesComparison/classFilesComparison.kt +++ b/jps/jps-plugin/test/org/jetbrains/kotlin/jps/build/classFilesComparison/classFilesComparison.kt @@ -22,9 +22,7 @@ import com.google.common.io.Files import com.google.protobuf.ExtensionRegistry import com.intellij.openapi.util.io.FileUtil import org.jetbrains.kotlin.jps.incremental.LocalFileKotlinClass -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassPartKind +import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.serialization.DebugProtoBuf import org.jetbrains.kotlin.serialization.jvm.BitEncoding import org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf @@ -141,14 +139,17 @@ fun classFileToString(classFile: File): String { out.write("\n------ string table types proto -----\n${DebugJvmProtoBuf.StringTableTypes.parseDelimitedFrom(input)}") - when { - classHeader!!.isCompatibleFileFacadeKind() -> - out.write("\n------ file facade proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}") - classHeader.isCompatibleClassKind() -> - out.write("\n------ class proto -----\n${DebugProtoBuf.Class.parseFrom(input, getExtensionRegistry())}") - classHeader.isCompatibleMultifileClassPartKind() -> - out.write("\n------ multi-file part proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}") + if (!classHeader!!.metadataVersion.isCompatible()) { + error("Incompatible class ($classHeader): $classFile") + } + when (classHeader.kind) { + KotlinClassHeader.Kind.FILE_FACADE -> + out.write("\n------ file facade proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}") + KotlinClassHeader.Kind.CLASS -> + out.write("\n------ class proto -----\n${DebugProtoBuf.Class.parseFrom(input, getExtensionRegistry())}") + KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> + out.write("\n------ multi-file part proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}") else -> throw IllegalStateException() } } diff --git a/jps/jps-plugin/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt b/jps/jps-plugin/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt index f9ae0e18edc..77fdb5fc752 100644 --- a/jps/jps-plugin/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt +++ b/jps/jps-plugin/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt @@ -20,9 +20,7 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.testFramework.UsefulTestCase import com.intellij.util.SmartList import org.jetbrains.kotlin.jps.incremental.storage.ProtoMapValue -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassPartKind +import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.serialization.jvm.BitEncoding import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.MockLibraryUtil @@ -93,19 +91,22 @@ abstract class AbstractProtoComparisonTest : UsefulTestCase() { val oldProtoBytes = BitEncoding.decodeBytes(oldClassHeader.annotationData!!) val newProtoBytes = BitEncoding.decodeBytes(newClassHeader.annotationData!!) + assert(oldClassHeader.metadataVersion.isCompatible()) { "Incompatible class ($oldClassHeader): $oldClassFile" } + assert(newClassHeader.metadataVersion.isCompatible()) { "Incompatible class ($newClassHeader): $newClassFile" } + val oldProto = ProtoMapValue( - oldClassHeader.isCompatibleFileFacadeKind() || oldClassHeader.isCompatibleMultifileClassPartKind(), + oldClassHeader.kind == KotlinClassHeader.Kind.FILE_FACADE || + oldClassHeader.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART, oldProtoBytes, oldClassHeader.strings!! ) val newProto = ProtoMapValue( - newClassHeader.isCompatibleFileFacadeKind() || newClassHeader.isCompatibleMultifileClassPartKind(), + newClassHeader.kind == KotlinClassHeader.Kind.FILE_FACADE || + newClassHeader.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART, newProtoBytes, newClassHeader.strings!! ) - val diff = when { - newClassHeader.isCompatibleClassKind() || - newClassHeader.isCompatibleFileFacadeKind() || - newClassHeader.isCompatibleMultifileClassPartKind() -> + val diff = when (newClassHeader.kind) { + KotlinClassHeader.Kind.CLASS, KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> difference(oldProto, newProto) else -> { println("ignore ${oldLocalFileKotlinClass.classId}")