From 4a37de51bb458f2f509f2f3d2fd376758d744044 Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Fri, 16 Jul 2021 17:48:19 +0300 Subject: [PATCH] [FIR] Add ANONYMOUS_INITIALIZER_IN_INTERFACE diagnostic --- .../diagnostics/FirDiagnosticsList.kt | 2 ++ .../fir/analysis/diagnostics/FirErrors.kt | 2 ++ .../checkers/CommonDeclarationCheckers.kt | 5 ++++ ...rAnonymousInitializerInInterfaceChecker.kt | 23 ++++++++++++++++ .../diagnostics/FirDefaultErrorMessages.kt | 2 ++ .../tests/AnonymousInitializers.fir.kt | 26 ------------------- .../tests/AnonymousInitializers.kt | 1 + .../tests/annotations/onInitializer.fir.kt | 4 +-- .../diagnostics/KtFirDataClassConverters.kt | 7 +++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 5 ++++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 8 ++++++ 11 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnonymousInitializerInInterfaceChecker.kt delete mode 100644 compiler/testData/diagnostics/tests/AnonymousInitializers.fir.kt diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index b8715598d21..f839c7b217a 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -1083,6 +1083,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val RETURN_NOT_ALLOWED by error(PositioningStrategy.RETURN_WITH_LABEL) val RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY by error(PositioningStrategy.RETURN_WITH_LABEL) val NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY by error(PositioningStrategy.DECLARATION_WITH_BODY) + + val ANONYMOUS_INITIALIZER_IN_INTERFACE by error(PositioningStrategy.DECLARATION_SIGNATURE) } val INLINE by object : DiagnosticGroup("Inline") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index eb9b445bc3f..c71ec33603e 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.psi.KtAnonymousInitializer import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS @@ -573,6 +574,7 @@ object FirErrors { val RETURN_NOT_ALLOWED by error0(SourceElementPositioningStrategies.RETURN_WITH_LABEL) val RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY by error0(SourceElementPositioningStrategies.RETURN_WITH_LABEL) val NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY by error0(SourceElementPositioningStrategies.DECLARATION_WITH_BODY) + val ANONYMOUS_INITIALIZER_IN_INTERFACE by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) // Inline val USAGE_IS_NOT_INLINABLE by error1>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index ef569281fc0..771262a72a9 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -140,4 +140,9 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirAnonymousFunctionParametersChecker, FirAnonymousFunctionSyntaxChecker, ) + + override val anonymousInitializerCheckers: Set + get() = setOf( + FirAnonymousInitializerInInterfaceChecker + ) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnonymousInitializerInInterfaceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnonymousInitializerInInterfaceChecker.kt new file mode 100644 index 00000000000..fdb5e40ab5f --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnonymousInitializerInInterfaceChecker.kt @@ -0,0 +1,23 @@ +/* + * 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.checkers.declaration + +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.declarations.FirAnonymousInitializer +import org.jetbrains.kotlin.fir.declarations.utils.isInterface + +object FirAnonymousInitializerInInterfaceChecker : FirAnonymousInitializerChecker() { + override fun check(declaration: FirAnonymousInitializer, context: CheckerContext, reporter: DiagnosticReporter) { + val clazz = context.findClosestClassOrObject() ?: return + if (clazz.isInterface) { + reporter.reportOn(declaration.source, FirErrors.ANONYMOUS_INITIALIZER_IN_INTERFACE, context) + } + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index b8a2a8753a1..3964a5faec7 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -57,6 +57,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_ON_SUP import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_USED_AS_ANNOTATION_ARGUMENT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_INITIALIZER_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_PASSED_TWICE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_TYPE_MISMATCH import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS @@ -1366,6 +1367,7 @@ class FirDefaultErrorMessages { RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY, "Returns are not allowed for functions with expression body. Use block body in '{...}'" ) + map.put(ANONYMOUS_INITIALIZER_IN_INTERFACE, "Anonymous initializers are not allowed in interfaces") // Inline map.put( diff --git a/compiler/testData/diagnostics/tests/AnonymousInitializers.fir.kt b/compiler/testData/diagnostics/tests/AnonymousInitializers.fir.kt deleted file mode 100644 index f4a9bcdd1c5..00000000000 --- a/compiler/testData/diagnostics/tests/AnonymousInitializers.fir.kt +++ /dev/null @@ -1,26 +0,0 @@ -interface NoC { - init { - - } - - val a : Int get() = 1 - - init { - - } -} - -class WithC() { - val x : Int = 1 - init { - val b = x - - } - - val a : Int get() = 1 - - init { - val z = b - val zz = x - } -} diff --git a/compiler/testData/diagnostics/tests/AnonymousInitializers.kt b/compiler/testData/diagnostics/tests/AnonymousInitializers.kt index 5b30445d0d3..a4d7e84ce95 100644 --- a/compiler/testData/diagnostics/tests/AnonymousInitializers.kt +++ b/compiler/testData/diagnostics/tests/AnonymousInitializers.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface NoC { init { diff --git a/compiler/testData/diagnostics/tests/annotations/onInitializer.fir.kt b/compiler/testData/diagnostics/tests/annotations/onInitializer.fir.kt index 9cfe8761a65..ae9955da41e 100644 --- a/compiler/testData/diagnostics/tests/annotations/onInitializer.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/onInitializer.fir.kt @@ -4,8 +4,8 @@ class A { } interface T { - @ann init {} - @aaa init {} + @ann init {} + @aaa init {} } annotation class ann 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 d8399b61ecb..1133def9ef5 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 @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.psi.KtAnonymousInitializer import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS @@ -2958,6 +2959,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.ANONYMOUS_INITIALIZER_IN_INTERFACE) { firDiagnostic -> + AnonymousInitializerInInterfaceImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } add(FirErrors.USAGE_IS_NOT_INLINABLE) { firDiagnostic -> UsageIsNotInlinableImpl( firSymbolBuilder.buildSymbol(firDiagnostic.a.fir), 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 4d86c29ad21..28a44f4cb23 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 @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.psi.KtAnonymousInitializer import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS @@ -2064,6 +2065,10 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = NoReturnInFunctionWithBlockBody::class } + abstract class AnonymousInitializerInInterface : KtFirDiagnostic() { + override val diagnosticClass get() = AnonymousInitializerInInterface::class + } + abstract class UsageIsNotInlinable : KtFirDiagnostic() { override val diagnosticClass get() = UsageIsNotInlinable::class abstract val parameter: KtSymbol 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 5110a976a1d..48d176576b2 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 @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.psi.KtAnonymousInitializer import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS @@ -3337,6 +3338,13 @@ internal class NoReturnInFunctionWithBlockBodyImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class AnonymousInitializerInInterfaceImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.AnonymousInitializerInInterface(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + internal class UsageIsNotInlinableImpl( override val parameter: KtSymbol, firDiagnostic: FirPsiDiagnostic,