[FIR] Copy receiver of delegateProvider in fir building
There was a problem that receiver of `delegateProvider` and `expression` field of `FirWrappedDelegateExpression` was the same object, so after some changes in FirCallCompletionResultsWriterTransformer (where call was partially completed and then copied) there was a problem with resolve of `delegateProvider`, because reference of it's receiver had resolved reference, but type arguments were unsubstituted (see `testCommonCaseForInference`). Maybe there is a better solution. E.g. we can transform type arguments in completion, so we don't need coping of function call at all
This commit is contained in:
+10
-3
@@ -14,7 +14,10 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.builder.*
|
||||
import org.jetbrains.kotlin.fir.builder.Context
|
||||
import org.jetbrains.kotlin.fir.builder.generateAccessorsByDelegate
|
||||
import org.jetbrains.kotlin.fir.builder.generateComponentFunctions
|
||||
import org.jetbrains.kotlin.fir.builder.generateCopyFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
@@ -819,6 +822,7 @@ class DeclarationsConverter(
|
||||
val parentNode = property.getParent()
|
||||
val isLocal = !(parentNode?.tokenType == KT_FILE || parentNode?.tokenType == CLASS_BODY)
|
||||
return if (isLocal) {
|
||||
val receiver = delegateExpression?.let { expressionConverter.getAsFirExpression<FirExpression>(it, "Incorrect delegate expression") }
|
||||
FirPropertyImpl(
|
||||
null,
|
||||
session,
|
||||
@@ -837,7 +841,7 @@ class DeclarationsConverter(
|
||||
FirDeclarationStatusImpl(Visibilities.LOCAL, Modality.FINAL)
|
||||
).apply {
|
||||
annotations += modifiers.annotations
|
||||
this.generateAccessorsByDelegate(this@DeclarationsConverter.session, member = false, stubMode = stubMode)
|
||||
this.generateAccessorsByDelegate(this@DeclarationsConverter.session, member = false, stubMode, receiver)
|
||||
}
|
||||
} else {
|
||||
val status = FirDeclarationStatusImpl(modifiers.getVisibility(), modifiers.getModality()).apply {
|
||||
@@ -847,6 +851,9 @@ class DeclarationsConverter(
|
||||
isConst = modifiers.isConst()
|
||||
isLateInit = modifiers.hasLateinit()
|
||||
}
|
||||
val receiver = delegateExpression?.let {
|
||||
expressionConverter.getAsFirExpression<FirExpression>(it, "Should have delegate")
|
||||
}
|
||||
FirPropertyImpl(
|
||||
null,
|
||||
session,
|
||||
@@ -871,7 +878,7 @@ class DeclarationsConverter(
|
||||
this.getter = getter ?: FirDefaultPropertyGetter(null, session, returnType, modifiers.getVisibility())
|
||||
this.setter = if (isVar) setter ?: FirDefaultPropertySetter(null, session, returnType, modifiers.getVisibility()) else null
|
||||
generateAccessorsByDelegate(
|
||||
this@DeclarationsConverter.session, member = parentNode?.tokenType != KT_FILE, stubMode = stubMode
|
||||
this@DeclarationsConverter.session, member = parentNode?.tokenType != KT_FILE, stubMode, receiver
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ fun generateTemporaryVariable(
|
||||
session: FirSession, source: FirSourceElement?, specialName: String, initializer: FirExpression
|
||||
): FirVariable<*> = generateTemporaryVariable(session, source, Name.special("<$specialName>"), initializer)
|
||||
|
||||
fun FirModifiableVariable<*>.generateAccessorsByDelegate(session: FirSession, member: Boolean, stubMode: Boolean) {
|
||||
fun FirModifiableVariable<*>.generateAccessorsByDelegate(session: FirSession, member: Boolean, stubMode: Boolean, receiver: FirExpression?) {
|
||||
val variable = this as FirVariable<*>
|
||||
val delegateFieldSymbol = delegateFieldSymbol ?: return
|
||||
val delegate = delegate as? FirWrappedDelegateExpressionImpl ?: return
|
||||
@@ -333,7 +333,7 @@ fun FirModifiableVariable<*>.generateAccessorsByDelegate(session: FirSession, me
|
||||
}
|
||||
|
||||
delegate.delegateProvider = if (stubMode) FirExpressionStub(null) else FirFunctionCallImpl(null).apply {
|
||||
explicitReceiver = delegate.expression
|
||||
explicitReceiver = receiver
|
||||
calleeReference = FirSimpleNamedReference(null, PROVIDE_DELEGATE, null)
|
||||
arguments += thisRef()
|
||||
arguments += propertyRef()
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -775,6 +774,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
||||
val delegateExpression by lazy { property.delegate?.expression }
|
||||
val propertySource = property.toFirSourceElement()
|
||||
val firProperty = if (property.isLocal) {
|
||||
val receiver = delegateExpression?.toFirExpression("Incorrect delegate expression")
|
||||
FirPropertyImpl(
|
||||
propertySource,
|
||||
session,
|
||||
@@ -793,7 +793,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
||||
true,
|
||||
FirDeclarationStatusImpl(Visibilities.LOCAL, Modality.FINAL)
|
||||
).apply {
|
||||
generateAccessorsByDelegate(this@RawFirBuilder.session, member = false, stubMode = stubMode)
|
||||
generateAccessorsByDelegate(this@RawFirBuilder.session, member = false, stubMode, receiver)
|
||||
}
|
||||
} else {
|
||||
val status = FirDeclarationStatusImpl(property.visibility, property.modality).apply {
|
||||
@@ -803,6 +803,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
||||
isConst = property.hasModifier(CONST_KEYWORD)
|
||||
isLateInit = property.hasModifier(LATEINIT_KEYWORD)
|
||||
}
|
||||
val receiver = delegateExpression?.toFirExpression("Should have delegate")
|
||||
FirPropertyImpl(
|
||||
propertySource,
|
||||
session,
|
||||
@@ -824,7 +825,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
||||
property.extractTypeParametersTo(this)
|
||||
getter = property.getter.toFirPropertyAccessor(property, propertyType, isGetter = true)
|
||||
setter = if (isVar) property.setter.toFirPropertyAccessor(property, propertyType, isGetter = false) else null
|
||||
generateAccessorsByDelegate(this@RawFirBuilder.session, member = !property.isTopLevel, stubMode = stubMode)
|
||||
generateAccessorsByDelegate(this@RawFirBuilder.session, member = !property.isTopLevel, stubMode, receiver)
|
||||
}
|
||||
}
|
||||
property.extractAnnotationsTo(firProperty)
|
||||
|
||||
+2
-10
@@ -21,16 +21,13 @@ import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirWrappedDelegateExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.isExtensionFunctionAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
@@ -136,13 +133,10 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
// NB: types are reused sometimes (e.g. in accessors)
|
||||
if (!result.add(element)) {
|
||||
throwTwiceVisitingError(element)
|
||||
} else if (element !is FirWrappedDelegateExpression) {
|
||||
element.acceptChildren(this)
|
||||
} else {
|
||||
element.delegateProvider.accept(this)
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ConsistencyTransformer : FirTransformer<Unit>() {
|
||||
@@ -151,10 +145,8 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
override fun <E : FirElement> transformElement(element: E, data: Unit): CompositeTransformResult<E> {
|
||||
if (!result.add(element)) {
|
||||
throwTwiceVisitingError(element)
|
||||
} else if (element !is FirWrappedDelegateExpressionImpl) {
|
||||
element.transformChildren(this, Unit)
|
||||
} else {
|
||||
element.delegateProvider = element.delegateProvider.transformSingle(this, data)
|
||||
element.transformChildren(this, Unit)
|
||||
}
|
||||
return CompositeTransformResult.single(element)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user