[FIR] Add FirConstValWithGetterOrDelegateChecker

This commit is contained in:
Br0mm
2021-03-09 18:36:25 +03:00
committed by TeamCityServer
parent 93f711e2b8
commit 75e4c74256
15 changed files with 129 additions and 19 deletions
@@ -920,6 +920,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
public void testConstValNotTopLevelOrObject() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/constVal/constValNotTopLevelOrObject.kt");
}
@TestMetadata("constValWithGetterOrDelegate.kt")
public void testConstValWithGetterOrDelegate() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/constVal/constValWithGetterOrDelegate.kt");
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/constructors")
@@ -0,0 +1,33 @@
FILE: constValWithGetterOrDelegate.kt
public final const val f: R|kotlin/Int| = Int(24)
public get(): R|kotlin/Int|
public final const val l: R|kotlin/Int| = Int(3)
public get(): R|kotlin/Int|
public final const val k: R|kotlin/Int|
public get(): R|kotlin/Int|
public final const val t: R|kotlin/Int|
public get(): R|kotlin/Int| {
^ Int(24)
}
public final class Test : R|kotlin/Any| {
public constructor(): R|Test| {
super<R|kotlin/Any|>()
}
public final operator fun getValue(nothing: R|kotlin/Nothing?|, property: R|kotlin/reflect/KProperty<*>|): R|kotlin/Int| {
^getValue Int(123)
}
}
public final const val delegated: R|kotlin/Int|by R|/Test.Test|()
public get(): R|kotlin/Int| {
^ D|/delegated|.R|/Test.getValue|(Null(null), ::R|/delegated|)
}
public final const val e: R|kotlin/Boolean|
public get(): R|kotlin/Boolean| {
^ Boolean(false)
}
public final const val property: R|kotlin/String| = String(123)
public get(): R|kotlin/String| {
^ F|/property|.R|kotlin/String.plus|(String( 123 123))
}
@@ -0,0 +1,26 @@
import kotlin.reflect.KProperty
const val f = 24
const val l = 3
<!CONST_VAL_WITH_GETTER!>get<!>
<!MUST_BE_INITIALIZED!>const val k: Int<!>
<!CONST_VAL_WITH_GETTER!>get<!>
const val t: Int
<!CONST_VAL_WITH_GETTER!>get() = 24<!>
class Test {
operator fun getValue(nothing: Nothing?, property: KProperty<*>): Int {
return 123
}
}
const val delegated: Int by <!CONST_VAL_WITH_DELEGATE!>Test()<!>
const val e: Boolean
<!CONST_VAL_WITH_GETTER!>get() = false<!>
const val property: String = "123"
<!CONST_VAL_WITH_GETTER!>get() = field + " 123 123"<!>
@@ -1062,6 +1062,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
public void testConstValNotTopLevelOrObject() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/constVal/constValNotTopLevelOrObject.kt");
}
@Test
@TestMetadata("constValWithGetterOrDelegate.kt")
public void testConstValWithGetterOrDelegate() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/constVal/constValWithGetterOrDelegate.kt");
}
}
@Nested
@@ -1071,6 +1071,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
public void testConstValNotTopLevelOrObject() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/constVal/constValNotTopLevelOrObject.kt");
}
@Test
@TestMetadata("constValWithGetterOrDelegate.kt")
public void testConstValWithGetterOrDelegate() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/constVal/constValWithGetterOrDelegate.kt");
}
}
@Nested
@@ -391,6 +391,8 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val EXPECTED_PRIVATE_DECLARATION by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
val VAL_WITH_SETTER by error<FirSourceElement, KtPropertyAccessor>()
val CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT by error<FirSourceElement, KtProperty>(PositioningStrategy.CONST_MODIFIER)
val CONST_VAL_WITH_GETTER by error<FirSourceElement, KtProperty>()
val CONST_VAL_WITH_DELEGATE by error<FirSourceElement, KtPropertyDelegate>()
}
val MPP_PROJECTS by object : DiagnosticGroup("Multi-platform projects") {
@@ -259,6 +259,8 @@ object FirErrors {
val EXPECTED_PRIVATE_DECLARATION by error0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val VAL_WITH_SETTER by error0<FirSourceElement, KtPropertyAccessor>()
val CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.CONST_MODIFIER)
val CONST_VAL_WITH_GETTER by error0<FirSourceElement, KtProperty>()
val CONST_VAL_WITH_DELEGATE by error0<FirSourceElement, KtPropertyDelegate>()
// Multi-platform projects
val EXPECTED_DECLARATION_WITH_BODY by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
@@ -31,9 +32,15 @@ object FirConstPropertyChecker : FirPropertyChecker() {
reporter.reportOn(declaration.source, FirErrors.CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, context)
}
if (declaration.getter?.source?.kind !is FirFakeSourceElementKind) {
reporter.reportOn(declaration.getter?.source, FirErrors.CONST_VAL_WITH_GETTER, context)
}
if (declaration.delegate != null) {
reporter.reportOn(declaration.delegate?.source, FirErrors.CONST_VAL_WITH_DELEGATE, context)
}
// TODO: Implement checkers for these errors (see ConstModifierChecker in FE1.0):
// - CONST_VAL_WITH_DELEGATE
// - CONST_VAL_WITH_GETTER
// - TYPE_CANT_BE_USED_FOR_CONST_VAL
// - CONST_VAL_WITHOUT_INITIALIZER
// - CONST_VAL_WITH_NON_CONST_INITIALIZER
@@ -1,12 +0,0 @@
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNUSED_PARAMETER
class Foo<K>
fun <T> getFoo(value: T) = null as Foo<out Foo<T>>
fun <R> takeLambda(block: () -> R) {}
fun main(x: Int) {
takeLambda {
getFoo(x)
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNUSED_PARAMETER
class Foo<K>
@@ -38,14 +38,14 @@ object D : C() {
}
}
const val delegated: Int by Delegate()
const val delegated: Int by <!CONST_VAL_WITH_DELEGATE!>Delegate()<!>
const val withGetter: Int
get() = 13
<!CONST_VAL_WITH_GETTER!>get() = 13<!>
const val withExplicitDefaultGetter: Int = 1
get
<!CONST_VAL_WITH_GETTER!>get<!>
fun foo(): Int {
const val local: Int = 14
@@ -68,7 +68,7 @@ class Outer {
}
const val defaultGetter = 19
get
<!CONST_VAL_WITH_GETTER!>get<!>
const val nonConstInitializer1 = foo()
const val nonConstInitializer2 = 1 as String
@@ -14,4 +14,4 @@ const val intArrayConst: IntArray = intArrayOf()
const val unresolvedConst1 = <!UNRESOLVED_REFERENCE!>Unresolved<!>
<!WRONG_MODIFIER_TARGET!>const<!> var unresolvedConst2 = <!UNRESOLVED_REFERENCE!>Unresolved<!>
const val unresolvedConst3 = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD, UNRESOLVED_REFERENCE!>Unresolved<!>
get() = 10
<!CONST_VAL_WITH_GETTER!>get() = 10<!>
@@ -1160,6 +1160,18 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.CONST_VAL_WITH_GETTER) { firDiagnostic ->
ConstValWithGetterImpl(
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.CONST_VAL_WITH_DELEGATE) { firDiagnostic ->
ConstValWithDelegateImpl(
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.EXPECTED_DECLARATION_WITH_BODY) { firDiagnostic ->
ExpectedDeclarationWithBodyImpl(
firDiagnostic as FirPsiDiagnostic<*>,
@@ -815,6 +815,14 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = ConstValNotTopLevelOrObject::class
}
abstract class ConstValWithGetter : KtFirDiagnostic<KtProperty>() {
override val diagnosticClass get() = ConstValWithGetter::class
}
abstract class ConstValWithDelegate : KtFirDiagnostic<KtPropertyDelegate>() {
override val diagnosticClass get() = ConstValWithDelegate::class
}
abstract class ExpectedDeclarationWithBody : KtFirDiagnostic<KtDeclaration>() {
override val diagnosticClass get() = ExpectedDeclarationWithBody::class
}
@@ -1326,6 +1326,20 @@ internal class ConstValNotTopLevelOrObjectImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ConstValWithGetterImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.ConstValWithGetter(), KtAbstractFirDiagnostic<KtProperty> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ConstValWithDelegateImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.ConstValWithDelegate(), KtAbstractFirDiagnostic<KtPropertyDelegate> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ExpectedDeclarationWithBodyImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,