[FIR] Forbid mixing supertypes with different functional kinds
^KT-61277 Fixed
This commit is contained in:
committed by
Space Team
parent
f674529558
commit
4958196c51
+9
@@ -4671,6 +4671,15 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.MIXING_FUNCTIONAL_KINDS_IN_SUPERTYPES) { firDiagnostic ->
|
||||||
|
MixingFunctionalKindsInSupertypesImpl(
|
||||||
|
firDiagnostic.a.map { functionTypeKind ->
|
||||||
|
functionTypeKind
|
||||||
|
},
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.REDUNDANT_LABEL_WARNING) { firDiagnostic ->
|
add(FirErrors.REDUNDANT_LABEL_WARNING) { firDiagnostic ->
|
||||||
RedundantLabelWarningImpl(
|
RedundantLabelWarningImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+5
@@ -3260,6 +3260,11 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = MixingSuspendAndNonSuspendSupertypes::class
|
override val diagnosticClass get() = MixingSuspendAndNonSuspendSupertypes::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MixingFunctionalKindsInSupertypes : KtFirDiagnostic<PsiElement> {
|
||||||
|
override val diagnosticClass get() = MixingFunctionalKindsInSupertypes::class
|
||||||
|
val kinds: List<FunctionTypeKind>
|
||||||
|
}
|
||||||
|
|
||||||
interface RedundantLabelWarning : KtFirDiagnostic<KtLabelReferenceExpression> {
|
interface RedundantLabelWarning : KtFirDiagnostic<KtLabelReferenceExpression> {
|
||||||
override val diagnosticClass get() = RedundantLabelWarning::class
|
override val diagnosticClass get() = RedundantLabelWarning::class
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -3933,6 +3933,12 @@ internal class MixingSuspendAndNonSuspendSupertypesImpl(
|
|||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.MixingSuspendAndNonSuspendSupertypes
|
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.MixingSuspendAndNonSuspendSupertypes
|
||||||
|
|
||||||
|
internal class MixingFunctionalKindsInSupertypesImpl(
|
||||||
|
override val kinds: List<FunctionTypeKind>,
|
||||||
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
token: KtLifetimeToken,
|
||||||
|
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.MixingFunctionalKindsInSupertypes
|
||||||
|
|
||||||
internal class RedundantLabelWarningImpl(
|
internal class RedundantLabelWarningImpl(
|
||||||
firDiagnostic: KtPsiDiagnostic,
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
|
|||||||
+3
@@ -1650,6 +1650,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
)
|
)
|
||||||
val RETURN_FOR_BUILT_IN_SUSPEND by error<KtReturnExpression>()
|
val RETURN_FOR_BUILT_IN_SUSPEND by error<KtReturnExpression>()
|
||||||
val MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES by error<PsiElement>(PositioningStrategy.SUPERTYPES_LIST)
|
val MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES by error<PsiElement>(PositioningStrategy.SUPERTYPES_LIST)
|
||||||
|
val MIXING_FUNCTIONAL_KINDS_IN_SUPERTYPES by error<PsiElement>(PositioningStrategy.SUPERTYPES_LIST) {
|
||||||
|
parameter<Set<FunctionTypeKind>>("kinds")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val LABEL by object : DiagnosticGroup("label") {
|
val LABEL by object : DiagnosticGroup("label") {
|
||||||
|
|||||||
@@ -827,6 +827,7 @@ object FirErrors {
|
|||||||
val MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND_FUN by deprecationError0<PsiElement>(ModifierNonBuiltinSuspendFunError, SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND_FUN by deprecationError0<PsiElement>(ModifierNonBuiltinSuspendFunError, SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val RETURN_FOR_BUILT_IN_SUSPEND by error0<KtReturnExpression>()
|
val RETURN_FOR_BUILT_IN_SUSPEND by error0<KtReturnExpression>()
|
||||||
val MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES by error0<PsiElement>(SourceElementPositioningStrategies.SUPERTYPES_LIST)
|
val MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES by error0<PsiElement>(SourceElementPositioningStrategies.SUPERTYPES_LIST)
|
||||||
|
val MIXING_FUNCTIONAL_KINDS_IN_SUPERTYPES by error1<PsiElement, Set<FunctionTypeKind>>(SourceElementPositioningStrategies.SUPERTYPES_LIST)
|
||||||
|
|
||||||
// label
|
// label
|
||||||
val REDUNDANT_LABEL_WARNING by warning0<KtLabelReferenceExpression>(SourceElementPositioningStrategies.LABEL)
|
val REDUNDANT_LABEL_WARNING by warning0<KtLabelReferenceExpression>(SourceElementPositioningStrategies.LABEL)
|
||||||
|
|||||||
+1
-1
@@ -109,7 +109,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
FirEnumCompanionInEnumConstructorCallChecker,
|
FirEnumCompanionInEnumConstructorCallChecker,
|
||||||
FirBadInheritedJavaSignaturesChecker,
|
FirBadInheritedJavaSignaturesChecker,
|
||||||
FirSealedInterfaceAllowedChecker,
|
FirSealedInterfaceAllowedChecker,
|
||||||
FirSuspendFunctionAsSupertypeChecker,
|
FirMixedFunctionalTypesInSupertypesChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val regularClassCheckers: Set<FirRegularClassChecker>
|
override val regularClassCheckers: Set<FirRegularClassChecker>
|
||||||
|
|||||||
+13
-10
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.functions.isBasicFunctionOrKFunction
|
import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind.Function
|
||||||
import org.jetbrains.kotlin.builtins.functions.isSuspendOrKSuspendFunction
|
import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind.SuspendFunction
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
@@ -15,16 +15,19 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
|
|||||||
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
||||||
import org.jetbrains.kotlin.fir.types.functionTypeKind
|
import org.jetbrains.kotlin.fir.types.functionTypeKind
|
||||||
|
|
||||||
object FirSuspendFunctionAsSupertypeChecker : FirClassChecker() {
|
object FirMixedFunctionalTypesInSupertypesChecker : FirClassChecker() {
|
||||||
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val supertypes = lookupSuperTypes(declaration.symbol, lookupInterfaces = true, deep = true, context.session)
|
val superKinds = lookupSuperTypes(declaration.symbol, lookupInterfaces = true, deep = true, context.session)
|
||||||
.mapNotNull { it.functionTypeKind(context.session) }
|
.mapNotNullTo(mutableSetOf()) { it.functionTypeKind(context.session)?.nonReflectKind() }
|
||||||
|
|
||||||
if (
|
when {
|
||||||
supertypes.any { it.isSuspendOrKSuspendFunction } &&
|
superKinds.size <= 1 -> {}
|
||||||
supertypes.any { it.isBasicFunctionOrKFunction }
|
superKinds == setOf(Function, SuspendFunction) -> {
|
||||||
) {
|
reporter.reportOn(declaration.source, FirErrors.MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES, context)
|
||||||
reporter.reportOn(declaration.source, FirErrors.MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES, context)
|
}
|
||||||
|
else -> {
|
||||||
|
reporter.reportOn(declaration.source, FirErrors.MIXING_FUNCTIONAL_KINDS_IN_SUPERTYPES, superKinds, context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
@@ -356,6 +356,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.METHOD_OF_ANY_IMP
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISPLACED_TYPE_PARAMETER_CONSTRAINTS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISPLACED_TYPE_PARAMETER_CONSTRAINTS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_STDLIB_CLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_STDLIB_CLASS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MIXING_FUNCTIONAL_KINDS_IN_SUPERTYPES
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND_FUN
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND_FUN
|
||||||
@@ -2349,6 +2350,11 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
)
|
)
|
||||||
map.put(RETURN_FOR_BUILT_IN_SUSPEND, "Using implicit label for this lambda is prohibited")
|
map.put(RETURN_FOR_BUILT_IN_SUSPEND, "Using implicit label for this lambda is prohibited")
|
||||||
map.put(MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES, "Mixing suspend and non-suspend supertypes is not allowed")
|
map.put(MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES, "Mixing suspend and non-suspend supertypes is not allowed")
|
||||||
|
map.put(
|
||||||
|
MIXING_FUNCTIONAL_KINDS_IN_SUPERTYPES,
|
||||||
|
"Mixing supertypes of different functional kinds ({0}) is not allowed.",
|
||||||
|
FUNCTIONAL_TYPE_KINDS,
|
||||||
|
)
|
||||||
|
|
||||||
// Label
|
// Label
|
||||||
map.put(
|
map.put(
|
||||||
|
|||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
FILE: mixingComposableAndNormalFunctions.kt
|
||||||
|
public abstract class MyClass : R|kotlin/reflect/KSuspendFunction0<kotlin/Unit>|, R|() -> kotlin/Unit| {
|
||||||
|
public constructor(): R|MyClass| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract class OurClass : R|@R|org/jetbrains/kotlin/fir/plugin/MyComposable|() some/MyComposableFunction1<kotlin/Int, kotlin/Unit>|, R|() -> kotlin/Unit| {
|
||||||
|
public constructor(): R|OurClass| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract class YourClass : R|@R|org/jetbrains/kotlin/fir/plugin/MyComposable|() kotlin/reflect/KFunction1<kotlin/Boolean, kotlin/Unit>|, R|() -> kotlin/Unit| {
|
||||||
|
public constructor(): R|YourClass| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract class Their : R|kotlin/reflect/KSuspendFunction1<kotlin/Boolean, kotlin/Unit>|, R|() -> kotlin/Unit| {
|
||||||
|
public constructor(): R|Their| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import org.jetbrains.kotlin.fir.plugin.MyComposable
|
||||||
|
import kotlin.reflect.*
|
||||||
|
|
||||||
|
abstract class MyClass: <!MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES!>KSuspendFunction0<Unit>, () -> Unit<!>
|
||||||
|
abstract class OurClass: <!MIXING_FUNCTIONAL_KINDS_IN_SUPERTYPES!>@MyComposable (Int) -> Unit, () -> Unit<!>
|
||||||
|
|
||||||
|
abstract class YourClass: @MyComposable KFunction1<Boolean, Unit>, () -> Unit
|
||||||
|
abstract class Their: <!MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES!>KSuspendFunction1<Boolean, Unit>, () -> Unit<!>
|
||||||
+6
@@ -39,6 +39,12 @@ public class FirPsiPluginDiagnosticTestGenerated extends AbstractFirPsiPluginDia
|
|||||||
runTest("plugins/fir-plugin-prototype/testData/diagnostics/checkers/dependencyWithoutAttributePlugin.kt");
|
runTest("plugins/fir-plugin-prototype/testData/diagnostics/checkers/dependencyWithoutAttributePlugin.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("mixingComposableAndNormalFunctions.kt")
|
||||||
|
public void testMixingComposableAndNormalFunctions() throws Exception {
|
||||||
|
runTest("plugins/fir-plugin-prototype/testData/diagnostics/checkers/mixingComposableAndNormalFunctions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("signedNumbersCheckers.kt")
|
@TestMetadata("signedNumbersCheckers.kt")
|
||||||
public void testSignedNumbersCheckers() throws Exception {
|
public void testSignedNumbersCheckers() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user