diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt index b4bdcd6c01d..79ca69ecef9 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.fir.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.FirSourceElement 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 @@ -21,27 +21,23 @@ internal fun isInsideExpectClass(containingDeclaration: FirRegularClass, context containingDeclaration.isExpect || context.containingDeclarations.asReversed().any { it is FirRegularClass && it.isExpect } // TODO: check class too -internal fun checkPrivateExpectedDeclaration(declaration: FirMemberDeclaration, reporter: DiagnosticReporter) { - val source = declaration.source ?: return - if (source.kind is FirFakeSourceElementKind) return - val modifierList = with(FirModifierList) { source.getModifierList() } - val isExpect = declaration.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true - if (isExpect && Visibilities.isPrivate(declaration.visibility)) { - reporter.report(source, FirErrors.EXPECTED_PRIVATE_DECLARATION) +internal fun checkExpectDeclarationVisibilityAndBody( + declaration: FirMemberDeclaration, + source: FirSourceElement, + modifierList: FirModifierList?, + reporter: DiagnosticReporter +) { + if (declaration.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true) { + if (Visibilities.isPrivate(declaration.visibility)) { + reporter.report(source, FirErrors.EXPECTED_PRIVATE_DECLARATION) + } + if (declaration is FirSimpleFunction && declaration.hasBody) { + reporter.report(source, FirErrors.EXPECTED_DECLARATION_WITH_BODY) + } } } -internal fun checkExpectFunctionHasBody(function: FirSimpleFunction, reporter: DiagnosticReporter) { - val source = function.source ?: return - if (source.kind is FirFakeSourceElementKind) return - val modifierList = with(FirModifierList) { source.getModifierList() } - val isExpect = function.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true - if (isExpect && function.hasBody) { - reporter.report(source, FirErrors.EXPECTED_DECLARATION_WITH_BODY) - } -} - -fun checkPropertyInitializer( +internal fun checkPropertyInitializer( containingClass: FirRegularClass?, property: FirProperty, reporter: DiagnosticReporter diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberFunctionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberFunctionChecker.kt index 7d34523465e..abf01537ef5 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberFunctionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberFunctionChecker.kt @@ -61,8 +61,7 @@ object FirMemberFunctionChecker : FirRegularClassChecker() { } } - checkExpectFunctionHasBody(function, reporter) - checkPrivateExpectedDeclaration(function, reporter) + checkExpectDeclarationVisibilityAndBody(function, source, modifierList, reporter) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertyChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertyChecker.kt index 04ed7eba00f..bf3db33af6c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertyChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertyChecker.kt @@ -65,7 +65,7 @@ object FirMemberPropertyChecker : FirRegularClassChecker() { reporter.report(it, FirErrors.ABSTRACT_DELEGATED_PROPERTY) } - checkAccessor(property.getter, property.delegate) { src, symbol -> + checkAccessor(property.getter, property.delegate) { src, _ -> reporter.report(src, FirErrors.ABSTRACT_PROPERTY_WITH_GETTER) } checkAccessor(property.setter, property.delegate) { src, symbol -> @@ -99,7 +99,7 @@ object FirMemberPropertyChecker : FirRegularClassChecker() { } } - checkPrivateExpectedDeclaration(property, reporter) + checkExpectDeclarationVisibilityAndBody(property, source, modifierList, reporter) } private fun checkAccessor( @@ -113,5 +113,4 @@ object FirMemberPropertyChecker : FirRegularClassChecker() { } } } - } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionChecker.kt index 4630b3d471e..67be9cc6bed 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionChecker.kt @@ -28,14 +28,13 @@ object FirTopLevelFunctionChecker : FirFileChecker() { // If multiple (potentially conflicting) modality modifiers are specified, not all modifiers are recorded at `status`. // So, our source of truth should be the full modifier list retrieved from the source. val modifierList = with(FirModifierList) { source.getModifierList() } - val hasAbstractModifier = modifierList?.modifiers?.any { it.token == KtTokens.ABSTRACT_KEYWORD } == true - val isExternal = function.isExternal || modifierList?.modifiers?.any { it.token == KtTokens.EXTERNAL_KEYWORD } == true + if (modifierList?.modifiers?.any { it.token == KtTokens.ABSTRACT_KEYWORD } == true) return + if (function.isExternal || modifierList?.modifiers?.any { it.token == KtTokens.EXTERNAL_KEYWORD } == true) return val isExpect = function.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true - if (!function.hasBody && !hasAbstractModifier && !isExternal && !isExpect) { + if (!function.hasBody && !isExpect) { reporter.report(FirErrors.NON_MEMBER_FUNCTION_NO_BODY.on(source, function)) } - checkExpectFunctionHasBody(function, reporter) - checkPrivateExpectedDeclaration(function, reporter) + checkExpectDeclarationVisibilityAndBody(function, source, modifierList, reporter) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertyChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertyChecker.kt index cf0c09e9d44..1e3d5d99ee1 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertyChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertyChecker.kt @@ -5,6 +5,7 @@ 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.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.declarations.FirFile @@ -21,7 +22,11 @@ object FirTopLevelPropertyChecker : FirFileChecker() { } private fun checkProperty(property: FirProperty, reporter: DiagnosticReporter) { + val source = property.source ?: return + if (source.kind is FirFakeSourceElementKind) return + val modifierList = with(FirModifierList) { source.getModifierList() } + checkPropertyInitializer(null, property, reporter) - checkPrivateExpectedDeclaration(property, reporter) + checkExpectDeclarationVisibilityAndBody(property, source, modifierList, reporter) } }