FIR checker: add diagnostic EXPECTED_DECLARATION_WITH_BODY
This commit is contained in:
committed by
Mikhail Glukhikh
parent
9341ca3004
commit
f9378a3ab7
+14
@@ -5,10 +5,24 @@
|
||||
|
||||
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.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.hasBody
|
||||
import org.jetbrains.kotlin.fir.declarations.isExpect
|
||||
|
||||
// Note that the class that contains the currently visiting declaration will *not* be in the context's containing declarations *yet*.
|
||||
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) {
|
||||
val source = function.source ?: return
|
||||
if (source.kind is FirFakeSourceElementKind) return
|
||||
if (function.hasBody) {
|
||||
reporter.report(source, FirErrors.EXPECTED_DECLARATION_WITH_BODY)
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -60,6 +60,11 @@ object FirMemberFunctionChecker : FirRegularClassChecker() {
|
||||
reporter.report(FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(source, function))
|
||||
}
|
||||
}
|
||||
|
||||
val isExpect = function.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true
|
||||
if (isExpect) {
|
||||
checkExpectFunction(function, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-1
@@ -7,7 +7,6 @@ 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.*
|
||||
@@ -35,5 +34,9 @@ object FirTopLevelFunctionChecker : FirFileChecker() {
|
||||
if (!function.hasBody && !hasAbstractModifier && !isExternal && !isExpect) {
|
||||
reporter.report(FirErrors.NON_MEMBER_FUNCTION_NO_BODY.on(source, function))
|
||||
}
|
||||
|
||||
if (isExpect) {
|
||||
checkExpectFunction(function, reporter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -50,6 +50,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DESERIALIZATION_E
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EMPTY_RANGE
|
||||
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.EXPLICIT_DELEGATION_CALL_REQUIRED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_FUNCTION_RETURN_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PARAMETER_TYPE
|
||||
@@ -394,6 +395,9 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
map.put(PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY, "Private setters are not allowed for abstract properties")
|
||||
map.put(PRIVATE_SETTER_FOR_OPEN_PROPERTY, "Private setters are not allowed for open properties")
|
||||
|
||||
// Multi-platform projects
|
||||
map.put(EXPECTED_DECLARATION_WITH_BODY, "Expected declaration must not have a body")
|
||||
|
||||
// Destructuring declaration
|
||||
map.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration")
|
||||
map.put(
|
||||
|
||||
@@ -180,6 +180,9 @@ object FirErrors {
|
||||
val PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY by error0<FirSourceElement, PsiElement>()
|
||||
val PRIVATE_SETTER_FOR_OPEN_PROPERTY by error0<FirSourceElement, PsiElement>()
|
||||
|
||||
// Multi-platform projects
|
||||
val EXPECTED_DECLARATION_WITH_BODY by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||
|
||||
// Destructuring declaration
|
||||
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<FirSourceElement, KtDestructuringDeclaration>()
|
||||
val COMPONENT_FUNCTION_MISSING by error2<FirSourceElement, PsiElement, Name, FirTypeRef>()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
expect interface My {
|
||||
open fun bar()
|
||||
open fun bas() {}
|
||||
<!EXPECTED_DECLARATION_WITH_BODY!>open fun bas()<!> {}
|
||||
<!REDUNDANT_MODIFIER!>open<!> abstract fun bat(): Int
|
||||
|
||||
fun foo()
|
||||
|
||||
Vendored
+1
-1
@@ -21,7 +21,7 @@ expect class Foo(
|
||||
get() = "no"
|
||||
set(value) {}
|
||||
|
||||
fun functionWithBody(x: Int): Int {
|
||||
<!EXPECTED_DECLARATION_WITH_BODY!>fun functionWithBody(x: Int): Int<!> {
|
||||
return x + 1
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
-9
@@ -1,9 +0,0 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>expect fun foo()<!>
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>expect fun foo()<!> {}
|
||||
|
||||
expect fun bar() {}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
Reference in New Issue
Block a user