From de592f4f676e2c33eba55d97ad2803ffec3e1b45 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Fri, 15 Jan 2021 23:21:24 -0800 Subject: [PATCH] FIR checker: introduce FunctionChecker alias and use it to add support diagnostic FUNCTION_DECLARATION_WITH_NO_NAME --- .../diagnostics/conflictingOverloads.kt | 4 +-- .../kotlin/fir/checkers/generator/Main.kt | 1 + .../ComposedDeclarationCheckers.kt | 4 +++ .../declaration/DeclarationCheckers.kt | 4 ++- .../FirDeclarationCheckerAliases.kt | 2 ++ .../declaration/FirFunctionNameChecker.kt | 29 +++++++++++++++++++ .../DeclarationCheckersDiagnosticComponent.kt | 4 +-- .../diagnostics/FirDefaultErrorMessages.kt | 3 ++ .../fir/analysis/diagnostics/FirErrors.kt | 2 ++ .../fir/checkers/CommonDeclarationCheckers.kt | 4 +++ .../FunctionWithMissingNames.fir.kt | 16 +++++----- .../duplicateJvmSignature/missingNames.fir.kt | 6 ++-- .../tests/recovery/namelessInJava.fir.kt | 18 ------------ .../tests/recovery/namelessInJava.kt | 1 + .../tests/recovery/namelessMembers.fir.kt | 17 ----------- .../tests/recovery/namelessMembers.kt | 1 + .../namelessToplevelDeclarations.fir.kt | 2 +- 17 files changed, 66 insertions(+), 52 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirFunctionNameChecker.kt delete mode 100644 compiler/testData/diagnostics/tests/recovery/namelessInJava.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/recovery/namelessMembers.fir.kt diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.kt index 48bf6e25af2..d123aa55763 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.kt @@ -63,6 +63,6 @@ fun mest() class mest -fun() {} +fun() {} -private fun() {} +private fun() {} diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt index 1eadb1b7186..41ec1d4a3a1 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt @@ -27,6 +27,7 @@ fun main(args: Array) { generateCheckersComponents(generationPath, declarationPackage, "FirDeclarationChecker") { alias("BasicDeclarationChecker") alias("MemberDeclarationChecker") + alias>("FunctionChecker") alias("PropertyChecker") alias("RegularClassChecker") alias("ConstructorChecker") diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/ComposedDeclarationCheckers.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/ComposedDeclarationCheckers.kt index 8080f5c677b..0298aabbea9 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/ComposedDeclarationCheckers.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/ComposedDeclarationCheckers.kt @@ -19,6 +19,8 @@ internal class ComposedDeclarationCheckers : DeclarationCheckers() { get() = _basicDeclarationCheckers override val memberDeclarationCheckers: Set get() = _memberDeclarationCheckers + override val functionCheckers: Set + get() = _functionCheckers override val propertyCheckers: Set get() = _propertyCheckers override val regularClassCheckers: Set @@ -34,6 +36,7 @@ internal class ComposedDeclarationCheckers : DeclarationCheckers() { private val _basicDeclarationCheckers: MutableSet = mutableSetOf() private val _memberDeclarationCheckers: MutableSet = mutableSetOf() + private val _functionCheckers: MutableSet = mutableSetOf() private val _propertyCheckers: MutableSet = mutableSetOf() private val _regularClassCheckers: MutableSet = mutableSetOf() private val _constructorCheckers: MutableSet = mutableSetOf() @@ -45,6 +48,7 @@ internal class ComposedDeclarationCheckers : DeclarationCheckers() { internal fun register(checkers: DeclarationCheckers) { _basicDeclarationCheckers += checkers.allBasicDeclarationCheckers _memberDeclarationCheckers += checkers.allMemberDeclarationCheckers + _functionCheckers += checkers.allFunctionCheckers _propertyCheckers += checkers.allPropertyCheckers _regularClassCheckers += checkers.allRegularClassCheckers _constructorCheckers += checkers.allConstructorCheckers diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/DeclarationCheckers.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/DeclarationCheckers.kt index 56a62ef5153..f96ece8dbe5 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/DeclarationCheckers.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/DeclarationCheckers.kt @@ -21,6 +21,7 @@ abstract class DeclarationCheckers { open val basicDeclarationCheckers: Set = emptySet() open val memberDeclarationCheckers: Set = emptySet() + open val functionCheckers: Set = emptySet() open val propertyCheckers: Set = emptySet() open val regularClassCheckers: Set = emptySet() open val constructorCheckers: Set = emptySet() @@ -31,8 +32,9 @@ abstract class DeclarationCheckers { @CheckersComponentInternal internal val allBasicDeclarationCheckers: Set get() = basicDeclarationCheckers @CheckersComponentInternal internal val allMemberDeclarationCheckers: Set get() = memberDeclarationCheckers + allBasicDeclarationCheckers + @CheckersComponentInternal internal val allFunctionCheckers: Set get() = functionCheckers + allBasicDeclarationCheckers @CheckersComponentInternal internal val allPropertyCheckers: Set get() = propertyCheckers + allMemberDeclarationCheckers @CheckersComponentInternal internal val allRegularClassCheckers: Set get() = regularClassCheckers + allMemberDeclarationCheckers - @CheckersComponentInternal internal val allConstructorCheckers: Set get() = constructorCheckers + allMemberDeclarationCheckers + @CheckersComponentInternal internal val allConstructorCheckers: Set get() = constructorCheckers + allFunctionCheckers @CheckersComponentInternal internal val allFileCheckers: Set get() = fileCheckers + allBasicDeclarationCheckers } diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerAliases.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerAliases.kt index 4b680e2445c..ef4ca66ed49 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerAliases.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerAliases.kt @@ -13,12 +13,14 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirRegularClass typealias FirBasicDeclarationChecker = FirDeclarationChecker typealias FirMemberDeclarationChecker = FirDeclarationChecker +typealias FirFunctionChecker = FirDeclarationChecker> typealias FirPropertyChecker = FirDeclarationChecker typealias FirRegularClassChecker = FirDeclarationChecker typealias FirConstructorChecker = FirDeclarationChecker diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirFunctionNameChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirFunctionNameChecker.kt new file mode 100644 index 00000000000..63b7a9d3508 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirFunctionNameChecker.kt @@ -0,0 +1,29 @@ +/* + * 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.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.extended.report +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.declarations.FirClass +import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.declarations.FirFunction +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.name.SpecialNames + +object FirFunctionNameChecker : FirFunctionChecker() { + override fun check(declaration: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) { + val source = declaration.source + if (source == null || source.kind is FirFakeSourceElementKind) return + val containingDeclaration = context.containingDeclarations.lastOrNull() + val isNonLocal = containingDeclaration is FirFile || containingDeclaration is FirClass<*> + if (declaration is FirSimpleFunction && declaration.name == SpecialNames.NO_NAME_PROVIDED && isNonLocal) { + reporter.report(source, FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME) + } + } +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/DeclarationCheckersDiagnosticComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/DeclarationCheckersDiagnosticComponent.kt index 513153297fe..a89ec402aa4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/DeclarationCheckersDiagnosticComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/DeclarationCheckersDiagnosticComponent.kt @@ -30,7 +30,7 @@ class DeclarationCheckersDiagnosticComponent( } override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: CheckerContext) { - checkers.memberDeclarationCheckers.check(simpleFunction, data, reporter) + (checkers.memberDeclarationCheckers + checkers.functionCheckers).check(simpleFunction, data, reporter) } override fun visitTypeAlias(typeAlias: FirTypeAlias, data: CheckerContext) { @@ -38,7 +38,7 @@ class DeclarationCheckersDiagnosticComponent( } override fun visitConstructor(constructor: FirConstructor, data: CheckerContext) { - checkers.constructorCheckers.check(constructor, data, reporter) + (checkers.memberDeclarationCheckers + checkers.constructorCheckers).check(constructor, data, reporter) } override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: CheckerContext) { 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 4b3e444d388..a038eb8dd01 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 @@ -54,6 +54,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_CLA import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_CONST_EXPRESSION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_UNDERSCORE @@ -353,6 +354,8 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(NON_ABSTRACT_FUNCTION_WITH_NO_BODY, "Function ''{0}'' without a body must be abstract", DECLARATION_NAME) map.put(PRIVATE_FUNCTION_WITH_NO_BODY, "Function ''{0}'' without body cannot be private", DECLARATION_NAME) + map.put(FUNCTION_DECLARATION_WITH_NO_NAME, "Function declaration must have a name") + // Properties & accessors map.put( ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 9b15b3505e6..c8c56ec913f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -153,6 +153,8 @@ object FirErrors { val NON_ABSTRACT_FUNCTION_WITH_NO_BODY by error1(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val PRIVATE_FUNCTION_WITH_NO_BODY by error1(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) + val FUNCTION_DECLARATION_WITH_NO_NAME by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) + // Properties & accessors val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2(SourceElementPositioningStrategies.MODALITY_MODIFIER) val PRIVATE_PROPERTY_IN_INTERFACE by error0(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt index fd289afbdb5..673eb05c602 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt @@ -28,6 +28,10 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirSealedSupertypeChecker, ) + override val functionCheckers: Set = setOf( + FirFunctionNameChecker, + ) + override val propertyCheckers: Set = setOf( FirInapplicableLateinitChecker, FirDestructuringDeclarationInitializerChecker, diff --git a/compiler/testData/diagnostics/tests/declarationChecks/FunctionWithMissingNames.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/FunctionWithMissingNames.fir.kt index 35f770556d9..2c30dfe864e 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/FunctionWithMissingNames.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/FunctionWithMissingNames.fir.kt @@ -3,18 +3,18 @@ annotation class a interface A interface B -fun () {} -fun A.() {} +fun () {} +fun A.() {} -@a fun () {} -fun @a A.() {} +@a fun () {} +fun @a A.() {} class Outer { - fun () {} - fun B.() {} + fun () {} + fun B.() {} - @a fun () {} - fun @a A.() {} + @a fun () {} + fun @a A.() {} } fun outerFun() { diff --git a/compiler/testData/diagnostics/tests/duplicateJvmSignature/missingNames.fir.kt b/compiler/testData/diagnostics/tests/duplicateJvmSignature/missingNames.fir.kt index 9bf897065b4..9f5dda53c4d 100644 --- a/compiler/testData/diagnostics/tests/duplicateJvmSignature/missingNames.fir.kt +++ b/compiler/testData/diagnostics/tests/duplicateJvmSignature/missingNames.fir.kt @@ -1,9 +1,9 @@ // !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES -fun () { +fun () { } -fun Outer.() { +fun Outer.() { } @@ -30,7 +30,7 @@ annotation class { } class Outer { - fun () { + fun () { } diff --git a/compiler/testData/diagnostics/tests/recovery/namelessInJava.fir.kt b/compiler/testData/diagnostics/tests/recovery/namelessInJava.fir.kt deleted file mode 100644 index 7017eaced2e..00000000000 --- a/compiler/testData/diagnostics/tests/recovery/namelessInJava.fir.kt +++ /dev/null @@ -1,18 +0,0 @@ -// SKIP_JAVAC -// FILE: p/Nameless.java - -package p; - -public class Nameless { - void () {} - int ; -} - -// FILE: k.kt - -import p.* - -class K : Nameless() { - fun () {} - val : Int = 1 -} diff --git a/compiler/testData/diagnostics/tests/recovery/namelessInJava.kt b/compiler/testData/diagnostics/tests/recovery/namelessInJava.kt index 8028e9059db..33c382dbf9d 100644 --- a/compiler/testData/diagnostics/tests/recovery/namelessInJava.kt +++ b/compiler/testData/diagnostics/tests/recovery/namelessInJava.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // SKIP_JAVAC // FILE: p/Nameless.java diff --git a/compiler/testData/diagnostics/tests/recovery/namelessMembers.fir.kt b/compiler/testData/diagnostics/tests/recovery/namelessMembers.fir.kt deleted file mode 100644 index 6bd0aa7f1fe..00000000000 --- a/compiler/testData/diagnostics/tests/recovery/namelessMembers.fir.kt +++ /dev/null @@ -1,17 +0,0 @@ -// !DIAGNOSTICS: -REDECLARATION -DUPLICATE_CLASS_NAMES - -class C { - fun () { - - } - - val : Int = 1 - - class {} - - enum class {} -} - -class C1<in> {} - -class C2(val) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/recovery/namelessMembers.kt b/compiler/testData/diagnostics/tests/recovery/namelessMembers.kt index a11d5649f11..ca24786d62f 100644 --- a/compiler/testData/diagnostics/tests/recovery/namelessMembers.kt +++ b/compiler/testData/diagnostics/tests/recovery/namelessMembers.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -REDECLARATION -DUPLICATE_CLASS_NAMES class C { diff --git a/compiler/testData/diagnostics/tests/recovery/namelessToplevelDeclarations.fir.kt b/compiler/testData/diagnostics/tests/recovery/namelessToplevelDeclarations.fir.kt index 4c13a3703b1..54973f749d1 100644 --- a/compiler/testData/diagnostics/tests/recovery/namelessToplevelDeclarations.fir.kt +++ b/compiler/testData/diagnostics/tests/recovery/namelessToplevelDeclarations.fir.kt @@ -2,7 +2,7 @@ package -fun () { +fun () { }