K2: report INCOMPATIBLE_CLASS in JVM
#KT-60795
This commit is contained in:
committed by
Space Team
parent
db8fb30343
commit
7d60b5df43
+2
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
@@ -372,6 +373,7 @@ internal object FirToKtConversionCreator {
|
||||
ClassKind::class,
|
||||
FunctionTypeKind::class,
|
||||
VersionRequirement.Version::class,
|
||||
IncompatibleVersionErrorData::class,
|
||||
)
|
||||
|
||||
private val KType.kClass: KClass<*>
|
||||
|
||||
+8
@@ -5298,6 +5298,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.INCOMPATIBLE_CLASS) { firDiagnostic ->
|
||||
IncompatibleClassImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.IMPLEMENTING_FUNCTION_INTERFACE) { firDiagnostic ->
|
||||
ImplementingFunctionInterfaceImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
|
||||
+7
@@ -86,6 +86,7 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
/*
|
||||
@@ -3691,6 +3692,12 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = NoReflectionInClassPath::class
|
||||
}
|
||||
|
||||
interface IncompatibleClass : KtFirDiagnostic<PsiElement> {
|
||||
override val diagnosticClass get() = IncompatibleClass::class
|
||||
val presentableString: String
|
||||
val incompatibility: IncompatibleVersionErrorData<*>
|
||||
}
|
||||
|
||||
interface ImplementingFunctionInterface : KtFirDiagnostic<KtClassOrObject> {
|
||||
override val diagnosticClass get() = ImplementingFunctionInterface::class
|
||||
}
|
||||
|
||||
+8
@@ -87,6 +87,7 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
/*
|
||||
@@ -4461,6 +4462,13 @@ internal class NoReflectionInClassPathImpl(
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.NoReflectionInClassPath
|
||||
|
||||
internal class IncompatibleClassImpl(
|
||||
override val presentableString: String,
|
||||
override val incompatibility: IncompatibleVersionErrorData<*>,
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.IncompatibleClass
|
||||
|
||||
internal class ImplementingFunctionInterfaceImpl(
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
|
||||
+9
-13
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
|
||||
import java.io.Closeable
|
||||
import java.io.File
|
||||
import java.io.InputStreamReader
|
||||
@@ -24,6 +25,14 @@ object FirDiagnosticsCompilerResultsReporter {
|
||||
): Boolean {
|
||||
return reportByFile(diagnosticsCollector) { diagnostic, location ->
|
||||
reportDiagnosticToMessageCollector(diagnostic, location, messageCollector, renderDiagnosticName)
|
||||
}.also {
|
||||
AnalyzerWithCompilerReport.reportSpecialErrors(
|
||||
diagnosticsCollector.diagnostics.any { it.factory == FirJvmErrors.INCOMPATIBLE_CLASS },
|
||||
hasPrereleaseClasses = false, // TODO (KT-60780): missing PRE_RELEASE_CLASS
|
||||
hasUnstableClasses = false, // TODO (KT-61598): report FIR_COMPILED_CLASS and IR_WITH_UNSTABLE_ABI_COMPILED_CLASS
|
||||
hasFirUnstableClasses = false, // TODO (KT-61598): report FIR_COMPILED_CLASS and IR_WITH_UNSTABLE_ABI_COMPILED_CLASS
|
||||
messageCollector,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,22 +86,9 @@ object FirDiagnosticsCompilerResultsReporter {
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: for uncommenting, see comment in reportSpecialErrors
|
||||
// reportSpecialErrors(diagnostics)
|
||||
return hasErrors
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER", "unused")
|
||||
private fun reportSpecialErrors(diagnostics: Collection<KtDiagnostic>) {
|
||||
/*
|
||||
* TODO: handle next diagnostics when they will be supported in FIR:
|
||||
* - INCOMPATIBLE_CLASS
|
||||
* - PRE_RELEASE_CLASS
|
||||
* - IR_WITH_UNSTABLE_ABI_COMPILED_CLASS
|
||||
* - FIR_COMPILED_CLASS
|
||||
*/
|
||||
}
|
||||
|
||||
private fun reportDiagnosticToMessageCollector(
|
||||
diagnostic: KtDiagnostic,
|
||||
location: CompilerMessageSourceLocation,
|
||||
|
||||
+21
-7
@@ -180,9 +180,25 @@ class AnalyzerWithCompilerReport(
|
||||
messageCollector: MessageCollector,
|
||||
renderInternalDiagnosticName: Boolean
|
||||
): Boolean {
|
||||
val hasErrors = reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector), renderInternalDiagnosticName)
|
||||
return reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector), renderInternalDiagnosticName).also {
|
||||
reportSpecialErrors(
|
||||
diagnostics.any { it.factory == Errors.INCOMPATIBLE_CLASS },
|
||||
diagnostics.any { it.factory == Errors.PRE_RELEASE_CLASS },
|
||||
diagnostics.any { it.factory == Errors.IR_WITH_UNSTABLE_ABI_COMPILED_CLASS },
|
||||
diagnostics.any { it.factory == Errors.FIR_COMPILED_CLASS },
|
||||
messageCollector,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (diagnostics.any { it.factory == Errors.INCOMPATIBLE_CLASS }) {
|
||||
fun reportSpecialErrors(
|
||||
hasIncompatibleClasses: Boolean,
|
||||
hasPrereleaseClasses: Boolean,
|
||||
hasUnstableClasses: Boolean,
|
||||
hasFirUnstableClasses: Boolean,
|
||||
messageCollector: MessageCollector,
|
||||
) {
|
||||
if (hasIncompatibleClasses) {
|
||||
messageCollector.report(
|
||||
ERROR,
|
||||
"Incompatible classes were found in dependencies. " +
|
||||
@@ -190,7 +206,7 @@ class AnalyzerWithCompilerReport(
|
||||
)
|
||||
}
|
||||
|
||||
if (diagnostics.any { it.factory == Errors.PRE_RELEASE_CLASS }) {
|
||||
if (hasPrereleaseClasses) {
|
||||
messageCollector.report(
|
||||
ERROR,
|
||||
"Pre-release classes were found in dependencies. " +
|
||||
@@ -199,7 +215,7 @@ class AnalyzerWithCompilerReport(
|
||||
)
|
||||
}
|
||||
|
||||
if (diagnostics.any { it.factory == Errors.IR_WITH_UNSTABLE_ABI_COMPILED_CLASS }) {
|
||||
if (hasUnstableClasses) {
|
||||
messageCollector.report(
|
||||
ERROR,
|
||||
"Classes compiled by an unstable version of the Kotlin compiler were found in dependencies. " +
|
||||
@@ -207,15 +223,13 @@ class AnalyzerWithCompilerReport(
|
||||
)
|
||||
}
|
||||
|
||||
if (diagnostics.any { it.factory == Errors.FIR_COMPILED_CLASS }) {
|
||||
if (hasFirUnstableClasses) {
|
||||
messageCollector.report(
|
||||
ERROR,
|
||||
"Classes compiled by the new Kotlin compiler frontend were found in dependencies. " +
|
||||
"Remove them from the classpath or use '-Xallow-unstable-dependencies' to suppress errors"
|
||||
)
|
||||
}
|
||||
|
||||
return hasErrors
|
||||
}
|
||||
|
||||
fun reportSyntaxErrors(file: PsiElement, reporter: DiagnosticMessageReporter): SyntaxErrorReport {
|
||||
|
||||
+7
@@ -6,7 +6,9 @@
|
||||
package org.jetbrains.kotlin.fir.checkers.generator.diagnostics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.*
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.util.PrivateForInline
|
||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList
|
||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy
|
||||
@@ -19,6 +21,7 @@ import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
|
||||
@Suppress("ClassName", "unused")
|
||||
@OptIn(PrivateForInline::class)
|
||||
@@ -174,5 +177,9 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") {
|
||||
)
|
||||
val JAVA_SAM_INTERFACE_CONSTRUCTOR_REFERENCE by error<PsiElement>()
|
||||
val NO_REFLECTION_IN_CLASS_PATH by warning<PsiElement>()
|
||||
val INCOMPATIBLE_CLASS by error<PsiElement> {
|
||||
parameter<String>("presentableString")
|
||||
parameter<IncompatibleVersionErrorData<*>>("incompatibility")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
@@ -120,6 +121,7 @@ object FirJvmErrors {
|
||||
val SPREAD_ON_SIGNATURE_POLYMORPHIC_CALL by deprecationError0<PsiElement>(ProhibitSpreadOnSignaturePolymorphicCall, SourceElementPositioningStrategies.SPREAD_OPERATOR)
|
||||
val JAVA_SAM_INTERFACE_CONSTRUCTOR_REFERENCE by error0<PsiElement>()
|
||||
val NO_REFLECTION_IN_CLASS_PATH by warning0<PsiElement>()
|
||||
val INCOMPATIBLE_CLASS by error2<PsiElement, String, IncompatibleVersionErrorData<*>>()
|
||||
|
||||
init {
|
||||
RootDiagnosticRendererFactory.registerFactory(FirJvmErrorsDefaultMessages)
|
||||
|
||||
+16
@@ -5,10 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics.jvm
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticRenderers.TO_STRING
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderer
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.CONCURRENT_HASH_MAP_CONTAINS_OPERATOR
|
||||
@@ -27,6 +29,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.ILLEGAL_JV
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INAPPLICABLE_JVM_FIELD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INAPPLICABLE_JVM_FIELD_WARNING
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INAPPLICABLE_JVM_NAME
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INCOMPATIBLE_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INNER_JVM_RECORD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INTERFACE_CANT_CALL_DEFAULT_METHOD_VIA_SUPER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JAVA_SAM_INTERFACE_CONSTRUCTOR_REFERENCE
|
||||
@@ -79,6 +82,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZ
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_SUSPEND
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_CANNOT_BE_ARRAY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
|
||||
object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
|
||||
@@ -263,5 +267,17 @@ object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
"Call uses reflection API which is not found in compilation classpath. " +
|
||||
"Make sure you have kotlin-reflect.jar in the classpath."
|
||||
)
|
||||
map.put(
|
||||
INCOMPATIBLE_CLASS,
|
||||
"{0} was compiled with an incompatible version of Kotlin. {1}",
|
||||
STRING,
|
||||
Renderer { incompatibility: IncompatibleVersionErrorData<*> ->
|
||||
"The actual metadata version is ${incompatibility.actualVersion}, " +
|
||||
"but the compiler version ${incompatibility.compilerVersion}" +
|
||||
(if (incompatibility.languageVersion == incompatibility.compilerVersion) "" else " [with language version " + incompatibility.languageVersion + "]") +
|
||||
" can read versions up to ${incompatibility.expectedVersion}.\n" +
|
||||
"The class is loaded from ${FileUtil.toSystemIndependentName(incompatibility.filePath)}"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -19,6 +19,7 @@ object JvmExpressionCheckers : ExpressionCheckers() {
|
||||
get() = setOf(
|
||||
FirInterfaceDefaultMethodCallChecker,
|
||||
FirJavaSamInterfaceConstructorReferenceChecker,
|
||||
FirIncompatibleClassExpressionChecker,
|
||||
)
|
||||
|
||||
override val callableReferenceAccessCheckers: Set<FirCallableReferenceAccessChecker>
|
||||
|
||||
+2
@@ -8,10 +8,12 @@ package org.jetbrains.kotlin.fir.analysis.jvm.checkers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirDynamicUnsupportedChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.*
|
||||
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.type.FirFunctionalTypeParameterNameChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.type.FirJvmIncompatibleClassTypeChecker
|
||||
|
||||
object JvmTypeCheckers : TypeCheckers() {
|
||||
override val typeRefCheckers: Set<FirTypeRefChecker> = setOf(
|
||||
FirDynamicUnsupportedChecker,
|
||||
FirFunctionalTypeParameterNameChecker,
|
||||
FirJvmIncompatibleClassTypeChecker,
|
||||
)
|
||||
}
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessExpressionChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.sourceElement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
object FirIncompatibleClassExpressionChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val symbol = expression.calleeReference.toResolvedCallableSymbol() ?: return
|
||||
|
||||
checkType(symbol.resolvedReturnType, expression, context, reporter)
|
||||
checkType(symbol.receiverParameter?.typeRef?.coneType, expression, context, reporter)
|
||||
if (symbol is FirFunctionSymbol) {
|
||||
for (parameter in symbol.valueParameterSymbols) {
|
||||
checkType(parameter.resolvedReturnTypeRef.type, expression, context, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
checkSourceElement(symbol.fir.containerSource, expression, context, reporter)
|
||||
}
|
||||
|
||||
internal fun checkType(type: ConeKotlinType?, element: FirElement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val classSymbol = type?.toRegularClassSymbol(context.session)
|
||||
checkSourceElement(classSymbol?.sourceElement, element, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkSourceElement(source: SourceElement?, element: FirElement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (source !is DeserializedContainerSource) return
|
||||
|
||||
val incompatibility = source.incompatibility
|
||||
if (incompatibility != null) {
|
||||
reporter.reportOn(element.source, FirJvmErrors.INCOMPATIBLE_CLASS, source.presentableString, incompatibility, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.jvm.checkers.type
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.FirTypeRefChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression.FirIncompatibleClassExpressionChecker
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
|
||||
|
||||
object FirJvmIncompatibleClassTypeChecker : FirTypeRefChecker() {
|
||||
override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
FirIncompatibleClassExpressionChecker.checkType(typeRef.coneTypeOrNull, typeRef, context, reporter)
|
||||
}
|
||||
}
|
||||
+1
@@ -611,6 +611,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
|
||||
"JVM_SYNTHETIC_ON_DELEGATE",
|
||||
"SUBCLASS_CANT_CALL_COMPANION_PROTECTED_NON_STATIC",
|
||||
"JAVA_SAM_INTERFACE_CONSTRUCTOR_REFERENCE",
|
||||
"INCOMPATIBLE_CLASS",
|
||||
"IMPLEMENTING_FUNCTION_INTERFACE",
|
||||
"OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS",
|
||||
"OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE",
|
||||
|
||||
+2
-2
@@ -135,7 +135,7 @@ class JvmClassFileBasedSymbolProvider(
|
||||
|
||||
val kotlinClass = result.kotlinJvmBinaryClass
|
||||
if (kotlinClass.classHeader.kind != KotlinClassHeader.Kind.CLASS || kotlinClass.classId != classId) return null
|
||||
val data = kotlinClass.classHeader.data ?: return null
|
||||
val data = kotlinClass.classHeader.data ?: kotlinClass.classHeader.incompatibleData ?: return null
|
||||
val strings = kotlinClass.classHeader.strings ?: return null
|
||||
val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(data, strings)
|
||||
|
||||
@@ -144,7 +144,7 @@ class JvmClassFileBasedSymbolProvider(
|
||||
classProto,
|
||||
JvmBinaryAnnotationDeserializer(session, kotlinClass, kotlinClassFinder, result.byteContent),
|
||||
moduleDataProvider.getModuleData(kotlinClass.containingLibrary?.toPath()),
|
||||
KotlinJvmBinarySourceElement(kotlinClass),
|
||||
KotlinJvmBinarySourceElement(kotlinClass, kotlinClass.incompatibility),
|
||||
classPostProcessor = { loadAnnotationsFromClassFile(result, it) }
|
||||
)
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors
|
||||
$TMP_DIR$/library.jar!/META-INF/main.kotlin_module: error: module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is $ABI_VERSION$.
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:3:13: error: class 'a.C' was compiled with an incompatible version of Kotlin. The actual metadata version is 2.1.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library.jar!/a/C.class
|
||||
fun test(c: C) {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:4:5: error: unresolved reference 'f'.
|
||||
f()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:5:5: error: unresolved reference 'v'.
|
||||
v
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:6:5: error: class 'a.C' was compiled with an incompatible version of Kotlin. The actual metadata version is 2.1.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library.jar!/a/C.class
|
||||
c.let { C() }
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:6:13: error: class 'a.C' was compiled with an incompatible version of Kotlin. The actual metadata version is 2.1.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library.jar!/a/C.class
|
||||
c.let { C() }
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors
|
||||
$TMP_DIR$/library-after.jar!/META-INF/main.kotlin_module: error: module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:5:16: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
|
||||
fun baz(param: A, nested: A.Nested) {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:5:27: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A$Nested.class
|
||||
fun baz(param: A, nested: A.Nested) {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:6:23: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
|
||||
val constructor = A()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:7:18: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A$Nested.class
|
||||
val nested = A.Nested()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:8:22: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
|
||||
val methodCall = param.method()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:9:30: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
|
||||
val supertype = object : A() {}
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:11:13: error: unresolved reference 'foo'.
|
||||
val x = foo()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:12:13: error: unresolved reference 'bar'.
|
||||
val y = bar
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:13:5: error: unresolved reference 'bar'.
|
||||
bar = 239
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:14:12: error: unresolved reference 'TA'.
|
||||
val z: TA = ""
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors
|
||||
$TMP_DIR$/library-after.jar!/META-INF/main.kotlin_module: error: module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:16: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
|
||||
fun baz(param: A, nested: A.Nested) {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:27: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A$Nested.class
|
||||
fun baz(param: A, nested: A.Nested) {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:6:23: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
|
||||
val constructor = A()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:7:18: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A$Nested.class
|
||||
val nested = A.Nested()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:8:22: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
|
||||
val methodCall = param.method()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:9:30: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ [with language version $ABI_VERSION_NEXT$] can read versions up to $ABI_VERSION_NEXT$.
|
||||
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
|
||||
val supertype = object : A() {}
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:11:13: error: unresolved reference 'foo'.
|
||||
val x = foo()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:12:13: error: unresolved reference 'bar'.
|
||||
val y = bar
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:13:5: error: unresolved reference 'bar'.
|
||||
bar = 239
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:14:12: error: unresolved reference 'TA'.
|
||||
val z: TA = ""
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
+4
-7
@@ -282,8 +282,7 @@ abstract class AbstractCompileKotlinAgainstCustomBinariesTest : AbstractKotlinCo
|
||||
)
|
||||
}
|
||||
|
||||
// KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error
|
||||
fun testWrongMetadataVersion() = muteForK2 {
|
||||
fun testWrongMetadataVersion() {
|
||||
doTestKotlinLibraryWithWrongMetadataVersion("library", null)
|
||||
}
|
||||
|
||||
@@ -312,8 +311,7 @@ abstract class AbstractCompileKotlinAgainstCustomBinariesTest : AbstractKotlinCo
|
||||
doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-metadata-version-check")
|
||||
}
|
||||
|
||||
// KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error
|
||||
fun testWrongMetadataVersionSkipPrereleaseCheckHasNoEffect() = muteForK2 {
|
||||
fun testWrongMetadataVersionSkipPrereleaseCheckHasNoEffect() {
|
||||
doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-prerelease-check")
|
||||
}
|
||||
|
||||
@@ -346,9 +344,8 @@ abstract class AbstractCompileKotlinAgainstCustomBinariesTest : AbstractKotlinCo
|
||||
compileKotlin("source.kt", tmpdir, listOf(library))
|
||||
}
|
||||
|
||||
// KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error
|
||||
fun testStrictMetadataVersionSemanticsOldVersion() = muteForK2 {
|
||||
val nextMetadataVersion = JvmMetadataVersion.INSTANCE.next()
|
||||
fun testStrictMetadataVersionSemanticsOldVersion() {
|
||||
val nextMetadataVersion = languageVersion.toMetadataVersion().next()
|
||||
val library = compileLibrary(
|
||||
"library", additionalOptions = listOf("-Xgenerate-strict-metadata-version", "-Xmetadata-version=$nextMetadataVersion")
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user