FIR: add checker for local extension properties
^KT-56013 Fixed
This commit is contained in:
committed by
Space Team
parent
9873fe84f2
commit
c1420794b4
+6
@@ -3043,6 +3043,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.LOCAL_EXTENSION_PROPERTY) { firDiagnostic ->
|
||||||
|
LocalExtensionPropertyImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.EXPECTED_DECLARATION_WITH_BODY) { firDiagnostic ->
|
add(FirErrors.EXPECTED_DECLARATION_WITH_BODY) { firDiagnostic ->
|
||||||
ExpectedDeclarationWithBodyImpl(
|
ExpectedDeclarationWithBodyImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+4
@@ -2145,6 +2145,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val declaration: KtSymbol
|
abstract val declaration: KtSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class LocalExtensionProperty : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = LocalExtensionProperty::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ExpectedDeclarationWithBody : KtFirDiagnostic<KtDeclaration>() {
|
abstract class ExpectedDeclarationWithBody : KtFirDiagnostic<KtDeclaration>() {
|
||||||
override val diagnosticClass get() = ExpectedDeclarationWithBody::class
|
override val diagnosticClass get() = ExpectedDeclarationWithBody::class
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -2586,6 +2586,11 @@ internal class LateinitIntrinsicCallOnNonAccessiblePropertyImpl(
|
|||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
) : KtFirDiagnostic.LateinitIntrinsicCallOnNonAccessibleProperty(), KtAbstractFirDiagnostic<PsiElement>
|
) : KtFirDiagnostic.LateinitIntrinsicCallOnNonAccessibleProperty(), KtAbstractFirDiagnostic<PsiElement>
|
||||||
|
|
||||||
|
internal class LocalExtensionPropertyImpl(
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.LocalExtensionProperty(), KtAbstractFirDiagnostic<PsiElement>
|
||||||
|
|
||||||
internal class ExpectedDeclarationWithBodyImpl(
|
internal class ExpectedDeclarationWithBodyImpl(
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
|
|||||||
+6
@@ -24840,6 +24840,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt");
|
runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localPropertyExtensions.kt")
|
||||||
|
public void testLocalPropertyExtensions() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("protectedGetterWithPublicSetter.kt")
|
@TestMetadata("protectedGetterWithPublicSetter.kt")
|
||||||
public void testProtectedGetterWithPublicSetter() throws Exception {
|
public void testProtectedGetterWithPublicSetter() throws Exception {
|
||||||
|
|||||||
+6
@@ -24846,6 +24846,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt");
|
runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localPropertyExtensions.kt")
|
||||||
|
public void testLocalPropertyExtensions() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("protectedGetterWithPublicSetter.kt")
|
@TestMetadata("protectedGetterWithPublicSetter.kt")
|
||||||
public void testProtectedGetterWithPublicSetter() throws Exception {
|
public void testProtectedGetterWithPublicSetter() throws Exception {
|
||||||
|
|||||||
+6
@@ -24840,6 +24840,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt");
|
runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localPropertyExtensions.kt")
|
||||||
|
public void testLocalPropertyExtensions() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("protectedGetterWithPublicSetter.kt")
|
@TestMetadata("protectedGetterWithPublicSetter.kt")
|
||||||
public void testProtectedGetterWithPublicSetter() throws Exception {
|
public void testProtectedGetterWithPublicSetter() throws Exception {
|
||||||
|
|||||||
+2
@@ -1035,6 +1035,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY by error<PsiElement>() {
|
val LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY by error<PsiElement>() {
|
||||||
parameter<Symbol>("declaration")
|
parameter<Symbol>("declaration")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val LOCAL_EXTENSION_PROPERTY by error<PsiElement>()
|
||||||
}
|
}
|
||||||
|
|
||||||
val MPP_PROJECTS by object : DiagnosticGroup("Multi-platform projects") {
|
val MPP_PROJECTS by object : DiagnosticGroup("Multi-platform projects") {
|
||||||
|
|||||||
@@ -565,6 +565,7 @@ object FirErrors {
|
|||||||
val LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT by error0<PsiElement>()
|
val LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT by error0<PsiElement>()
|
||||||
val LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION by error0<PsiElement>()
|
val LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION by error0<PsiElement>()
|
||||||
val LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY by error1<PsiElement, FirBasedSymbol<*>>()
|
val LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY by error1<PsiElement, FirBasedSymbol<*>>()
|
||||||
|
val LOCAL_EXTENSION_PROPERTY by error0<PsiElement>()
|
||||||
|
|
||||||
// Multi-platform projects
|
// Multi-platform projects
|
||||||
val EXPECTED_DECLARATION_WITH_BODY by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
val EXPECTED_DECLARATION_WITH_BODY by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
|
|||||||
+1
@@ -72,6 +72,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
FirLocalVariableTypeParametersSyntaxChecker,
|
FirLocalVariableTypeParametersSyntaxChecker,
|
||||||
FirDelegateUsesExtensionPropertyTypeParameterChecker,
|
FirDelegateUsesExtensionPropertyTypeParameterChecker,
|
||||||
FirTopLevelPropertiesChecker,
|
FirTopLevelPropertiesChecker,
|
||||||
|
FirLocalExtensionPropertyChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val backingFieldCheckers: Set<FirBackingFieldChecker>
|
override val backingFieldCheckers: Set<FirBackingFieldChecker>
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.declaration
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isExtension
|
||||||
|
|
||||||
|
object FirLocalExtensionPropertyChecker : FirPropertyChecker() {
|
||||||
|
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
if (declaration.isLocal && declaration.isExtension) {
|
||||||
|
reporter.reportOn(declaration.receiverParameter?.source, FirErrors.LOCAL_EXTENSION_PROPERTY, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -300,6 +300,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_NULLABLE
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_PROPERTY_FIELD_DECLARATION_WITH_INITIALIZER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_PROPERTY_FIELD_DECLARATION_WITH_INITIALIZER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LEAKED_IN_PLACE_LAMBDA
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LEAKED_IN_PLACE_LAMBDA
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_ANNOTATION_CLASS_ERROR
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_ANNOTATION_CLASS_ERROR
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_EXTENSION_PROPERTY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_INTERFACE_NOT_ALLOWED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_INTERFACE_NOT_ALLOWED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_OBJECT_NOT_ALLOWED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_OBJECT_NOT_ALLOWED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_VARIABLE_WITH_TYPE_PARAMETERS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_VARIABLE_WITH_TYPE_PARAMETERS
|
||||||
@@ -1668,6 +1669,8 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
map.put(LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION, "This declaration can not be used inside an inline function")
|
map.put(LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION, "This declaration can not be used inside an inline function")
|
||||||
map.put(LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY, "Backing field of ''{0}'' is not accessible at this point", SYMBOL)
|
map.put(LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY, "Backing field of ''{0}'' is not accessible at this point", SYMBOL)
|
||||||
|
|
||||||
|
map.put(LOCAL_EXTENSION_PROPERTY, "Local extension properties are not allowed")
|
||||||
|
|
||||||
map.put(CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, "Const 'val' are only allowed on top level, in named objects, or in companion objects")
|
map.put(CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, "Const 'val' are only allowed on top level, in named objects, or in companion objects")
|
||||||
map.put(CONST_VAL_WITH_GETTER, "Const 'val' should not have a getter")
|
map.put(CONST_VAL_WITH_GETTER, "Const 'val' should not have a getter")
|
||||||
map.put(CONST_VAL_WITH_DELEGATE, "Const 'val' should not have a delegate")
|
map.put(CONST_VAL_WITH_DELEGATE, "Const 'val' should not have a delegate")
|
||||||
|
|||||||
+2
-1
@@ -1198,6 +1198,8 @@ class DeclarationsConverter(
|
|||||||
returnTypeRef = returnType
|
returnTypeRef = returnType
|
||||||
name = propertyName
|
name = propertyName
|
||||||
this.isVar = isVar
|
this.isVar = isVar
|
||||||
|
|
||||||
|
receiverParameter = receiverType?.convertToReceiverParameter()
|
||||||
initializer = propertyInitializer
|
initializer = propertyInitializer
|
||||||
|
|
||||||
//probably can do this for delegateExpression itself
|
//probably can do this for delegateExpression itself
|
||||||
@@ -1234,7 +1236,6 @@ class DeclarationsConverter(
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
this.isLocal = false
|
this.isLocal = false
|
||||||
receiverParameter = receiverType?.convertToReceiverParameter()
|
|
||||||
|
|
||||||
dispatchReceiverType = currentDispatchReceiverType()
|
dispatchReceiverType = currentDispatchReceiverType()
|
||||||
withCapturedTypeParameters(true, propertySource, firTypeParameters) {
|
withCapturedTypeParameters(true, propertySource, firTypeParameters) {
|
||||||
|
|||||||
@@ -1730,6 +1730,7 @@ open class RawFirBuilder(
|
|||||||
name = propertyName
|
name = propertyName
|
||||||
this.isVar = isVar
|
this.isVar = isVar
|
||||||
|
|
||||||
|
receiverParameter = receiverTypeReference.convertSafe<FirTypeRef>()?.convertToReceiverParameter()
|
||||||
initializer = propertyInitializer
|
initializer = propertyInitializer
|
||||||
|
|
||||||
val propertyAnnotations = mutableListOf<FirAnnotationCall>()
|
val propertyAnnotations = mutableListOf<FirAnnotationCall>()
|
||||||
@@ -1772,7 +1773,6 @@ open class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isLocal = false
|
isLocal = false
|
||||||
receiverParameter = receiverTypeReference.convertSafe<FirTypeRef>()?.convertToReceiverParameter()
|
|
||||||
symbol = FirPropertySymbol(callableIdForName(propertyName))
|
symbol = FirPropertySymbol(callableIdForName(propertyName))
|
||||||
dispatchReceiverType = currentDispatchReceiverType()
|
dispatchReceiverType = currentDispatchReceiverType()
|
||||||
extractTypeParametersTo(this, symbol)
|
extractTypeParametersTo(this, symbol)
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// SKIP_TXT
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val <!LOCAL_EXTENSION_PROPERTY!>String<!>.count = 42
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// SKIP_TXT
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val <!DEBUG_INFO_MISSING_UNRESOLVED, LOCAL_EXTENSION_PROPERTY!>String<!>.count = 42
|
||||||
|
}
|
||||||
Generated
+6
@@ -24846,6 +24846,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt");
|
runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localPropertyExtensions.kt")
|
||||||
|
public void testLocalPropertyExtensions() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("protectedGetterWithPublicSetter.kt")
|
@TestMetadata("protectedGetterWithPublicSetter.kt")
|
||||||
public void testProtectedGetterWithPublicSetter() throws Exception {
|
public void testProtectedGetterWithPublicSetter() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user