Add several subclasses of BinaryVersion
To simplify comparison of expected vs actual versions in the future
This commit is contained in:
@@ -22,8 +22,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.load.java.AbiVersionUtil;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
@@ -147,6 +147,6 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
|
||||
int[] version = (int[]) CodegenTestUtil.getAnnotationAttribute(annotation, VERSION_FIELD_NAME);
|
||||
assertNotNull(version);
|
||||
assertTrue("Annotation " + annotationFqName + " is written with an unsupported format",
|
||||
AbiVersionUtil.isAbiVersionCompatible(BinaryVersion.create(version)));
|
||||
AbiVersionUtil.isAbiVersionCompatible(JvmBytecodeBinaryVersion.create(version)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.utils
|
||||
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
|
||||
import java.io.File
|
||||
import javax.xml.bind.DatatypeConverter.parseBase64Binary
|
||||
import javax.xml.bind.DatatypeConverter.printBase64Binary
|
||||
@@ -24,6 +25,19 @@ class KotlinJavascriptMetadata(val abiVersion: Int, val moduleName: String, val
|
||||
val isAbiVersionCompatible: Boolean = KotlinJavascriptMetadataUtils.isAbiVersionCompatible(abiVersion)
|
||||
}
|
||||
|
||||
// TODO: move to JS modules
|
||||
class JsBinaryVersion protected constructor(
|
||||
major: Int, minor: Int, patch: Int, rest: List<Int>
|
||||
) : BinaryVersion(major, minor, patch, rest) {
|
||||
companion object {
|
||||
@JvmField val INVALID_VERSION = JsBinaryVersion.create(IntArray(0))
|
||||
|
||||
@JvmStatic fun create(version: IntArray) = create(version, ::JsBinaryVersion)
|
||||
|
||||
@JvmStatic fun create(major: Int, minor: Int, patch: Int) = create(major, minor, patch, ::JsBinaryVersion)
|
||||
}
|
||||
}
|
||||
|
||||
object KotlinJavascriptMetadataUtils {
|
||||
const val JS_EXT: String = ".js"
|
||||
const val META_JS_SUFFIX: String = ".meta.js"
|
||||
@@ -36,7 +50,7 @@ object KotlinJavascriptMetadataUtils {
|
||||
*/
|
||||
private val METADATA_PATTERN = "(?m)\\w+\\.$KOTLIN_JAVASCRIPT_METHOD_NAME\\((\\d+),\\s*(['\"])([^'\"]*)\\2,\\s*(['\"])([^'\"]*)\\4\\)".toPattern()
|
||||
|
||||
@JvmField val ABI_VERSION: Int = 3
|
||||
@JvmField val ABI_VERSION: Int = JsBinaryVersion.create(0, 3, 0).minor
|
||||
|
||||
fun replaceSuffix(filePath: String): String = filePath.substringBeforeLast(JS_EXT) + META_JS_SUFFIX
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion;
|
||||
|
||||
public final class AbiVersionUtil {
|
||||
public static final BinaryVersion INVALID_VERSION = BinaryVersion.create(new int[0]);
|
||||
|
||||
public static boolean isAbiVersionCompatible(@NotNull BinaryVersion actual) {
|
||||
return actual.isCompatibleTo(JvmAbi.VERSION);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion;
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.CapitalizeDecapitalizeKt;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isClassOrEnumClass;
|
||||
@@ -43,7 +42,7 @@ public final class JvmAbi {
|
||||
* - 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 BinaryVersion VERSION = BinaryVersion.create(1, 0, 2);
|
||||
public static final JvmBytecodeBinaryVersion VERSION = JvmBytecodeBinaryVersion.create(1, 0, 2);
|
||||
|
||||
public static final String DEFAULT_IMPLS_CLASS_NAME = "DefaultImpls";
|
||||
public static final String DEFAULT_IMPLS_SUFFIX = "$" + DEFAULT_IMPLS_CLASS_NAME;
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.load.java
|
||||
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
|
||||
|
||||
class JvmBytecodeBinaryVersion protected constructor(
|
||||
major: Int, minor: Int, patch: Int, rest: List<Int>
|
||||
) : BinaryVersion(major, minor, patch, rest) {
|
||||
companion object {
|
||||
@JvmField
|
||||
val INVALID_VERSION = JvmBytecodeBinaryVersion.create(IntArray(0))
|
||||
|
||||
@JvmStatic
|
||||
fun create(version: IntArray) = create(version, ::JvmBytecodeBinaryVersion)
|
||||
|
||||
@JvmStatic
|
||||
fun create(major: Int, minor: Int, patch: Int) = create(major, minor, patch, ::JvmBytecodeBinaryVersion)
|
||||
}
|
||||
}
|
||||
@@ -17,7 +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.load.java.JvmBytecodeBinaryVersion
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmPackageTable
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.DataInputStream
|
||||
@@ -41,7 +41,7 @@ class ModuleMapping private constructor(val packageFqName2Parts: Map<String, Pac
|
||||
val inputStream = DataInputStream(ByteArrayInputStream(proto))
|
||||
val size = inputStream.readInt()
|
||||
|
||||
val version = BinaryVersion.create((0..size - 1).map { inputStream.readInt() }.toIntArray())
|
||||
val version = JvmBytecodeBinaryVersion.create((0..size - 1).map { inputStream.readInt() }.toIntArray())
|
||||
|
||||
if (AbiVersionUtil.isAbiVersionCompatible(version)) {
|
||||
val parseFrom = JvmPackageTable.PackageTable.parseFrom(inputStream)
|
||||
|
||||
+3
-2
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement;
|
||||
import org.jetbrains.kotlin.load.java.AbiVersionUtil;
|
||||
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -45,7 +46,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
HEADER_KINDS.put(ClassId.topLevel(KOTLIN_SYNTHETIC_CLASS), SYNTHETIC_CLASS);
|
||||
}
|
||||
|
||||
private BinaryVersion version = AbiVersionUtil.INVALID_VERSION;
|
||||
private BinaryVersion version = JvmBytecodeBinaryVersion.INVALID_VERSION;
|
||||
private String multifileClassName = null;
|
||||
private String[] filePartClassNames = null;
|
||||
private String[] annotationData = null;
|
||||
@@ -131,7 +132,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
|
||||
String string = name.asString();
|
||||
if (VERSION_FIELD_NAME.equals(string)) {
|
||||
version = value instanceof int[] ? BinaryVersion.create((int[]) value) : AbiVersionUtil.INVALID_VERSION;
|
||||
version = value instanceof int[] ? JvmBytecodeBinaryVersion.create((int[]) value) : JvmBytecodeBinaryVersion.INVALID_VERSION;
|
||||
}
|
||||
else if (MULTIFILE_CLASS_NAME_FIELD_NAME.equals(string)) {
|
||||
multifileClassName = value instanceof String ? (String) value : null;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.builtins
|
||||
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
|
||||
|
||||
class BuiltInsBinaryVersion protected constructor(
|
||||
major: Int, minor: Int, patch: Int, rest: List<Int>
|
||||
) : BinaryVersion(major, minor, patch, rest) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun create(version: IntArray) = create(version, ::BuiltInsBinaryVersion)
|
||||
|
||||
@JvmStatic
|
||||
fun create(major: Int, minor: Int, patch: Int) = create(major, minor, patch, ::BuiltInsBinaryVersion)
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ class BuiltinsPackageFragment(
|
||||
) : DeserializedPackageFragment(fqName, storageManager, module, BuiltInsSerializedResourcePaths, loadResource) {
|
||||
val builtinsMessage = loadResource(BuiltInsSerializedResourcePaths.getBuiltInsFilePath(fqName))?.let { stream ->
|
||||
val dataInput = DataInputStream(stream)
|
||||
val version = BinaryVersion.create((1..dataInput.readInt()).map { dataInput.readInt() }.toIntArray())
|
||||
val version = BuiltInsBinaryVersion.create((1..dataInput.readInt()).map { dataInput.readInt() }.toIntArray())
|
||||
|
||||
if (!version.isCompatibleTo(BuiltinsPackageFragment.VERSION)) {
|
||||
// TODO: report a proper diagnostic
|
||||
@@ -74,6 +74,6 @@ class BuiltinsPackageFragment(
|
||||
|
||||
companion object {
|
||||
// Advance this version when the common or builtins-specific binary metadata format is changed
|
||||
val VERSION = BinaryVersion.create(1, 0, 0)
|
||||
val VERSION = BuiltInsBinaryVersion.create(1, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
+26
-9
@@ -16,11 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.serialization.deserialization
|
||||
|
||||
data class BinaryVersion private constructor(
|
||||
abstract class BinaryVersion protected constructor(
|
||||
val major: Int,
|
||||
val minor: Int,
|
||||
val patch: Int,
|
||||
val rest: List<Int> = listOf()
|
||||
val rest: List<Int>
|
||||
) {
|
||||
fun toArray(): IntArray =
|
||||
intArrayOf(major, minor, patch, *rest.toIntArray())
|
||||
@@ -41,20 +41,37 @@ data class BinaryVersion private constructor(
|
||||
return if (versions.isEmpty()) "unknown" else versions.joinToString(".")
|
||||
}
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
this.javaClass == other?.javaClass &&
|
||||
major == (other as BinaryVersion).major && minor == other.minor && patch == other.patch && rest == other.rest
|
||||
|
||||
override fun hashCode(): Int{
|
||||
var result = major
|
||||
result += 31 * result + minor
|
||||
result += 31 * result + patch
|
||||
result += 31 * result + rest.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
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()
|
||||
fun <T : BinaryVersion> create(
|
||||
version: IntArray,
|
||||
factory: (major: Int, minor: Int, patch: Int, rest: List<Int>) -> T
|
||||
): T {
|
||||
return factory(
|
||||
version.getOrNull(0) ?: UNKNOWN,
|
||||
version.getOrNull(1) ?: UNKNOWN,
|
||||
version.getOrNull(2) ?: UNKNOWN,
|
||||
if (version.size > 3) version.asList().subList(3, version.size).toList() else emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun create(major: Int, minor: Int, patch: Int) = BinaryVersion(major, minor, patch)
|
||||
fun <T : BinaryVersion> create(
|
||||
major: Int, minor: Int, patch: Int, factory: (major: Int, minor: Int, patch: Int, rest: List<Int>) -> T
|
||||
): T = factory(major, minor, patch, emptyList())
|
||||
}
|
||||
}
|
||||
@@ -21,16 +21,17 @@ import com.intellij.util.indexing.DataIndexer
|
||||
import com.intellij.util.indexing.FileBasedIndex
|
||||
import com.intellij.util.indexing.FileContent
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses
|
||||
import org.jetbrains.kotlin.load.java.AbiVersionUtil
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.*
|
||||
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
|
||||
object KotlinAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinAbiVersionIndex>(KotlinAbiVersionIndex::class.java) {
|
||||
|
||||
object KotlinAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinAbiVersionIndex>(
|
||||
KotlinAbiVersionIndex::class.java, { JvmBytecodeBinaryVersion.create(it) }
|
||||
) {
|
||||
override fun getIndexer() = INDEXER
|
||||
|
||||
override fun getInputFilter() = FileBasedIndex.InputFilter() { file -> file.fileType == StdFileTypes.CLASS }
|
||||
@@ -60,7 +61,7 @@ object KotlinAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinAbiVersionIndex>(
|
||||
return object : AnnotationVisitor(Opcodes.ASM5) {
|
||||
override fun visit(name: String, value: Any) {
|
||||
if (name == VERSION_FIELD_NAME && value is IntArray) {
|
||||
version = BinaryVersion.create(value)
|
||||
version = JvmBytecodeBinaryVersion.create(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,7 +71,7 @@ object KotlinAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinAbiVersionIndex>(
|
||||
|
||||
if (annotationPresent && version == null) {
|
||||
// No version at all because the class is too old, or version is set to something weird
|
||||
version = AbiVersionUtil.INVALID_VERSION
|
||||
version = JvmBytecodeBinaryVersion.INVALID_VERSION
|
||||
}
|
||||
|
||||
if (version != null) mapOf(version!! to null) else mapOf()
|
||||
|
||||
@@ -29,7 +29,10 @@ import java.io.DataOutput
|
||||
/**
|
||||
* Important! This is not a stub-based index. And it has its own version
|
||||
*/
|
||||
abstract class KotlinAbiVersionIndexBase<T>(private val classOfIndex: Class<T>) : ScalarIndexExtension<BinaryVersion>() {
|
||||
abstract class KotlinAbiVersionIndexBase<T>(
|
||||
private val classOfIndex: Class<T>,
|
||||
private val createBinaryVersion: (IntArray) -> BinaryVersion
|
||||
) : ScalarIndexExtension<BinaryVersion>() {
|
||||
|
||||
override fun getName() = ID.create<BinaryVersion, Void>(classOfIndex.canonicalName)
|
||||
|
||||
@@ -40,7 +43,7 @@ abstract class KotlinAbiVersionIndexBase<T>(private val classOfIndex: Class<T>)
|
||||
|
||||
override fun read(input: DataInput): BinaryVersion {
|
||||
val size = DataInputOutputUtil.readINT(input)
|
||||
return BinaryVersion.create((0..size - 1).map { DataInputOutputUtil.readINT(input) }.toIntArray())
|
||||
return createBinaryVersion((0..size - 1).map { DataInputOutputUtil.readINT(input) }.toIntArray())
|
||||
}
|
||||
|
||||
override fun save(output: DataOutput, value: BinaryVersion) {
|
||||
|
||||
@@ -21,14 +21,15 @@ import com.intellij.util.indexing.DataIndexer
|
||||
import com.intellij.util.indexing.FileBasedIndex
|
||||
import com.intellij.util.indexing.FileContent
|
||||
import org.jetbrains.kotlin.js.JavaScript
|
||||
import org.jetbrains.kotlin.load.java.AbiVersionUtil
|
||||
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
|
||||
import org.jetbrains.kotlin.utils.JsBinaryVersion
|
||||
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata
|
||||
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
|
||||
import java.util.*
|
||||
|
||||
object KotlinJavaScriptAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinJavaScriptAbiVersionIndex>(KotlinJavaScriptAbiVersionIndex::class.java) {
|
||||
|
||||
object KotlinJavaScriptAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinJavaScriptAbiVersionIndex>(
|
||||
KotlinJavaScriptAbiVersionIndex::class.java, { JsBinaryVersion.create(it) }
|
||||
) {
|
||||
override fun getIndexer() = INDEXER
|
||||
|
||||
override fun getInputFilter() = FileBasedIndex.InputFilter() { file -> JavaScript.EXTENSION == file.extension }
|
||||
@@ -46,11 +47,11 @@ object KotlinJavaScriptAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinJavaScr
|
||||
KotlinJavascriptMetadataUtils.parseMetadata(text, metadataList)
|
||||
for (metadata in metadataList) {
|
||||
val version = if (KotlinJavascriptMetadataUtils.isAbiVersionCompatible(metadata.abiVersion)) {
|
||||
BinaryVersion.create(0, metadata.abiVersion, 0)
|
||||
JsBinaryVersion.create(0, metadata.abiVersion, 0)
|
||||
}
|
||||
else {
|
||||
// Version is set to something weird
|
||||
AbiVersionUtil.INVALID_VERSION
|
||||
JsBinaryVersion.INVALID_VERSION
|
||||
}
|
||||
result[version] = null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user