diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index f24b29deb7a..baf2c282898 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -245,7 +245,6 @@ class GenerationState private constructor( this.moduleName, languageVersionSettings, useOldManglingSchemeForFunctionsWithInlineClassesInSignatures, - IncompatibleClassTrackerImpl(extraJvmDiagnosticsTrace), target, isIrBackend ) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/IncompatibleClassTracker.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/IncompatibleClassTracker.kt deleted file mode 100644 index 14ff439d1ef..00000000000 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/IncompatibleClassTracker.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2010-2016 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.codegen.state - -import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmBytecodeBinaryVersion -import org.jetbrains.kotlin.resolve.BindingTrace -import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData -import org.jetbrains.kotlin.util.slicedMap.Slices -import org.jetbrains.kotlin.util.slicedMap.WritableSlice - -interface IncompatibleClassTracker { - fun record(binaryClass: KotlinJvmBinaryClass) - - object DoNothing : IncompatibleClassTracker { - override fun record(binaryClass: KotlinJvmBinaryClass) { - } - } -} - -class IncompatibleClassTrackerImpl(val trace: BindingTrace) : IncompatibleClassTracker { - private val classes = linkedSetOf() - - override fun record(binaryClass: KotlinJvmBinaryClass) { - if (classes.add(binaryClass.location)) { - val errorData = IncompatibleVersionErrorData( - binaryClass.classHeader.bytecodeVersion, - JvmBytecodeBinaryVersion.INSTANCE, - binaryClass.location, - binaryClass.classId - ) - trace.record(BYTECODE_VERSION_ERRORS, binaryClass.location, errorData) - } - } - - companion object { - @JvmField - val BYTECODE_VERSION_ERRORS: WritableSlice> = Slices.createCollectiveSlice() - } -} diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt index 7c2ab8f0614..5a55189613e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt @@ -87,7 +87,6 @@ class KotlinTypeMapper @JvmOverloads constructor( private val moduleName: String, val languageVersionSettings: LanguageVersionSettings, private val useOldInlineClassesManglingScheme: Boolean, - private val incompatibleClassTracker: IncompatibleClassTracker = IncompatibleClassTracker.DoNothing, val jvmTarget: JvmTarget = JvmTarget.DEFAULT, private val isIrBackend: Boolean = false, private val typePreprocessor: ((KotlinType) -> KotlinType?)? = null, @@ -845,8 +844,6 @@ class KotlinTypeMapper @JvmOverloads constructor( skipGenericSignature: Boolean, hasSpecialBridge: Boolean ): JvmMethodGenericSignature { - checkOwnerCompatibility(f) - val sw = if (skipGenericSignature || f is AccessorForCallableDescriptor<*>) JvmSignatureWriter() else @@ -969,15 +966,6 @@ class KotlinTypeMapper @JvmOverloads constructor( } } - private fun checkOwnerCompatibility(descriptor: FunctionDescriptor) { - val ownerClass = descriptor.getContainingKotlinJvmBinaryClass() ?: return - - val version = ownerClass.classHeader.bytecodeVersion - if (!version.isCompatible()) { - incompatibleClassTracker.record(ownerClass) - } - } - fun mapDefaultMethod(functionDescriptor: FunctionDescriptor, kind: OwnerKind): Method { val jvmSignature = mapAsmMethod(functionDescriptor, kind) val ownerType = mapOwner(functionDescriptor) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt index 74a026062a7..e0658ca56ec 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.cli.common.messages -import com.intellij.openapi.util.io.FileUtil.toSystemDependentName import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.* import com.intellij.psi.util.PsiFormatUtil @@ -24,7 +23,6 @@ import org.jetbrains.kotlin.analyzer.AbstractAnalyzerWithCompilerReport import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.* -import org.jetbrains.kotlin.codegen.state.IncompatibleClassTrackerImpl import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.LanguageVersionSettings @@ -33,16 +31,12 @@ import org.jetbrains.kotlin.diagnostics.* import org.jetbrains.kotlin.diagnostics.DiagnosticUtils.sortedDiagnostics import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.load.java.components.TraceBasedErrorReporter -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmBytecodeBinaryVersion import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.AnalyzingUtils -import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker import org.jetbrains.kotlin.resolve.jvm.JvmBindingContextSlices -import org.jetbrains.kotlin.resolve.jvm.JvmClassName -import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData class AnalyzerWithCompilerReport( private val messageCollector: MessageCollector, @@ -246,33 +240,5 @@ class AnalyzerWithCompilerReport( fun reportSyntaxErrors(file: PsiElement, messageCollector: MessageCollector): SyntaxErrorReport { return reportSyntaxErrors(file, DefaultDiagnosticReporter(messageCollector)) } - - fun reportBytecodeVersionErrors(bindingContext: BindingContext, messageCollector: MessageCollector) { - val severity = - if (System.getProperty("kotlin.jvm.disable.bytecode.version.error") == "true") STRONG_WARNING - else ERROR - - val locations = bindingContext.getKeys(IncompatibleClassTrackerImpl.BYTECODE_VERSION_ERRORS) - if (locations.isEmpty()) return - - for (location in locations) { - val data = bindingContext.get(IncompatibleClassTrackerImpl.BYTECODE_VERSION_ERRORS, location) - ?: error("Value is missing for key in binding context: $location") - reportIncompatibleBinaryVersion(messageCollector, data, severity) - } - } - - private fun reportIncompatibleBinaryVersion( - messageCollector: MessageCollector, - data: IncompatibleVersionErrorData, - severity: CompilerMessageSeverity - ) { - messageCollector.report( - severity, - "Class '" + JvmClassName.byClassId(data.classId) + "' was compiled with an incompatible version of Kotlin. " + - "The binary version of its bytecode is " + data.actualVersion + ", expected version is " + data.expectedVersion, - CompilerMessageLocation.create(toSystemDependentName(data.filePath)) - ) - } } } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 7beaf6b4ffb..1812715ec94 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -409,10 +409,6 @@ object KotlinToJVMBytecodeCompiler { environment.messageCollector ) - AnalyzerWithCompilerReport.reportBytecodeVersionErrors( - generationState.extraJvmDiagnosticsTrace.bindingContext, environment.messageCollector - ) - performanceManager?.notifyIRGenerationFinished() performanceManager?.notifyGenerationFinished() ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() @@ -611,10 +607,6 @@ object KotlinToJVMBytecodeCompiler { environment.messageCollector ) - AnalyzerWithCompilerReport.reportBytecodeVersionErrors( - generationState.extraJvmDiagnosticsTrace.bindingContext, environment.messageCollector - ) - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() return generationState } diff --git a/compiler/testData/bytecodeVersion/simple/A.kt b/compiler/testData/bytecodeVersion/simple/A.kt deleted file mode 100644 index cff1e79a68c..00000000000 --- a/compiler/testData/bytecodeVersion/simple/A.kt +++ /dev/null @@ -1,7 +0,0 @@ -package library - -class A { - fun member() {} -} - -fun topLevel() {} diff --git a/compiler/testData/bytecodeVersion/simple/B.kt b/compiler/testData/bytecodeVersion/simple/B.kt deleted file mode 100644 index 6e62c2ec327..00000000000 --- a/compiler/testData/bytecodeVersion/simple/B.kt +++ /dev/null @@ -1,6 +0,0 @@ -import library.* - -fun test() { - A().member() - topLevel() -} diff --git a/compiler/testData/bytecodeVersion/simple/output.txt b/compiler/testData/bytecodeVersion/simple/output.txt deleted file mode 100644 index 7992e8beab7..00000000000 --- a/compiler/testData/bytecodeVersion/simple/output.txt +++ /dev/null @@ -1,3 +0,0 @@ -$TESTDATA_DIR$/library/A.class: error: class 'library/A' was compiled with an incompatible version of Kotlin. The binary version of its bytecode is 42.0.0, expected version is $ABI_VERSION$ -$TESTDATA_DIR$/library/AKt.class: error: class 'library/AKt' was compiled with an incompatible version of Kotlin. The binary version of its bytecode is 42.0.0, expected version is $ABI_VERSION$ -COMPILATION_ERROR diff --git a/compiler/tests/org/jetbrains/kotlin/cli/WrongBytecodeVersionTest.kt b/compiler/tests/org/jetbrains/kotlin/cli/WrongBytecodeVersionTest.kt deleted file mode 100644 index 8cfb6f663ca..00000000000 --- a/compiler/tests/org/jetbrains/kotlin/cli/WrongBytecodeVersionTest.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2010-2016 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.cli - -import com.intellij.ide.highlighter.JavaClassFileType -import org.jetbrains.kotlin.cli.common.ExitCode -import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler -import org.jetbrains.kotlin.jvm.compiler.LoadDescriptorUtil -import org.jetbrains.kotlin.load.java.JvmAnnotationNames -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmBytecodeBinaryVersion -import org.jetbrains.kotlin.test.KotlinTestUtils -import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase -import org.jetbrains.kotlin.test.util.KtTestUtil -import org.jetbrains.org.objectweb.asm.* -import java.io.File - -class WrongBytecodeVersionTest : KtUsefulTestCase() { - private val incompatibleVersion = JvmBytecodeBinaryVersion(42, 0, 0).toArray() - - private fun doTest(relativeDirectory: String, version: IntArray = incompatibleVersion) { - val directory = KtTestUtil.getTestDataPathBase() + relativeDirectory - val librarySource = File(directory, "A.kt") - val usageSource = File(directory, "B.kt") - - val tmpdir = KtTestUtil.tmpDir(this::class.java.simpleName) - - val environment = KotlinTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(testRootDisposable) - LoadDescriptorUtil.compileKotlinToDirAndGetModule(listOf(librarySource), tmpdir, environment) - - for (classFile in File(tmpdir, "library").listFiles { file -> file.extension == JavaClassFileType.INSTANCE.defaultExtension }) { - classFile.writeBytes(transformMetadataInClassFile(classFile.readBytes()) { name, _ -> - if (name == JvmAnnotationNames.BYTECODE_VERSION_FIELD_NAME) version else null - }) - } - - val (output, exitCode) = AbstractCliTest.executeCompilerGrabOutput(K2JVMCompiler(), listOf( - usageSource.path, - "-classpath", tmpdir.path, - "-d", tmpdir.path, - "-Xuse-old-backend" - )) - - assertEquals("Compilation error expected", ExitCode.COMPILATION_ERROR, exitCode) - - val normalized = AbstractCliTest.getNormalizedCompilerOutput(output, exitCode, tmpdir.path) - .replace("expected version is ${JvmBytecodeBinaryVersion.INSTANCE}", "expected version is \$ABI_VERSION\$") - - KotlinTestUtils.assertEqualsToFile(File(directory, "output.txt"), normalized) - } - - fun testSimple() { - doTest("/bytecodeVersion/simple") - } - - companion object { - fun transformMetadataInClassFile(bytes: ByteArray, transform: (fieldName: String, value: Any?) -> Any?): ByteArray { - val writer = ClassWriter(0) - ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION, writer) { - override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor { - val superVisitor = super.visitAnnotation(desc, visible) - if (desc == JvmAnnotationNames.METADATA_DESC) { - return object : AnnotationVisitor(Opcodes.API_VERSION, superVisitor) { - override fun visit(name: String, value: Any) { - super.visit(name, transform(name, value) ?: value) - } - - override fun visitArray(name: String): AnnotationVisitor { - val entries = arrayListOf() - val arrayVisitor = { super.visitArray(name) } - return object : AnnotationVisitor(Opcodes.API_VERSION) { - override fun visit(name: String?, value: Any) { - entries.add(value as String) - } - - override fun visitEnd() { - @Suppress("UNCHECKED_CAST") - val result = transform(name, entries.toTypedArray()) as Array? ?: entries.toTypedArray() - if (result.isEmpty()) return - with(arrayVisitor()) { - for (value in result) { - visit(null, value) - } - visitEnd() - } - } - } - } - } - } - return superVisitor - } - }, 0) - return writer.toByteArray() - } - } -} diff --git a/compiler/tests/org/jetbrains/kotlin/cli/transformMetadataInClassFile.kt b/compiler/tests/org/jetbrains/kotlin/cli/transformMetadataInClassFile.kt new file mode 100644 index 00000000000..8322d1bfcf4 --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/cli/transformMetadataInClassFile.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2010-2016 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.cli + +import org.jetbrains.kotlin.load.java.JvmAnnotationNames +import org.jetbrains.org.objectweb.asm.* + +internal fun transformMetadataInClassFile(bytes: ByteArray, transform: (fieldName: String, value: Any?) -> Any?): ByteArray { + val writer = ClassWriter(0) + ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION, writer) { + override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor { + val superVisitor = super.visitAnnotation(desc, visible) + if (desc == JvmAnnotationNames.METADATA_DESC) { + return object : AnnotationVisitor(Opcodes.API_VERSION, superVisitor) { + override fun visit(name: String, value: Any) { + super.visit(name, transform(name, value) ?: value) + } + + override fun visitArray(name: String): AnnotationVisitor { + val entries = arrayListOf() + val arrayVisitor = { super.visitArray(name) } + return object : AnnotationVisitor(Opcodes.API_VERSION) { + override fun visit(name: String?, value: Any) { + entries.add(value as String) + } + + override fun visitEnd() { + @Suppress("UNCHECKED_CAST") + val result = transform(name, entries.toTypedArray()) as Array? ?: entries.toTypedArray() + if (result.isEmpty()) return + with(arrayVisitor()) { + for (value in result) { + visit(null, value) + } + visitEnd() + } + } + } + } + } + } + return superVisitor + } + }, 0) + return writer.toByteArray() +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt index 4eaf74593c2..9d80dc183d5 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.jvm.compiler import com.intellij.openapi.util.io.FileUtil import junit.framework.TestCase -import org.jetbrains.kotlin.cli.WrongBytecodeVersionTest import org.jetbrains.kotlin.cli.common.CLICompiler import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport @@ -18,6 +17,7 @@ import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler +import org.jetbrains.kotlin.cli.transformMetadataInClassFile import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.codegen.inline.remove import org.jetbrains.kotlin.codegen.optimization.common.asSequence @@ -102,7 +102,7 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration val library = transformJar( compileLibrary(libraryName, additionalOptions = listOf("-Xmetadata-version=42.0.0")), { _, bytes -> - WrongBytecodeVersionTest.transformMetadataInClassFile(bytes) { fieldName, value -> + transformMetadataInClassFile(bytes) { fieldName, value -> additionalTransformation?.invoke(fieldName, value) } } diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java index e2420c17411..21a70333d44 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.load.java; -import kotlin.annotation.Repeatable; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.resolve.jvm.JvmClassName; diff --git a/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmBytecodeBinaryVersion.kt b/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmBytecodeBinaryVersion.kt index d74423b9b2c..fa972dedd89 100644 --- a/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmBytecodeBinaryVersion.kt +++ b/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmBytecodeBinaryVersion.kt @@ -17,8 +17,5 @@ class JvmBytecodeBinaryVersion(vararg numbers: Int) : BinaryVersion(*numbers) { companion object { @JvmField val INSTANCE = JvmBytecodeBinaryVersion(1, 0, 3) - - @JvmField - val INVALID_VERSION = JvmBytecodeBinaryVersion() } }