K2: report INCOMPATIBLE_CLASS in JVM
#KT-60795
This commit is contained in:
committed by
Space Team
parent
db8fb30343
commit
7d60b5df43
+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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user