[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.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.fir.*
|
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.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
@@ -819,6 +822,7 @@ class DeclarationsConverter(
|
|||||||
val parentNode = property.getParent()
|
val parentNode = property.getParent()
|
||||||
val isLocal = !(parentNode?.tokenType == KT_FILE || parentNode?.tokenType == CLASS_BODY)
|
val isLocal = !(parentNode?.tokenType == KT_FILE || parentNode?.tokenType == CLASS_BODY)
|
||||||
return if (isLocal) {
|
return if (isLocal) {
|
||||||
|
val receiver = delegateExpression?.let { expressionConverter.getAsFirExpression<FirExpression>(it, "Incorrect delegate expression") }
|
||||||
FirPropertyImpl(
|
FirPropertyImpl(
|
||||||
null,
|
null,
|
||||||
session,
|
session,
|
||||||
@@ -837,7 +841,7 @@ class DeclarationsConverter(
|
|||||||
FirDeclarationStatusImpl(Visibilities.LOCAL, Modality.FINAL)
|
FirDeclarationStatusImpl(Visibilities.LOCAL, Modality.FINAL)
|
||||||
).apply {
|
).apply {
|
||||||
annotations += modifiers.annotations
|
annotations += modifiers.annotations
|
||||||
this.generateAccessorsByDelegate(this@DeclarationsConverter.session, member = false, stubMode = stubMode)
|
this.generateAccessorsByDelegate(this@DeclarationsConverter.session, member = false, stubMode, receiver)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val status = FirDeclarationStatusImpl(modifiers.getVisibility(), modifiers.getModality()).apply {
|
val status = FirDeclarationStatusImpl(modifiers.getVisibility(), modifiers.getModality()).apply {
|
||||||
@@ -847,6 +851,9 @@ class DeclarationsConverter(
|
|||||||
isConst = modifiers.isConst()
|
isConst = modifiers.isConst()
|
||||||
isLateInit = modifiers.hasLateinit()
|
isLateInit = modifiers.hasLateinit()
|
||||||
}
|
}
|
||||||
|
val receiver = delegateExpression?.let {
|
||||||
|
expressionConverter.getAsFirExpression<FirExpression>(it, "Should have delegate")
|
||||||
|
}
|
||||||
FirPropertyImpl(
|
FirPropertyImpl(
|
||||||
null,
|
null,
|
||||||
session,
|
session,
|
||||||
@@ -871,7 +878,7 @@ class DeclarationsConverter(
|
|||||||
this.getter = getter ?: FirDefaultPropertyGetter(null, session, returnType, modifiers.getVisibility())
|
this.getter = getter ?: FirDefaultPropertyGetter(null, session, returnType, modifiers.getVisibility())
|
||||||
this.setter = if (isVar) setter ?: FirDefaultPropertySetter(null, session, returnType, modifiers.getVisibility()) else null
|
this.setter = if (isVar) setter ?: FirDefaultPropertySetter(null, session, returnType, modifiers.getVisibility()) else null
|
||||||
generateAccessorsByDelegate(
|
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
|
session: FirSession, source: FirSourceElement?, specialName: String, initializer: FirExpression
|
||||||
): FirVariable<*> = generateTemporaryVariable(session, source, Name.special("<$specialName>"), initializer)
|
): 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 variable = this as FirVariable<*>
|
||||||
val delegateFieldSymbol = delegateFieldSymbol ?: return
|
val delegateFieldSymbol = delegateFieldSymbol ?: return
|
||||||
val delegate = delegate as? FirWrappedDelegateExpressionImpl ?: 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 {
|
delegate.delegateProvider = if (stubMode) FirExpressionStub(null) else FirFunctionCallImpl(null).apply {
|
||||||
explicitReceiver = delegate.expression
|
explicitReceiver = receiver
|
||||||
calleeReference = FirSimpleNamedReference(null, PROVIDE_DELEGATE, null)
|
calleeReference = FirSimpleNamedReference(null, PROVIDE_DELEGATE, null)
|
||||||
arguments += thisRef()
|
arguments += thisRef()
|
||||||
arguments += propertyRef()
|
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.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.*
|
import org.jetbrains.kotlin.fir.types.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
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 delegateExpression by lazy { property.delegate?.expression }
|
||||||
val propertySource = property.toFirSourceElement()
|
val propertySource = property.toFirSourceElement()
|
||||||
val firProperty = if (property.isLocal) {
|
val firProperty = if (property.isLocal) {
|
||||||
|
val receiver = delegateExpression?.toFirExpression("Incorrect delegate expression")
|
||||||
FirPropertyImpl(
|
FirPropertyImpl(
|
||||||
propertySource,
|
propertySource,
|
||||||
session,
|
session,
|
||||||
@@ -793,7 +793,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
true,
|
true,
|
||||||
FirDeclarationStatusImpl(Visibilities.LOCAL, Modality.FINAL)
|
FirDeclarationStatusImpl(Visibilities.LOCAL, Modality.FINAL)
|
||||||
).apply {
|
).apply {
|
||||||
generateAccessorsByDelegate(this@RawFirBuilder.session, member = false, stubMode = stubMode)
|
generateAccessorsByDelegate(this@RawFirBuilder.session, member = false, stubMode, receiver)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val status = FirDeclarationStatusImpl(property.visibility, property.modality).apply {
|
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)
|
isConst = property.hasModifier(CONST_KEYWORD)
|
||||||
isLateInit = property.hasModifier(LATEINIT_KEYWORD)
|
isLateInit = property.hasModifier(LATEINIT_KEYWORD)
|
||||||
}
|
}
|
||||||
|
val receiver = delegateExpression?.toFirExpression("Should have delegate")
|
||||||
FirPropertyImpl(
|
FirPropertyImpl(
|
||||||
propertySource,
|
propertySource,
|
||||||
session,
|
session,
|
||||||
@@ -824,7 +825,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
property.extractTypeParametersTo(this)
|
property.extractTypeParametersTo(this)
|
||||||
getter = property.getter.toFirPropertyAccessor(property, propertyType, isGetter = true)
|
getter = property.getter.toFirPropertyAccessor(property, propertyType, isGetter = true)
|
||||||
setter = if (isVar) property.setter.toFirPropertyAccessor(property, propertyType, isGetter = false) else null
|
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)
|
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.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
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.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirWrappedDelegateExpressionImpl
|
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.isExtensionFunctionAnnotationCall
|
import org.jetbrains.kotlin.fir.types.isExtensionFunctionAnnotationCall
|
||||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
|
||||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
@@ -136,13 +133,10 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
|||||||
// NB: types are reused sometimes (e.g. in accessors)
|
// NB: types are reused sometimes (e.g. in accessors)
|
||||||
if (!result.add(element)) {
|
if (!result.add(element)) {
|
||||||
throwTwiceVisitingError(element)
|
throwTwiceVisitingError(element)
|
||||||
} else if (element !is FirWrappedDelegateExpression) {
|
|
||||||
element.acceptChildren(this)
|
|
||||||
} else {
|
} else {
|
||||||
element.delegateProvider.accept(this)
|
element.acceptChildren(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ConsistencyTransformer : FirTransformer<Unit>() {
|
private class ConsistencyTransformer : FirTransformer<Unit>() {
|
||||||
@@ -151,10 +145,8 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
|||||||
override fun <E : FirElement> transformElement(element: E, data: Unit): CompositeTransformResult<E> {
|
override fun <E : FirElement> transformElement(element: E, data: Unit): CompositeTransformResult<E> {
|
||||||
if (!result.add(element)) {
|
if (!result.add(element)) {
|
||||||
throwTwiceVisitingError(element)
|
throwTwiceVisitingError(element)
|
||||||
} else if (element !is FirWrappedDelegateExpressionImpl) {
|
|
||||||
element.transformChildren(this, Unit)
|
|
||||||
} else {
|
} else {
|
||||||
element.delegateProvider = element.delegateProvider.transformSingle(this, data)
|
element.transformChildren(this, Unit)
|
||||||
}
|
}
|
||||||
return CompositeTransformResult.single(element)
|
return CompositeTransformResult.single(element)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user