[FIR IDE] Fix invalid lazy expressions for property initializers
This commit is contained in:
committed by
TeamCityServer
parent
19e5e7d511
commit
e802ef27f1
+5
@@ -353,6 +353,11 @@ public class LightTree2FirConverterTestCaseGenerated extends AbstractLightTree2F
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclarationWithExpression.kt")
|
||||
public void testLocalDeclarationWithExpression() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/localDeclarationWithExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("locals.kt")
|
||||
public void testLocals() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/locals.kt");
|
||||
|
||||
+51
-44
@@ -210,7 +210,7 @@ open class RawFirBuilder(
|
||||
|
||||
private fun KtElement?.toFirExpression(
|
||||
errorReason: String,
|
||||
kind: DiagnosticKind = DiagnosticKind.ExpressionExpected,
|
||||
kind: DiagnosticKind = DiagnosticKind.ExpressionExpected
|
||||
): FirExpression {
|
||||
if (stubMode) {
|
||||
return buildExpressionStub()
|
||||
@@ -1401,7 +1401,7 @@ open class RawFirBuilder(
|
||||
else -> initializer.toFirExpression("Should have initializer")
|
||||
|
||||
}
|
||||
val delegateExpression by lazy { delegate?.expression }
|
||||
|
||||
val propertySource = toFirSourceElement()
|
||||
|
||||
return buildProperty {
|
||||
@@ -1417,27 +1417,31 @@ open class RawFirBuilder(
|
||||
if (this@toFirProperty.isLocal) {
|
||||
isLocal = true
|
||||
symbol = FirPropertySymbol(propertyName)
|
||||
val delegateBuilder = delegateExpression?.let {
|
||||
FirWrappedDelegateExpressionBuilder().apply {
|
||||
source = it.toFirSourceElement(FirFakeSourceElementKind.WrappedDelegate)
|
||||
expression = it.toFirExpression("Incorrect delegate expression")
|
||||
}
|
||||
}
|
||||
|
||||
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL).apply {
|
||||
isLateInit = hasModifier(LATEINIT_KEYWORD)
|
||||
}
|
||||
|
||||
val receiver = delegateExpression?.toFirExpression("Incorrect delegate expression")
|
||||
generateAccessorsByDelegate(
|
||||
delegateBuilder,
|
||||
baseModuleData,
|
||||
ownerRegularOrAnonymousObjectSymbol = null,
|
||||
ownerRegularClassTypeParametersCount = null,
|
||||
isExtension = false,
|
||||
stubMode = stubMode,
|
||||
receiver = receiver
|
||||
)
|
||||
if (hasDelegate()) {
|
||||
fun extractDelegateExpression() =
|
||||
this@toFirProperty.delegate?.expression.toFirExpression("Incorrect delegate expression")
|
||||
|
||||
val delegateBuilder = FirWrappedDelegateExpressionBuilder().apply {
|
||||
val delegateFirExpression = extractDelegateExpression()
|
||||
source = delegateFirExpression.source?.fakeElement(FirFakeSourceElementKind.WrappedDelegate)
|
||||
expression = delegateFirExpression
|
||||
}
|
||||
|
||||
generateAccessorsByDelegate(
|
||||
delegateBuilder,
|
||||
baseModuleData,
|
||||
ownerRegularOrAnonymousObjectSymbol = null,
|
||||
ownerRegularClassTypeParametersCount = null,
|
||||
isExtension = false,
|
||||
stubMode = stubMode,
|
||||
//TODO This expression should be the same for wrapper and receiver
|
||||
receiver = extractDelegateExpression()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
isLocal = false
|
||||
receiverTypeRef = receiverTypeReference.convertSafe()
|
||||
@@ -1445,21 +1449,6 @@ open class RawFirBuilder(
|
||||
dispatchReceiverType = currentDispatchReceiverType()
|
||||
extractTypeParametersTo(this, symbol)
|
||||
withCapturedTypeParameters(true, this.typeParameters) {
|
||||
val delegateBuilder = if (hasDelegate()) {
|
||||
FirWrappedDelegateExpressionBuilder().apply {
|
||||
source =
|
||||
if (stubMode) null else delegateExpression?.toFirSourceElement(FirFakeSourceElementKind.WrappedDelegate)
|
||||
expression = when (mode) {
|
||||
BodyBuildingMode.NORMAL -> delegateExpression.toFirExpression("Should have delegate")
|
||||
BodyBuildingMode.STUBS -> buildExpressionStub()
|
||||
BodyBuildingMode.LAZY_BODIES -> buildLazyExpression {
|
||||
source = delegateExpression!!.toFirSourceElement()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else null
|
||||
|
||||
getter = this@toFirProperty.getter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = true)
|
||||
setter = this@toFirProperty.setter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = false)
|
||||
|
||||
@@ -1472,16 +1461,34 @@ open class RawFirBuilder(
|
||||
isExternal = hasModifier(EXTERNAL_KEYWORD)
|
||||
}
|
||||
|
||||
val receiver = delegateExpression?.toFirExpression("Should have delegate")
|
||||
generateAccessorsByDelegate(
|
||||
delegateBuilder,
|
||||
baseModuleData,
|
||||
ownerRegularOrAnonymousObjectSymbol,
|
||||
ownerRegularClassTypeParametersCount,
|
||||
isExtension = receiverTypeReference != null,
|
||||
stubMode = stubMode,
|
||||
receiver = receiver
|
||||
)
|
||||
if (hasDelegate()) {
|
||||
fun extractDelegateExpression() = when (mode) {
|
||||
BodyBuildingMode.NORMAL -> this@toFirProperty.delegate?.expression.toFirExpression("Should have delegate")
|
||||
BodyBuildingMode.STUBS -> buildExpressionStub()
|
||||
BodyBuildingMode.LAZY_BODIES -> this@toFirProperty.delegate?.expression?.let {
|
||||
buildLazyExpression { source = it.toFirSourceElement() }
|
||||
} ?: buildErrorExpression {
|
||||
ConeSimpleDiagnostic("Should have delegate", DiagnosticKind.ExpressionExpected)
|
||||
}
|
||||
}
|
||||
|
||||
val delegateBuilder = FirWrappedDelegateExpressionBuilder().apply {
|
||||
val delegateExpression = extractDelegateExpression()
|
||||
source = delegateExpression.source?.fakeElement(FirFakeSourceElementKind.WrappedDelegate)
|
||||
expression = extractDelegateExpression()
|
||||
}
|
||||
|
||||
generateAccessorsByDelegate(
|
||||
delegateBuilder,
|
||||
baseModuleData,
|
||||
ownerRegularOrAnonymousObjectSymbol,
|
||||
ownerRegularClassTypeParametersCount,
|
||||
isExtension = receiverTypeReference != null,
|
||||
stubMode = stubMode,
|
||||
//TODO This expression should be the same for wrapper and receiver
|
||||
receiver = extractDelegateExpression()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
extractAnnotationsTo(this)
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
private val nonLocalProperty: List<XXX> by lazy {
|
||||
val localProperty = mutableListOf<KtLightField>()
|
||||
localProperty
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
FILE: localDeclarationWithExpression.kt
|
||||
private final? val nonLocalProperty: List<XXX>by LAZY_EXPRESSION
|
||||
public? get(): <implicit> {
|
||||
^ D|/nonLocalProperty|.getValue#(Null(null), ::R|/nonLocalProperty|)
|
||||
}
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
FILE: localDeclarationWithExpression.kt
|
||||
private final? val nonLocalProperty: List<XXX>by lazy#(<L> = lazy@fun <implicit>.<anonymous>(): <implicit> <inline=Unknown> {
|
||||
lval localProperty: <implicit> = mutableListOf#<KtLightField>()
|
||||
localProperty#
|
||||
}
|
||||
)
|
||||
public? get(): <implicit> {
|
||||
^ D|/nonLocalProperty|.getValue#(Null(null), ::R|/nonLocalProperty|)
|
||||
}
|
||||
+5
@@ -353,6 +353,11 @@ public class RawFirBuilderLazyBodiesTestCaseGenerated extends AbstractRawFirBuil
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclarationWithExpression.kt")
|
||||
public void testLocalDeclarationWithExpression() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/localDeclarationWithExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("locals.kt")
|
||||
public void testLocals() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/locals.kt");
|
||||
|
||||
+5
@@ -353,6 +353,11 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclarationWithExpression.kt")
|
||||
public void testLocalDeclarationWithExpression() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/localDeclarationWithExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("locals.kt")
|
||||
public void testLocals() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/locals.kt");
|
||||
|
||||
+6
@@ -385,6 +385,12 @@ public class FirVisualizerForRawFirDataGenerated extends AbstractFirVisualizerTe
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localDeclarationWithExpression.kt")
|
||||
public void testLocalDeclarationWithExpression() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/localDeclarationWithExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("locals.kt")
|
||||
public void testLocals() throws Exception {
|
||||
|
||||
+6
@@ -385,6 +385,12 @@ public class PsiVisualizerForRawFirDataGenerated extends AbstractPsiVisualizerTe
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localDeclarationWithExpression.kt")
|
||||
public void testLocalDeclarationWithExpression() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/localDeclarationWithExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("locals.kt")
|
||||
public void testLocals() throws Exception {
|
||||
|
||||
+15
-3
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirLazyBlock
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirLazyExpression
|
||||
@@ -90,10 +92,20 @@ internal object FirLazyBodiesCalculator {
|
||||
firProperty.replaceInitializer(newProperty.initializer)
|
||||
}
|
||||
|
||||
val delegate = firProperty.delegate
|
||||
if (delegate is FirWrappedDelegateExpression && delegate.expression is FirLazyExpression) {
|
||||
val newDelegate = newProperty.delegate as FirWrappedDelegateExpression
|
||||
val delegate = firProperty.delegate as? FirWrappedDelegateExpression
|
||||
val delegateExpression = delegate?.expression
|
||||
if (delegateExpression is FirLazyExpression) {
|
||||
val newDelegate = newProperty.delegate as? FirWrappedDelegateExpression
|
||||
check(newDelegate != null) { "Invalid replacement delegate" }
|
||||
delegate.replaceExpression(newDelegate.expression)
|
||||
|
||||
val delegateProviderCall = delegate.delegateProvider as? FirFunctionCall
|
||||
val delegateProviderExplicitReceiver = delegateProviderCall?.explicitReceiver
|
||||
if (delegateProviderExplicitReceiver is FirLazyExpression) {
|
||||
val newDelegateProviderExplicitReceiver = (newDelegate.delegateProvider as? FirFunctionCall)?.explicitReceiver
|
||||
check(newDelegateProviderExplicitReceiver != null) { "Invalid replacement expression" }
|
||||
delegateProviderCall.replaceExplicitReceiver(newDelegateProviderExplicitReceiver)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
@@ -6,10 +6,14 @@
|
||||
package org.jetbrains.kotlin.idea.fir.low.level.api
|
||||
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.builder.BodyBuildingMode
|
||||
import org.jetbrains.kotlin.fir.builder.PsiHandlingMode
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirLazyBlock
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirLazyExpression
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyBodiesCalculator
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
|
||||
@@ -18,6 +22,15 @@ import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
abstract class AbstractFirLazyBodiesCalculatorTest : AbstractLowLevelApiSingleFileTest() {
|
||||
|
||||
private val lazyChecker = object : FirVisitorVoid() {
|
||||
override fun visitElement(element: FirElement) {
|
||||
TestCase.assertFalse("${FirLazyBlock::class.qualifiedName} should not present in the tree", element is FirLazyBlock)
|
||||
TestCase.assertFalse("${FirLazyExpression::class.qualifiedName} should not present in the tree", element is FirLazyExpression)
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
|
||||
resolveWithClearCaches(ktFile) { resolveState ->
|
||||
val session = resolveState.rootModuleSession
|
||||
@@ -31,6 +44,7 @@ abstract class AbstractFirLazyBodiesCalculatorTest : AbstractLowLevelApiSingleFi
|
||||
).buildFirFile(ktFile)
|
||||
|
||||
FirLazyBodiesCalculator.calculateLazyBodies(laziedFirFile)
|
||||
laziedFirFile.accept(lazyChecker)
|
||||
|
||||
val fullFirFile = RawFirBuilder(
|
||||
session,
|
||||
|
||||
+6
@@ -385,6 +385,12 @@ public class FirLazyBodiesCalculatorTestGenerated extends AbstractFirLazyBodiesC
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localDeclarationWithExpression.kt")
|
||||
public void testLocalDeclarationWithExpression() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/localDeclarationWithExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("locals.kt")
|
||||
public void testLocals() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user