K2: add ACCIDENTAL_OVERRIDE_CLASH_BY_JVM_SIGNATURE for clashing functions
This diagnostic is reported on an explicitly-declared function which overrides a regular Java function with the same signature as a hidden one from the same scope. #KT-64846 Fixed
This commit is contained in:
committed by
Space Team
parent
8f9614c1fb
commit
7615d863d5
+2
@@ -32,6 +32,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.psi.KtNamedFunction
|
||||
|
||||
/**
|
||||
* Generated from: [org.jetbrains.kotlin.fir.checkers.generator.diagnostics.JVM_DIAGNOSTICS_LIST]
|
||||
@@ -50,6 +51,7 @@ object FirJvmErrors {
|
||||
val VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION: KtDiagnosticFactory0 by error0<PsiElement>()
|
||||
val JVM_INLINE_WITHOUT_VALUE_CLASS: KtDiagnosticFactory0 by error0<PsiElement>()
|
||||
val WRONG_NULLABILITY_FOR_JAVA_OVERRIDE: KtDiagnosticFactory2<FirCallableSymbol<*>, FirCallableSymbol<*>> by warning2<PsiElement, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
|
||||
val ACCIDENTAL_OVERRIDE_CLASH_BY_JVM_SIGNATURE: KtDiagnosticFactory3<FirNamedFunctionSymbol, String, FirNamedFunctionSymbol> by error3<KtNamedFunction, FirNamedFunctionSymbol, String, FirNamedFunctionSymbol>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
|
||||
// Types
|
||||
val JAVA_TYPE_MISMATCH: KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType> by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
|
||||
|
||||
+11
@@ -12,9 +12,11 @@ import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.NAME
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.OPTIONAL_SENTENCE
|
||||
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.ACCIDENTAL_OVERRIDE_CLASH_BY_JVM_SIGNATURE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.CONCURRENT_HASH_MAP_CONTAINS_OPERATOR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.DELEGATION_BY_IN_JVM_RECORD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.DEPRECATED_JAVA_ANNOTATION
|
||||
@@ -115,6 +117,15 @@ object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
SYMBOL,
|
||||
)
|
||||
|
||||
map.put(
|
||||
ACCIDENTAL_OVERRIDE_CLASH_BY_JVM_SIGNATURE,
|
||||
"This function accidentally overrides both ''{0}'' and {1} ''{2}'' from JVM point of view because of mixed Java/Kotlin hierarchy.\n" +
|
||||
"This situation provokes a JVM clash and thus is forbidden. To fix it, you have to delete either this function or one of overridden functions.",
|
||||
FQ_NAMES_IN_TYPES,
|
||||
STRING,
|
||||
FQ_NAMES_IN_TYPES,
|
||||
)
|
||||
|
||||
map.put(
|
||||
UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS,
|
||||
"Type argument is not within its bounds: should be subtype of ''{0}''.",
|
||||
|
||||
+1
@@ -58,6 +58,7 @@ object JvmDeclarationCheckers : DeclarationCheckers() {
|
||||
override val simpleFunctionCheckers: Set<FirSimpleFunctionChecker>
|
||||
get() = setOf(
|
||||
FirInlineBodySimpleFunctionChecker,
|
||||
FirAccidentalOverrideClashChecker,
|
||||
)
|
||||
|
||||
override val valueParameterCheckers: Set<FirValueParameterChecker>
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.declaration
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirSimpleFunctionChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.ACCIDENTAL_OVERRIDE_CLASH_BY_JVM_SIGNATURE
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.isHiddenToOvercomeSignatureClash
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
|
||||
import org.jetbrains.kotlin.fir.initialSignatureAttr
|
||||
import org.jetbrains.kotlin.fir.resolve.getContainingClass
|
||||
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.Companion.JVM_SHORT_NAME_TO_BUILTIN_SHORT_NAMES_MAP
|
||||
import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.Companion.sameAsBuiltinMethodWithErasedValueParameters
|
||||
|
||||
object FirAccidentalOverrideClashChecker : FirSimpleFunctionChecker(MppCheckerKind.Platform) {
|
||||
override fun check(
|
||||
declaration: FirSimpleFunction,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
) {
|
||||
if (!declaration.isOverride) return
|
||||
val name = declaration.name
|
||||
val mayBeRenamedBuiltIn = name in namesPossibleForRenamedBuiltin
|
||||
val mayBeSameAsBuiltInWithErasedParameters = name.sameAsBuiltinMethodWithErasedValueParameters
|
||||
if (!mayBeRenamedBuiltIn && !mayBeSameAsBuiltInWithErasedParameters) return
|
||||
val containingClass = declaration.getContainingClass(context.session) ?: return
|
||||
|
||||
var reported = false
|
||||
containingClass.unsubstitutedScope(context).processFunctionsByName(name) {
|
||||
@OptIn(SymbolInternals::class)
|
||||
val hiddenFir = it.fir
|
||||
if (!reported && hiddenFir.isHiddenToOvercomeSignatureClash == true) {
|
||||
if (declaration.computeJvmDescriptor() == hiddenFir.computeJvmDescriptor()) {
|
||||
val regularBase = hiddenFir.initialSignatureAttr as? FirSimpleFunction ?: return@processFunctionsByName
|
||||
val description = when {
|
||||
mayBeRenamedBuiltIn -> "a renamed function"
|
||||
else -> "a function with erased parameters"
|
||||
}
|
||||
reporter.reportOn(
|
||||
declaration.source, ACCIDENTAL_OVERRIDE_CLASH_BY_JVM_SIGNATURE, it, description, regularBase.symbol, context
|
||||
)
|
||||
reported = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val namesPossibleForRenamedBuiltin = JVM_SHORT_NAME_TO_BUILTIN_SHORT_NAMES_MAP.values.toSet()
|
||||
}
|
||||
Reference in New Issue
Block a user