[FIR] Fix generation of raw FIR for delegate with receiver

This commit is contained in:
simon.ogorodnik
2020-01-31 19:04:54 +03:00
committed by Mikhail Glukhikh
parent ef5aab374b
commit ca5fee77d4
5 changed files with 58 additions and 8 deletions
@@ -865,7 +865,13 @@ 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, receiver) this.generateAccessorsByDelegate(
this@DeclarationsConverter.session,
member = false,
extension = false,
stubMode,
receiver
)
} }
} else { } else {
val status = FirDeclarationStatusImpl(modifiers.getVisibility(), modifiers.getModality()).apply { val status = FirDeclarationStatusImpl(modifiers.getVisibility(), modifiers.getModality()).apply {
@@ -902,7 +908,11 @@ 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, receiver this@DeclarationsConverter.session,
member = parentNode?.tokenType != KT_FILE,
extension = receiverType != null,
stubMode,
receiver
) )
} }
} }
@@ -314,7 +314,13 @@ 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, receiver: FirExpression?) { fun FirModifiableVariable<*>.generateAccessorsByDelegate(
session: FirSession,
member: Boolean,
extension: 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
@@ -323,10 +329,12 @@ fun FirModifiableVariable<*>.generateAccessorsByDelegate(session: FirSession, me
} }
fun thisRef(): FirExpression = fun thisRef(): FirExpression =
if (member) FirQualifiedAccessExpressionImpl(null).apply { when {
calleeReference = FirExplicitThisReference(null, null) member || extension -> FirQualifiedAccessExpressionImpl(null).apply {
calleeReference = FirExplicitThisReference(null, null)
}
else -> FirConstExpressionImpl(null, FirConstKind.Null, null)
} }
else FirConstExpressionImpl(null, FirConstKind.Null, null)
fun propertyRef() = FirCallableReferenceAccessImpl(null).apply { fun propertyRef() = FirCallableReferenceAccessImpl(null).apply {
calleeReference = FirResolvedNamedReferenceImpl(null, variable.name, variable.symbol) calleeReference = FirResolvedNamedReferenceImpl(null, variable.name, variable.symbol)
@@ -863,7 +863,7 @@ class RawFirBuilder(session: FirSession, val scopeProvider: FirScopeProvider, va
true, true,
FirDeclarationStatusImpl(Visibilities.LOCAL, Modality.FINAL) FirDeclarationStatusImpl(Visibilities.LOCAL, Modality.FINAL)
).apply { ).apply {
generateAccessorsByDelegate(this@RawFirBuilder.session, member = false, stubMode, receiver) generateAccessorsByDelegate(this@RawFirBuilder.session, member = false, extension = false, stubMode, receiver)
} }
} else { } else {
val status = FirDeclarationStatusImpl(property.visibility, property.modality).apply { val status = FirDeclarationStatusImpl(property.visibility, property.modality).apply {
@@ -895,7 +895,13 @@ class RawFirBuilder(session: FirSession, val scopeProvider: FirScopeProvider, va
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, receiver) generateAccessorsByDelegate(
this@RawFirBuilder.session,
member = !property.isTopLevel,
extension = property.receiverTypeReference != null,
stubMode,
receiver
)
} }
} }
property.extractAnnotationsTo(firProperty) property.extractAnnotationsTo(firProperty)
@@ -7,3 +7,11 @@ fun foo() {
val y by lazy { "Bye" } val y by lazy { "Bye" }
y.length y.length
} }
class Some {
val z by lazy { "Some" }
fun foo() {
z.length
}
}
@@ -14,3 +14,21 @@ FILE: simpleLazy.kt
) )
R|<local>/y|.R|kotlin/String.length| R|<local>/y|.R|kotlin/String.length|
} }
public final class Some : R|kotlin/Any| {
public constructor(): R|Some| {
super<R|kotlin/Any|>()
}
public final val z: R|kotlin/String|by R|kotlin/lazy|<R|kotlin/String|>(<L> = lazy@fun <anonymous>(): R|kotlin/String| {
String(Some)
}
)
public get(): R|kotlin/String| {
^ D|/Some.z|.R|kotlin/getValue|<R|kotlin/String|>(this@R|/Some|, ::R|/Some.z|)
}
public final fun foo(): R|kotlin/Unit| {
this@R|/Some|.R|/Some.z|.R|kotlin/String.length|
}
}