FIR checker: add support diagnostic: EXPECTED_PRIVATE_DECLARATION

This commit is contained in:
Jinseong Jeon
2021-01-25 12:36:25 -08:00
committed by Mikhail Glukhikh
parent 57c8dd86a0
commit 97241599bf
9 changed files with 32 additions and 15 deletions
@@ -5,6 +5,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.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.extended.report
@@ -19,10 +20,23 @@ import org.jetbrains.kotlin.lexer.KtTokens
internal fun isInsideExpectClass(containingDeclaration: FirRegularClass, context: CheckerContext): Boolean =
containingDeclaration.isExpect || context.containingDeclarations.asReversed().any { it is FirRegularClass && it.isExpect }
internal fun checkExpectFunction(function: FirSimpleFunction, reporter: DiagnosticReporter) {
// 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 checkExpectFunctionHasBody(function: FirSimpleFunction, reporter: DiagnosticReporter) {
val source = function.source ?: return
if (source.kind is FirFakeSourceElementKind) return
if (function.hasBody) {
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)
}
}
@@ -61,10 +61,8 @@ object FirMemberFunctionChecker : FirRegularClassChecker() {
}
}
val isExpect = function.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true
if (isExpect) {
checkExpectFunction(function, reporter)
}
checkExpectFunctionHasBody(function, reporter)
checkPrivateExpectedDeclaration(function, reporter)
}
}
@@ -98,6 +98,8 @@ object FirMemberPropertyChecker : FirRegularClassChecker() {
}
}
}
checkPrivateExpectedDeclaration(property, reporter)
}
private fun checkAccessor(
@@ -35,8 +35,7 @@ object FirTopLevelFunctionChecker : FirFileChecker() {
reporter.report(FirErrors.NON_MEMBER_FUNCTION_NO_BODY.on(source, function))
}
if (isExpect) {
checkExpectFunction(function, reporter)
}
checkExpectFunctionHasBody(function, reporter)
checkPrivateExpectedDeclaration(function, reporter)
}
}
@@ -22,5 +22,6 @@ object FirTopLevelPropertyChecker : FirFileChecker() {
private fun checkProperty(property: FirProperty, reporter: DiagnosticReporter) {
checkPropertyInitializer(null, property, reporter)
checkPrivateExpectedDeclaration(property, reporter)
}
}
@@ -52,6 +52,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ENUM_AS_SUPERTYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ERROR_FROM_JAVA_RESOLUTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_DECLARATION_WITH_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_DELEGATED_PROPERTY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_PRIVATE_DECLARATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_PROPERTY_INITIALIZER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPLICIT_DELEGATION_CALL_REQUIRED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_FUNCTION_RETURN_TYPE
@@ -401,6 +402,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(EXPECTED_DECLARATION_WITH_BODY, "Expected declaration must not have a body")
map.put(EXPECTED_PROPERTY_INITIALIZER, "Expected property cannot have an initializer")
map.put(EXPECTED_DELEGATED_PROPERTY, "Expected property cannot be delegated")
map.put(EXPECTED_PRIVATE_DECLARATION, "Expected declaration cannot be private")
// Destructuring declaration
map.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration")
@@ -193,6 +193,7 @@ object FirErrors {
val EXPECTED_PROPERTY_INITIALIZER by error0<FirSourceElement, KtExpression>()
// TODO: need to cover `by` as well as delegate expression
val EXPECTED_DELEGATED_PROPERTY by error0<FirSourceElement, KtPropertyDelegate>()
val EXPECTED_PRIVATE_DECLARATION by error0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
// Destructuring declaration
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<FirSourceElement, KtDestructuringDeclaration>()
@@ -3,9 +3,9 @@
// FILE: common.kt
expect class A {
private fun foo()
private val bar: String
private fun Int.memExt(): Any
<!EXPECTED_PRIVATE_DECLARATION!>private<!> fun foo()
<!EXPECTED_PRIVATE_DECLARATION!>private<!> val bar: String
<!EXPECTED_PRIVATE_DECLARATION!>private<!> fun Int.memExt(): Any
private class Nested
}
@@ -2,9 +2,9 @@
// MODULE: m1-common
// FILE: common.kt
private expect fun foo()
private expect val bar: String
private expect fun Int.memExt(): Any
<!EXPECTED_PRIVATE_DECLARATION!>private<!> expect fun foo()
<!EXPECTED_PRIVATE_DECLARATION!>private<!> expect val bar: String
<!EXPECTED_PRIVATE_DECLARATION!>private<!> expect fun Int.memExt(): Any
private expect class Foo