From 3b21759697d5e2d34694b91dd70f3327bf858083 Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Wed, 18 Aug 2021 16:55:50 +0300 Subject: [PATCH] [FIR] SUPER_CALL_WITH_DEFAULT_PARAMETERS diagnostic --- .../diagnostics/FirJvmDiagnosticsList.kt | 6 +++ .../analysis/diagnostics/jvm/FirJvmErrors.kt | 3 ++ .../jvm/checkers/JvmExpressionCheckers.kt | 2 + .../FirSuperCallWithDefaultsChecker.kt | 41 +++++++++++++++++++ .../tests/defaultArguments/superCall.fir.kt | 28 ------------- .../tests/defaultArguments/superCall.kt | 1 + .../diagnostics/KtFirDataClassConverters.kt | 22 +--------- .../api/fir/diagnostics/KtFirDiagnostics.kt | 18 ++------ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 27 ++---------- 9 files changed, 61 insertions(+), 87 deletions(-) create mode 100644 compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirSuperCallWithDefaultsChecker.kt delete mode 100644 compiler/testData/diagnostics/tests/defaultArguments/superCall.fir.kt diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt index a8bb52ff8a9..b0889fb665a 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt @@ -55,4 +55,10 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") { val JVM_PACKAGE_NAME_NOT_SUPPORTED_IN_FILES_WITH_CLASSES by error() } + val SUPER by object : DiagnosticGroup("Super") { + val SUPER_CALL_WITH_DEFAULT_PARAMETERS by error() { + parameter("name") + } + } + } diff --git a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt index 89ab3872b8a..cdbb8bf00ce 100644 --- a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt +++ b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt @@ -46,4 +46,7 @@ object FirJvmErrors { val JVM_PACKAGE_NAME_MUST_BE_VALID_NAME by error0() val JVM_PACKAGE_NAME_NOT_SUPPORTED_IN_FILES_WITH_CLASSES by error0() + // Super + val SUPER_CALL_WITH_DEFAULT_PARAMETERS by error1() + } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmExpressionCheckers.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmExpressionCheckers.kt index c013bae4a4a..6d62e496731 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmExpressionCheckers.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmExpressionCheckers.kt @@ -11,11 +11,13 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChec import org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression.FirDeprecatedJavaAnnotationsChecker import org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression.FirJavaGenericVarianceViolationTypeChecker import org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression.FirJvmPackageNameAnnotationsChecker +import org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression.FirSuperCallWithDefaultsChecker object JvmExpressionCheckers : ExpressionCheckers() { override val functionCallCheckers: Set get() = setOf( FirJavaGenericVarianceViolationTypeChecker, + FirSuperCallWithDefaultsChecker, ) override val annotationCallCheckers: Set diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirSuperCallWithDefaultsChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirSuperCallWithDefaultsChecker.kt new file mode 100644 index 00000000000..c9cd6324c90 --- /dev/null +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirSuperCallWithDefaultsChecker.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2021 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.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.expressions.FirFunctionCall +import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression +import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.references.FirSuperReference +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.utils.addToStdlib.safeAs + +object FirSuperCallWithDefaultsChecker : FirFunctionCallChecker() { + + override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) { + expression.explicitReceiver.safeAs() + ?.calleeReference.safeAs() + ?: return + + val functionSymbol = + (expression.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol ?: return + if (!functionSymbol.valueParameterSymbols.any { it.hasDefaultValue }) return + val arguments = expression.argumentList as? FirResolvedArgumentList ?: return + if (arguments.arguments.size < functionSymbol.valueParameterSymbols.size) { + reporter.reportOn( + expression.calleeReference.source, + FirJvmErrors.SUPER_CALL_WITH_DEFAULT_PARAMETERS, + functionSymbol.name.asString(), + context + ) + } + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/defaultArguments/superCall.fir.kt b/compiler/testData/diagnostics/tests/defaultArguments/superCall.fir.kt deleted file mode 100644 index 2361d21397f..00000000000 --- a/compiler/testData/diagnostics/tests/defaultArguments/superCall.fir.kt +++ /dev/null @@ -1,28 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -ABSTRACT_SUPER_CALL - -abstract class A { - open fun foo(a: String = "default") { - } - - final fun foo2(a: String = "default") { - } - - abstract fun foo3(a: String = "default") -} - -open class B : A() { - fun test() { - super.foo("123") - super.foo() - - super.foo2("123") - super.foo2() - - super.foo3("123") - super.foo3() - } - - override fun foo3(a: String) { - throw UnsupportedOperationException() - } -} diff --git a/compiler/testData/diagnostics/tests/defaultArguments/superCall.kt b/compiler/testData/diagnostics/tests/defaultArguments/superCall.kt index 7091ae75d08..a3a63e1e77e 100644 --- a/compiler/testData/diagnostics/tests/defaultArguments/superCall.kt +++ b/compiler/testData/diagnostics/tests/defaultArguments/superCall.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER -ABSTRACT_SUPER_CALL abstract class A { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index da5a0d19a28..1e5111ca23b 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -345,26 +345,8 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } - add(FirErrors.SUPER_IS_NOT_AN_EXPRESSION) { firDiagnostic -> - SuperIsNotAnExpressionImpl( - firDiagnostic as FirPsiDiagnostic, - token, - ) - } - add(FirErrors.SUPER_NOT_AVAILABLE) { firDiagnostic -> - SuperNotAvailableImpl( - firDiagnostic as FirPsiDiagnostic, - token, - ) - } - add(FirErrors.ABSTRACT_SUPER_CALL) { firDiagnostic -> - AbstractSuperCallImpl( - firDiagnostic as FirPsiDiagnostic, - token, - ) - } - add(FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL) { firDiagnostic -> - InstanceAccessBeforeSuperCallImpl( + add(FirJvmErrors.SUPER_CALL_WITH_DEFAULT_PARAMETERS) { firDiagnostic -> + SuperCallWithDefaultParametersImpl( firDiagnostic.a, firDiagnostic as FirPsiDiagnostic, token, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index 612011a92e4..8395cf15d29 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -270,21 +270,9 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val classSymbol: KtClassLikeSymbol } - abstract class SuperIsNotAnExpression : KtFirDiagnostic() { - override val diagnosticClass get() = SuperIsNotAnExpression::class - } - - abstract class SuperNotAvailable : KtFirDiagnostic() { - override val diagnosticClass get() = SuperNotAvailable::class - } - - abstract class AbstractSuperCall : KtFirDiagnostic() { - override val diagnosticClass get() = AbstractSuperCall::class - } - - abstract class InstanceAccessBeforeSuperCall : KtFirDiagnostic() { - override val diagnosticClass get() = InstanceAccessBeforeSuperCall::class - abstract val target: String + abstract class SuperCallWithDefaultParameters : KtFirDiagnostic() { + override val diagnosticClass get() = SuperCallWithDefaultParameters::class + abstract val name: String } abstract class NotASupertype : KtFirDiagnostic() { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index d4b240b4631..3b55dee04a9 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -400,32 +400,11 @@ internal class ResolutionToClassifierImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } -internal class SuperIsNotAnExpressionImpl( +internal class SuperCallWithDefaultParametersImpl( + override val name: String, firDiagnostic: FirPsiDiagnostic, override val token: ValidityToken, -) : KtFirDiagnostic.SuperIsNotAnExpression(), KtAbstractFirDiagnostic { - override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) -} - -internal class SuperNotAvailableImpl( - firDiagnostic: FirPsiDiagnostic, - override val token: ValidityToken, -) : KtFirDiagnostic.SuperNotAvailable(), KtAbstractFirDiagnostic { - override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) -} - -internal class AbstractSuperCallImpl( - firDiagnostic: FirPsiDiagnostic, - override val token: ValidityToken, -) : KtFirDiagnostic.AbstractSuperCall(), KtAbstractFirDiagnostic { - override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) -} - -internal class InstanceAccessBeforeSuperCallImpl( - override val target: String, - firDiagnostic: FirPsiDiagnostic, - override val token: ValidityToken, -) : KtFirDiagnostic.InstanceAccessBeforeSuperCall(), KtAbstractFirDiagnostic { +) : KtFirDiagnostic.SuperCallWithDefaultParameters(), KtAbstractFirDiagnostic { override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) }