Improve ABI version from one number to "major.minor.patch"
This commit is contained in:
@@ -16,11 +16,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.java;
|
||||
|
||||
public final class AbiVersionUtil {
|
||||
public static final int INVALID_VERSION = -1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion;
|
||||
|
||||
public static boolean isAbiVersionCompatible(int abiVersion) {
|
||||
return abiVersion == JvmAbi.VERSION;
|
||||
public final class AbiVersionUtil {
|
||||
public static final BinaryVersion INVALID_VERSION = BinaryVersion.create(new int[0]);
|
||||
|
||||
public static boolean isAbiVersionCompatible(@NotNull BinaryVersion actual) {
|
||||
// TODO: compare versions according to Semantic Versioning
|
||||
return actual.getMajor() == JvmAbi.VERSION.getMajor() &&
|
||||
actual.getMinor() == JvmAbi.VERSION.getMinor();
|
||||
}
|
||||
|
||||
private AbiVersionUtil() {
|
||||
|
||||
@@ -21,13 +21,20 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion;
|
||||
|
||||
public final class JvmAbi {
|
||||
/**
|
||||
* This constant is used to identify binary format (class file) versions
|
||||
* If you change class file metadata format and/or naming conventions, please increase this number
|
||||
* If you change class file metadata format and/or naming conventions, please change this version.
|
||||
* - Major version should be increased only when the new binary format is neither forward- nor backward compatible.
|
||||
* This shouldn't really ever happen at all.
|
||||
* - Minor version should be increased when the new format is backward compatible,
|
||||
* i.e. the new compiler can process old class files, but the old compiler will not be able to process new class files.
|
||||
* - Patch version can be increased freely and is only supposed to be used for debugging. Increase the patch version when you
|
||||
* make a change to the metadata format or the bytecode which is both forward- and backward compatible.
|
||||
*/
|
||||
public static final int VERSION = 24;
|
||||
public static final BinaryVersion VERSION = BinaryVersion.create(0, 24, 0);
|
||||
|
||||
public static final String TRAIT_IMPL_CLASS_NAME = "$TImpl";
|
||||
public static final String TRAIT_IMPL_SUFFIX = "$" + TRAIT_IMPL_CLASS_NAME;
|
||||
|
||||
+3
-1
@@ -38,7 +38,7 @@ public final class JvmAnnotationNames {
|
||||
public static final FqName KOTLIN_SIGNATURE = new FqName("kotlin.jvm.KotlinSignature");
|
||||
public static final FqName OLD_KOTLIN_SIGNATURE = new FqName("jet.runtime.typeinfo.KotlinSignature");
|
||||
|
||||
public static final String ABI_VERSION_FIELD_NAME = "abiVersion";
|
||||
public static final String VERSION_FIELD_NAME = "version";
|
||||
public static final String KIND_FIELD_NAME = "kind";
|
||||
public static final String FILE_PART_CLASS_NAMES_FIELD_NAME = "filePartClassNames";
|
||||
public static final String MULTIFILE_CLASS_NAME_FIELD_NAME = "multifileClassName";
|
||||
@@ -114,6 +114,8 @@ public final class JvmAnnotationNames {
|
||||
@Deprecated
|
||||
public static final FqName OLD_KOTLIN_TRAIT_IMPL = new FqName("jet.KotlinTraitImpl");
|
||||
|
||||
public static final String OLD_ABI_VERSION_FIELD_NAME = "abiVersion";
|
||||
|
||||
// When these annotations appear on a declaration, they are copied to the _type_ of the declaration, becoming type annotations
|
||||
// See also DescriptorRendererOptions#excludedTypeAnnotationClasses
|
||||
public static final Set<FqName> ANNOTATIONS_COPIED_TO_TYPES = KotlinPackage.setOf(
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.load.java.AbiVersionUtil
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmPackageTable
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.DataInputStream
|
||||
@@ -28,19 +29,27 @@ public class ModuleMapping private constructor(val packageFqName2Parts: Map<Stri
|
||||
}
|
||||
|
||||
companion object {
|
||||
public val MAPPING_FILE_EXT: String = "kotlin_module";
|
||||
public val MAPPING_FILE_EXT: String = "kotlin_module"
|
||||
|
||||
public val EMPTY: ModuleMapping = ModuleMapping(emptyMap())
|
||||
|
||||
fun create(protoWithAbi: ByteArray? = null): ModuleMapping {
|
||||
if (protoWithAbi == null) {
|
||||
fun create(proto: ByteArray? = null): ModuleMapping {
|
||||
if (proto == null) {
|
||||
return EMPTY
|
||||
}
|
||||
|
||||
val inputStream = DataInputStream(ByteArrayInputStream(protoWithAbi))
|
||||
val intCount = inputStream.readInt()
|
||||
assert(intCount == 1, {"Expected one int value for abi version, but: $intCount"})
|
||||
val abiVersion = Integer.valueOf(inputStream.readInt());
|
||||
val inputStream = DataInputStream(ByteArrayInputStream(proto))
|
||||
val size = inputStream.readInt()
|
||||
|
||||
val abiVersion =
|
||||
if (size == 1) {
|
||||
// TODO: this is a temporary workaround, drop after M13
|
||||
BinaryVersion.create(0, inputStream.readInt(), 0)
|
||||
}
|
||||
else {
|
||||
BinaryVersion.create((0..size - 1).map { inputStream.readInt() }.toIntArray())
|
||||
}
|
||||
|
||||
if (AbiVersionUtil.isAbiVersionCompatible(abiVersion)) {
|
||||
val parseFrom = JvmPackageTable.PackageTable.parseFrom(inputStream)
|
||||
if (parseFrom != null) {
|
||||
@@ -55,6 +64,7 @@ public class ModuleMapping private constructor(val packageFqName2Parts: Map<Stri
|
||||
return ModuleMapping(packageFqNameParts)
|
||||
}
|
||||
}
|
||||
|
||||
return EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -16,13 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin.header
|
||||
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
|
||||
import org.jetbrains.kotlin.load.java.AbiVersionUtil
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass
|
||||
|
||||
public class KotlinClassHeader(
|
||||
public val kind: KotlinClassHeader.Kind,
|
||||
public val version: Int,
|
||||
public val version: BinaryVersion,
|
||||
public val annotationData: Array<String>?,
|
||||
public val classKind: KotlinClass.Kind?,
|
||||
public val syntheticClassKind: KotlinSyntheticClass.Kind?,
|
||||
|
||||
+14
-7
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.load.java.AbiVersionUtil;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -59,7 +60,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
OLD_DEPRECATED_ANNOTATIONS_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(OLD_KOTLIN_TRAIT_IMPL), SYNTHETIC_CLASS);
|
||||
}
|
||||
|
||||
private int version = AbiVersionUtil.INVALID_VERSION;
|
||||
private BinaryVersion version = AbiVersionUtil.INVALID_VERSION;
|
||||
private String multifileClassName = null;
|
||||
private String[] filePartClassNames = null;
|
||||
private String[] annotationData = null;
|
||||
@@ -151,12 +152,18 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
|
||||
@Override
|
||||
public void visit(@Nullable Name name, @Nullable Object value) {
|
||||
if (name != null) {
|
||||
if (name.asString().equals(ABI_VERSION_FIELD_NAME)) {
|
||||
version = value instanceof Integer ? (Integer) value : AbiVersionUtil.INVALID_VERSION;
|
||||
}
|
||||
else if (name.asString().equals(MULTIFILE_CLASS_NAME_FIELD_NAME)) {
|
||||
multifileClassName = value instanceof String ? (String) value : null;
|
||||
if (name == null) return;
|
||||
|
||||
String string = name.asString();
|
||||
if (VERSION_FIELD_NAME.equals(string)) {
|
||||
version = value instanceof int[] ? BinaryVersion.create((int[]) value) : AbiVersionUtil.INVALID_VERSION;
|
||||
}
|
||||
else if (MULTIFILE_CLASS_NAME_FIELD_NAME.equals(string)) {
|
||||
multifileClassName = value instanceof String ? (String) value : null;
|
||||
}
|
||||
else if (OLD_ABI_VERSION_FIELD_NAME.equals(string)) {
|
||||
if (version == AbiVersionUtil.INVALID_VERSION && value instanceof Integer && (Integer) value > 0) {
|
||||
version = BinaryVersion.create(0, (Integer) value, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.load.java.components
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
|
||||
public object RuntimeErrorReporter : ErrorReporter {
|
||||
@@ -29,8 +29,8 @@ public object RuntimeErrorReporter : ErrorReporter {
|
||||
throw IllegalStateException("Incomplete hierarchy for class ${descriptor.getName()}, unresolved classes $unresolvedSuperClasses")
|
||||
}
|
||||
|
||||
override fun reportIncompatibleAbiVersion(classId: ClassId, filePath: String, actualVersion: Int) {
|
||||
throw IllegalStateException("Incompatible ABI version of ${classId}: $actualVersion " +
|
||||
override fun reportIncompatibleAbiVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
|
||||
throw IllegalStateException("Incompatible ABI version of $classId: $actualVersion " +
|
||||
"(expected version is ${JvmAbi.VERSION})")
|
||||
}
|
||||
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.kotlin.serialization.deserialization
|
||||
|
||||
data class BinaryVersion private constructor(
|
||||
val major: Int,
|
||||
val minor: Int,
|
||||
val patch: Int,
|
||||
val rest: List<Int> = listOf()
|
||||
) {
|
||||
fun toArray(): IntArray =
|
||||
intArrayOf(major, minor, patch, *rest.toIntArray())
|
||||
|
||||
override fun toString(): String {
|
||||
val versions = toArray().takeWhile { it != UNKNOWN }
|
||||
return if (versions.isEmpty()) "unknown" else versions.joinToString(".")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val UNKNOWN = -1
|
||||
|
||||
@JvmStatic
|
||||
fun create(version: IntArray): BinaryVersion {
|
||||
return BinaryVersion(
|
||||
major = version.getOrNull(0) ?: UNKNOWN,
|
||||
minor = version.getOrNull(1) ?: UNKNOWN,
|
||||
patch = version.getOrNull(2) ?: UNKNOWN,
|
||||
rest = if (version.size() > 3) version.asList().subList(3, version.size()).toList() else listOf()
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun create(major: Int, minor: Int, patch: Int) = BinaryVersion(major, minor, patch)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.name.ClassId;
|
||||
import java.util.List;
|
||||
|
||||
public interface ErrorReporter {
|
||||
void reportIncompatibleAbiVersion(@NotNull ClassId classId, @NotNull String filePath, int actualVersion);
|
||||
void reportIncompatibleAbiVersion(@NotNull ClassId classId, @NotNull String filePath, @NotNull BinaryVersion actualVersion);
|
||||
|
||||
void reportIncompleteHierarchy(@NotNull ClassDescriptor descriptor, @NotNull List<String> unresolvedSuperClasses);
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface KotlinCallable {
|
||||
@Deprecated
|
||||
int abiVersion();
|
||||
|
||||
int[] version() default {};
|
||||
|
||||
String[] data();
|
||||
}
|
||||
|
||||
@@ -21,8 +21,11 @@ import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface KotlinClass {
|
||||
@Deprecated
|
||||
int abiVersion();
|
||||
|
||||
int[] version() default {};
|
||||
|
||||
Kind kind() default Kind.CLASS;
|
||||
|
||||
String[] data();
|
||||
|
||||
@@ -21,7 +21,10 @@ import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface KotlinFileFacade {
|
||||
@Deprecated
|
||||
int abiVersion();
|
||||
|
||||
int[] version() default {};
|
||||
|
||||
String[] data();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface KotlinMultifileClass {
|
||||
@Deprecated
|
||||
int abiVersion();
|
||||
|
||||
int[] version() default {};
|
||||
|
||||
String[] filePartClassNames();
|
||||
}
|
||||
|
||||
@@ -21,8 +21,12 @@ import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface KotlinMultifileClassPart {
|
||||
@Deprecated
|
||||
int abiVersion();
|
||||
|
||||
int[] version() default {};
|
||||
|
||||
String multifileClassName();
|
||||
|
||||
String[] data();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface KotlinPackage {
|
||||
@Deprecated
|
||||
int abiVersion();
|
||||
|
||||
int[] version() default {};
|
||||
|
||||
String[] data();
|
||||
}
|
||||
|
||||
@@ -21,8 +21,11 @@ import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface KotlinSyntheticClass {
|
||||
@Deprecated
|
||||
int abiVersion();
|
||||
|
||||
int[] version() default {};
|
||||
|
||||
Kind kind();
|
||||
|
||||
enum Kind {
|
||||
|
||||
Reference in New Issue
Block a user