From 00112d42271fdc51a50d9509102100704d354e20 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 10 Dec 2019 11:59:07 +0300 Subject: [PATCH] [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 --- .../lightTree/converter/DeclarationsConverter.kt | 13 ++++++++++--- .../jetbrains/kotlin/fir/builder/ConversionUtils.kt | 4 ++-- .../jetbrains/kotlin/fir/builder/RawFirBuilder.kt | 7 ++++--- .../fir/builder/AbstractRawFirBuilderTestCase.kt | 12 ++---------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 084237c34cf..2563858c372 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -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(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(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 ) } } diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt index 31266b6ed70..590b1044720 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt @@ -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() diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 838508be884..cb991565c35 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -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) diff --git a/compiler/fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderTestCase.kt b/compiler/fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderTestCase.kt index f69b26d8cfb..8fea307bca6 100644 --- a/compiler/fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderTestCase.kt +++ b/compiler/fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderTestCase.kt @@ -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() { @@ -151,10 +145,8 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase( override fun transformElement(element: E, data: Unit): CompositeTransformResult { 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) }