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: bd47e9d47b
This commit is contained in:
@@ -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) +
|
||||
|
||||
+11
-10
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
+10
-9
@@ -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}")
|
||||
|
||||
Reference in New Issue
Block a user