FIR: inroduce FirFunInterfaceConstructorReferenceChecker
This commit is contained in:
+5
@@ -2855,6 +2855,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/samConstructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/samConstructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funInterfaceConstructorReference.kt")
|
||||||
|
public void testFunInterfaceConstructorReference() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/samConstructors/funInterfaceConstructorReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("genericSam.kt")
|
@TestMetadata("genericSam.kt")
|
||||||
public void testGenericSam() throws Exception {
|
public void testGenericSam() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/samConstructors/genericSam.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/samConstructors/genericSam.kt");
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
FILE: funInterfaceConstructorReference.kt
|
||||||
|
public abstract interface Test : R|kotlin/Any| {
|
||||||
|
public abstract fun foo(): R|kotlin/Unit|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final val f: R|kotlin/reflect/KFunction1<kotlin/Function0<kotlin/Unit>, Test>| = ::R|/Test|
|
||||||
|
public get(): R|kotlin/reflect/KFunction1<kotlin/Function0<kotlin/Unit>, Test>|
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun interface Test {
|
||||||
|
fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
val f = ::<!FUN_INTERFACE_CONSTRUCTOR_REFERENCE!>Test<!>
|
||||||
+6
@@ -3227,6 +3227,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/samConstructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/samConstructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorReference.kt")
|
||||||
|
public void testFunInterfaceConstructorReference() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/samConstructors/funInterfaceConstructorReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("genericSam.kt")
|
@TestMetadata("genericSam.kt")
|
||||||
public void testGenericSam() throws Exception {
|
public void testGenericSam() throws Exception {
|
||||||
|
|||||||
+6
@@ -3264,6 +3264,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/samConstructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/samConstructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorReference.kt")
|
||||||
|
public void testFunInterfaceConstructorReference() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/samConstructors/funInterfaceConstructorReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("genericSam.kt")
|
@TestMetadata("genericSam.kt")
|
||||||
public void testGenericSam() throws Exception {
|
public void testGenericSam() throws Exception {
|
||||||
|
|||||||
+4
@@ -479,6 +479,10 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
|||||||
val VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION by error<FirSourceElement, KtParameter>()
|
val VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION by error<FirSourceElement, KtParameter>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val FUN_INTERFACES by object : DiagnosticGroup("Fun interfaces") {
|
||||||
|
val FUN_INTERFACE_CONSTRUCTOR_REFERENCE by error<FirSourceElement, KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED)
|
||||||
|
}
|
||||||
|
|
||||||
val PROPERTIES_AND_ACCESSORS by object : DiagnosticGroup("Properties & accessors") {
|
val PROPERTIES_AND_ACCESSORS by object : DiagnosticGroup("Properties & accessors") {
|
||||||
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER) {
|
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER) {
|
||||||
parameter<FirMemberDeclaration>("property")
|
parameter<FirMemberDeclaration>("property")
|
||||||
|
|||||||
@@ -296,6 +296,9 @@ object FirErrors {
|
|||||||
val FORBIDDEN_VARARG_PARAMETER_TYPE by error1<FirSourceElement, KtParameter, ConeKotlinType>(SourceElementPositioningStrategies.PARAMETER_VARARG_MODIFIER)
|
val FORBIDDEN_VARARG_PARAMETER_TYPE by error1<FirSourceElement, KtParameter, ConeKotlinType>(SourceElementPositioningStrategies.PARAMETER_VARARG_MODIFIER)
|
||||||
val VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION by error0<FirSourceElement, KtParameter>()
|
val VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION by error0<FirSourceElement, KtParameter>()
|
||||||
|
|
||||||
|
// Fun interfaces
|
||||||
|
val FUN_INTERFACE_CONSTRUCTOR_REFERENCE by error0<FirSourceElement, KtExpression>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
|
|
||||||
// Properties & accessors
|
// Properties & accessors
|
||||||
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<FirSourceElement, KtModifierListOwner, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
|
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<FirSourceElement, KtModifierListOwner, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
|
||||||
val PRIVATE_PROPERTY_IN_INTERFACE by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
val PRIVATE_PROPERTY_IN_INTERFACE by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.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.FirSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.isInterface
|
||||||
|
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) {
|
||||||
|
if (expression !is FirCallableReferenceAccess || expression is FirGetClassCall) return
|
||||||
|
|
||||||
|
val reference = expression.calleeReference as? FirResolvedNamedReference ?: return
|
||||||
|
val referredDeclaration = reference.resolvedSymbol.fir
|
||||||
|
|
||||||
|
if (referredDeclaration is FirSimpleFunction &&
|
||||||
|
referredDeclaration.returnTypeRef.toRegularClass(context.session).isFunInterface()
|
||||||
|
) {
|
||||||
|
reporter.reportOn(reference.source, FUN_INTERFACE_CONSTRUCTOR_REFERENCE, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirRegularClass?.isFunInterface() = this != null && isInterface && hasModifier(KtTokens.FUN_KEYWORD)
|
||||||
|
}
|
||||||
+4
@@ -107,6 +107,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERT
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FINAL_UPPER_BOUND
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FINAL_UPPER_BOUND
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_CONSTRUCTOR_REFERENCE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.GENERIC_THROWABLE_SUBCLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.GENERIC_THROWABLE_SUBCLASS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN
|
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_CONST_EXPRESSION
|
||||||
@@ -685,6 +686,9 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
map.put(FORBIDDEN_VARARG_PARAMETER_TYPE, "Forbidden vararg parameter type: {0}", RENDER_TYPE)
|
map.put(FORBIDDEN_VARARG_PARAMETER_TYPE, "Forbidden vararg parameter type: {0}", RENDER_TYPE)
|
||||||
map.put(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION, "A type annotation is required on a value parameter")
|
map.put(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION, "A type annotation is required on a value parameter")
|
||||||
|
|
||||||
|
// Fun interfaces
|
||||||
|
map.put(FUN_INTERFACE_CONSTRUCTOR_REFERENCE, "Functional interface constructor references are prohibited")
|
||||||
|
|
||||||
// Properties & accessors
|
// Properties & accessors
|
||||||
map.put(
|
map.put(
|
||||||
ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS,
|
ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS,
|
||||||
|
|||||||
+1
@@ -28,6 +28,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
FirTypeParameterInQualifiedAccessChecker,
|
FirTypeParameterInQualifiedAccessChecker,
|
||||||
FirSealedClassConstructorCallChecker,
|
FirSealedClassConstructorCallChecker,
|
||||||
FirUninitializedEnumChecker,
|
FirUninitializedEnumChecker,
|
||||||
|
FirFunInterfaceConstructorReferenceChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val functionCallCheckers: Set<FirFunctionCallChecker> = setOf(
|
override val functionCallCheckers: Set<FirFunctionCallChecker> = setOf(
|
||||||
|
|||||||
Vendored
-7
@@ -1,7 +0,0 @@
|
|||||||
fun interface Foo {
|
|
||||||
fun run()
|
|
||||||
}
|
|
||||||
|
|
||||||
val x = ::Foo
|
|
||||||
val y = Foo { }
|
|
||||||
val z = ::Runnable
|
|
||||||
Vendored
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
|
||||||
fun interface Foo {
|
fun interface Foo {
|
||||||
fun run()
|
fun run()
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -1338,6 +1338,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.FUN_INTERFACE_CONSTRUCTOR_REFERENCE) { firDiagnostic ->
|
||||||
|
FunInterfaceConstructorReferenceImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS) { firDiagnostic ->
|
add(FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS) { firDiagnostic ->
|
||||||
AbstractPropertyInNonAbstractClassImpl(
|
AbstractPropertyInNonAbstractClassImpl(
|
||||||
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration),
|
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration),
|
||||||
|
|||||||
+4
@@ -949,6 +949,10 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = ValueParameterWithNoTypeAnnotation::class
|
override val diagnosticClass get() = ValueParameterWithNoTypeAnnotation::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class FunInterfaceConstructorReference : KtFirDiagnostic<KtExpression>() {
|
||||||
|
override val diagnosticClass get() = FunInterfaceConstructorReference::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class AbstractPropertyInNonAbstractClass : KtFirDiagnostic<KtModifierListOwner>() {
|
abstract class AbstractPropertyInNonAbstractClass : KtFirDiagnostic<KtModifierListOwner>() {
|
||||||
override val diagnosticClass get() = AbstractPropertyInNonAbstractClass::class
|
override val diagnosticClass get() = AbstractPropertyInNonAbstractClass::class
|
||||||
abstract val property: KtSymbol
|
abstract val property: KtSymbol
|
||||||
|
|||||||
+7
@@ -1529,6 +1529,13 @@ internal class ValueParameterWithNoTypeAnnotationImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class FunInterfaceConstructorReferenceImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.FunInterfaceConstructorReference(), KtAbstractFirDiagnostic<KtExpression> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class AbstractPropertyInNonAbstractClassImpl(
|
internal class AbstractPropertyInNonAbstractClassImpl(
|
||||||
override val property: KtSymbol,
|
override val property: KtSymbol,
|
||||||
override val containingClass: KtSymbol,
|
override val containingClass: KtSymbol,
|
||||||
|
|||||||
Reference in New Issue
Block a user