FIR: report FUN_INTERFACE_CONSTRUCTOR_REFERENCE on deserialized properly

This fixes KT-46100 for FIR
This commit is contained in:
Mikhail Glukhikh
2021-04-15 08:39:16 +03:00
parent 676e29e96e
commit 51d348d5fa
5 changed files with 13 additions and 10 deletions
@@ -6,17 +6,15 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.hasModifier
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_CONSTRUCTOR_REFERENCE
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.isInterface
import org.jetbrains.kotlin.fir.declarations.isFun
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.lexer.KtTokens
object FirFunInterfaceConstructorReferenceChecker : FirQualifiedAccessChecker() {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -26,11 +24,10 @@ object FirFunInterfaceConstructorReferenceChecker : FirQualifiedAccessChecker()
val referredDeclaration = reference.resolvedSymbol.fir
if (referredDeclaration is FirSimpleFunction &&
referredDeclaration.returnTypeRef.toRegularClass(context.session).isFunInterface()
referredDeclaration.origin == FirDeclarationOrigin.SamConstructor &&
referredDeclaration.returnTypeRef.toRegularClass(context.session)?.isFun == true
) {
reporter.reportOn(reference.source, FUN_INTERFACE_CONSTRUCTOR_REFERENCE, context)
}
}
private fun FirRegularClass?.isFunInterface() = this != null && isInterface && hasModifier(KtTokens.FUN_KEYWORD)
}
@@ -689,7 +689,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(CANNOT_INFER_PARAMETER_TYPE, "cannot infer a type for this parameter. Please specify it explicitly.")
// Fun interfaces
map.put(FUN_INTERFACE_CONSTRUCTOR_REFERENCE, "Functional interface constructor references are prohibited")
map.put(FUN_INTERFACE_CONSTRUCTOR_REFERENCE, "Functional/SAM interface constructor references are prohibited")
// Properties & accessors
map.put(
@@ -81,6 +81,7 @@ inline val FirMemberDeclaration.isConst: Boolean get() = status.isConst
inline val FirMemberDeclaration.isLateInit: Boolean get() = status.isLateInit
inline val FirMemberDeclaration.isFromSealedClass: Boolean get() = status.isFromSealedClass
inline val FirMemberDeclaration.isFromEnumClass: Boolean get() = status.isFromEnumClass
inline val FirMemberDeclaration.isFun: Boolean get() = status.isFun
inline val FirFunction<*>.hasBody get() = body != null
@@ -0,0 +1,7 @@
fun interface Foo {
fun run()
}
val x = ::<!FUN_INTERFACE_CONSTRUCTOR_REFERENCE!>Foo<!>
val y = Foo { }
val z = ::<!FUN_INTERFACE_CONSTRUCTOR_REFERENCE!>Runnable<!>
@@ -1,5 +1,3 @@
// FIR_IDENTICAL
fun interface Foo {
fun run()
}