From 7e7066d75e2cadc6c72ca051a9be4359cfabdb28 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Fri, 10 Sep 2021 18:00:31 +0300 Subject: [PATCH] [FIR] Add FUNCTION_DELEGATE_MEMBER_NAME_CLASH --- .../diagnostics/FirJvmDiagnosticsList.kt | 2 ++ .../analysis/diagnostics/jvm/FirJvmErrors.kt | 1 + .../jvm/checkers/JvmDeclarationCheckers.kt | 3 +- ...mFunctionDelegateMemberNameClashChecker.kt | 36 +++++++++++++++++++ .../diagnostics/FirJvmDefaultErrorMessages.kt | 3 ++ .../functionDelegateClashOnJvm.fir.kt | 32 ----------------- .../functionDelegateClashOnJvm.kt | 1 + .../diagnostics/KtFirDataClassConverters.kt | 6 ++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 4 +++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 7 ++++ 10 files changed, 62 insertions(+), 33 deletions(-) create mode 100644 compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmFunctionDelegateMemberNameClashChecker.kt delete mode 100644 compiler/testData/diagnostics/tests/funInterface/functionDelegateClashOnJvm.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 cf980bfc6bf..06caedf87ff 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 @@ -35,6 +35,8 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") { val INAPPLICABLE_JVM_NAME by error() val ILLEGAL_JVM_NAME by error() + + val FUNCTION_DELEGATE_MEMBER_NAME_CLASH by error(PositioningStrategy.DECLARATION_NAME) } val TYPES by object : DiagnosticGroup("Types") { 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 81c806a588d..08ad938f4c7 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 @@ -39,6 +39,7 @@ object FirJvmErrors { val JVM_STATIC_ON_EXTERNAL_IN_INTERFACE by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val INAPPLICABLE_JVM_NAME by error0() val ILLEGAL_JVM_NAME by error0() + val FUNCTION_DELEGATE_MEMBER_NAME_CLASH by error0(SourceElementPositioningStrategies.DECLARATION_NAME) // Types val JAVA_TYPE_MISMATCH by error2() diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt index 1341f54964a..596a410fa6a 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt @@ -13,7 +13,8 @@ object JvmDeclarationCheckers : DeclarationCheckers() { get() = setOf( FirJvmExternalDeclarationChecker, FirJvmNameChecker, - FirJvmDefaultChecker + FirJvmDefaultChecker, + FirJvmFunctionDelegateMemberNameClashChecker ) override val annotatedDeclarationCheckers: Set diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmFunctionDelegateMemberNameClashChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmFunctionDelegateMemberNameClashChecker.kt new file mode 100644 index 00000000000..56a8cfa81ff --- /dev/null +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmFunctionDelegateMemberNameClashChecker.kt @@ -0,0 +1,36 @@ +/* + * 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.declaration + +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker +import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol +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.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.isFun +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.isExtension +import org.jetbrains.kotlin.name.Name + +object FirJvmFunctionDelegateMemberNameClashChecker : FirBasicDeclarationChecker() { + private val functionDelegateName: Name = Name.identifier("functionDelegate") + private val getFunctionDelegateName: Name = Name.identifier("getFunctionDelegate") + + override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { + if (declaration !is FirCallableDeclaration) return + val containingClassSymbol = declaration.getContainingClassSymbol(context.session) as? FirRegularClassSymbol ?: return + if (!containingClassSymbol.isFun) return + if (declaration.symbol.isExtension || (declaration as? FirFunction)?.valueParameters?.isNotEmpty() == true) return + + if (declaration is FirSimpleFunction && declaration.name == getFunctionDelegateName || + declaration is FirProperty && declaration.name == functionDelegateName + ) { + reporter.reportOn(declaration.source, FirJvmErrors.FUNCTION_DELEGATE_MEMBER_NAME_CLASH, context) + } + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt index 47cbc2c534c..a1473ed14fd 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.EXTERNAL_D import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.EXTERNAL_DECLARATION_CANNOT_HAVE_BODY import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.EXTERNAL_DECLARATION_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.FIELD_IN_JVM_RECORD +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.FUNCTION_DELEGATE_MEMBER_NAME_CLASH import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.ILLEGAL_JVM_NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INAPPLICABLE_JVM_FIELD @@ -160,6 +161,8 @@ object FirJvmDefaultErrorMessages { map.put(INAPPLICABLE_JVM_NAME, "'@JvmName' annotation is not applicable to this declaration") map.put(ILLEGAL_JVM_NAME, "Illegal JVM name") + map.put(FUNCTION_DELEGATE_MEMBER_NAME_CLASH, "Spread operator is prohibited for arguments to signature-polymorphic calls") + map.put(JVM_DEFAULT_NOT_IN_INTERFACE, "'@JvmDefault' is only supported on interface members") map.put( JVM_DEFAULT_IN_JVM6_TARGET, diff --git a/compiler/testData/diagnostics/tests/funInterface/functionDelegateClashOnJvm.fir.kt b/compiler/testData/diagnostics/tests/funInterface/functionDelegateClashOnJvm.fir.kt deleted file mode 100644 index cb396db5560..00000000000 --- a/compiler/testData/diagnostics/tests/funInterface/functionDelegateClashOnJvm.fir.kt +++ /dev/null @@ -1,32 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER - -fun interface F1 { - val functionDelegate: Function<*>? get() = null - fun invoke() -} - -fun interface F2 { - fun getFunctionDelegate(): Function<*>? = null - fun invoke() -} - -fun interface F3 { - val getFunctionDelegate: Function<*>? get() = null - fun invoke() -} - -fun interface F4 { - fun functionDelegate(): Function<*>? = null - fun invoke() -} - -fun interface F5 { - val functionDelegate: Any? get() = null - fun invoke() -} - -fun interface F6 { - val String.functionDelegate: Function<*>? get() = null - fun getFunctionDelegate(x: Any?): Function<*>? = null - fun invoke() -} diff --git a/compiler/testData/diagnostics/tests/funInterface/functionDelegateClashOnJvm.kt b/compiler/testData/diagnostics/tests/funInterface/functionDelegateClashOnJvm.kt index 32bd0683588..355037a7b83 100644 --- a/compiler/testData/diagnostics/tests/funInterface/functionDelegateClashOnJvm.kt +++ b/compiler/testData/diagnostics/tests/funInterface/functionDelegateClashOnJvm.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER fun interface F1 { 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 b2f11ac5734..334f28ffbfd 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 @@ -3626,6 +3626,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirJvmErrors.FUNCTION_DELEGATE_MEMBER_NAME_CLASH) { firDiagnostic -> + FunctionDelegateMemberNameClashImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } add(FirJvmErrors.JAVA_TYPE_MISMATCH) { firDiagnostic -> JavaTypeMismatchImpl( firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), 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 7f4f3619a5b..b05a8e6d908 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 @@ -2525,6 +2525,10 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = IllegalJvmName::class } + abstract class FunctionDelegateMemberNameClash : KtFirDiagnostic() { + override val diagnosticClass get() = FunctionDelegateMemberNameClash::class + } + abstract class JavaTypeMismatch : KtFirDiagnostic() { override val diagnosticClass get() = JavaTypeMismatch::class abstract val expectedType: KtType 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 62c1103179e..9f7dc9f7a9a 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 @@ -4095,6 +4095,13 @@ internal class IllegalJvmNameImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class FunctionDelegateMemberNameClashImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.FunctionDelegateMemberNameClash(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + internal class JavaTypeMismatchImpl( override val expectedType: KtType, override val actualType: KtType,