FIR: implementation of delegateProvider in delegate resolve
This commit is contained in:
@@ -570,9 +570,10 @@ internal fun KtExpression?.generateAssignment(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun FirModifiableAccessorsOwner.generateAccessorsByDelegate(session: FirSession, member: Boolean) {
|
||||
internal fun FirModifiableAccessorsOwner.generateAccessorsByDelegate(session: FirSession, member: Boolean, stubMode: Boolean) {
|
||||
val variable = this as FirVariable<*>
|
||||
val delegateFieldSymbol = delegateFieldSymbol ?: return
|
||||
val delegate = delegate as? FirWrappedDelegateExpressionImpl ?: return
|
||||
fun delegateAccess() = FirQualifiedAccessExpressionImpl(session, null).apply {
|
||||
calleeReference = FirDelegateFieldReferenceImpl(session, null, delegateFieldSymbol)
|
||||
}
|
||||
@@ -588,6 +589,13 @@ internal fun FirModifiableAccessorsOwner.generateAccessorsByDelegate(session: Fi
|
||||
typeRef = FirImplicitKPropertyTypeRef(session, null, ConeStarProjection)
|
||||
}
|
||||
|
||||
delegate.delegateProvider = if (stubMode) FirExpressionStub(session, null) else FirFunctionCallImpl(session, null).apply {
|
||||
explicitReceiver = delegate.expression
|
||||
calleeReference = FirSimpleNamedReference(session, null, PROVIDE_DELEGATE)
|
||||
arguments += thisRef()
|
||||
arguments += propertyRef()
|
||||
}
|
||||
if (stubMode) return
|
||||
getter = (getter as? FirPropertyAccessorImpl)
|
||||
?: FirPropertyAccessorImpl(session, null, true, Visibilities.UNKNOWN, FirImplicitTypeRefImpl(session, null)).apply Accessor@{
|
||||
body = FirSingleExpressionBlock(
|
||||
@@ -631,4 +639,5 @@ internal fun FirModifiableAccessorsOwner.generateAccessorsByDelegate(session: Fi
|
||||
|
||||
private val GET_VALUE = Name.identifier("getValue")
|
||||
private val SET_VALUE = Name.identifier("setValue")
|
||||
private val PROVIDE_DELEGATE = Name.identifier("provideDelegate")
|
||||
private val DELEGATED_SETTER_PARAM = Name.special("<set-?>")
|
||||
@@ -70,7 +70,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
|
||||
}
|
||||
|
||||
private inner class Visitor : KtVisitor<FirElement, Unit>() {
|
||||
private inline fun <reified R : FirElement> KtElement?. convertSafe(): R? =
|
||||
private inline fun <reified R : FirElement> KtElement?.convertSafe(): R? =
|
||||
this?.accept(this@Visitor, Unit) as? R
|
||||
|
||||
private inline fun <reified R : FirElement> KtElement.convert(): R =
|
||||
@@ -774,6 +774,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
|
||||
val initializer = if (property.hasInitializer()) {
|
||||
{ property.initializer }.toFirExpression("Should have initializer")
|
||||
} else null
|
||||
val delegateExpression by lazy { property.delegate?.expression }
|
||||
val firProperty = if (property.isLocal) {
|
||||
FirVariableImpl(
|
||||
session,
|
||||
@@ -782,9 +783,14 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
|
||||
propertyType,
|
||||
isVar,
|
||||
initializer,
|
||||
delegate = property.delegate?.expression?.toFirExpression("Incorrect delegate expression")
|
||||
delegate = delegateExpression?.let {
|
||||
FirWrappedDelegateExpressionImpl(
|
||||
session, it,
|
||||
it.toFirExpression("Incorrect delegate expression")
|
||||
)
|
||||
}
|
||||
).apply {
|
||||
generateAccessorsByDelegate(this@RawFirBuilder.session, member = false)
|
||||
generateAccessorsByDelegate(this@RawFirBuilder.session, member = false, stubMode = stubMode)
|
||||
}
|
||||
} else {
|
||||
FirMemberPropertyImpl(
|
||||
@@ -804,13 +810,16 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
|
||||
isVar,
|
||||
initializer,
|
||||
if (property.hasDelegate()) {
|
||||
{ property.delegate?.expression }.toFirExpression("Should have delegate")
|
||||
FirWrappedDelegateExpressionImpl(
|
||||
session, if (stubMode) null else delegateExpression,
|
||||
{ delegateExpression }.toFirExpression("Should have delegate")
|
||||
)
|
||||
} else null
|
||||
).apply {
|
||||
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)
|
||||
generateAccessorsByDelegate(this@RawFirBuilder.session, member = !property.isTopLevel, stubMode = stubMode)
|
||||
}
|
||||
}
|
||||
property.extractAnnotationsTo(firProperty)
|
||||
|
||||
+15
-1
@@ -1063,6 +1063,20 @@ open class FirBodyResolveTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformWrappedDelegateExpression(
|
||||
wrappedDelegateExpression: FirWrappedDelegateExpression,
|
||||
data: Any?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
super.transformWrappedDelegateExpression(wrappedDelegateExpression, data)
|
||||
with(wrappedDelegateExpression) {
|
||||
val delegateProviderTypeRef = delegateProvider.typeRef
|
||||
val useDelegateProvider = delegateProviderTypeRef is FirResolvedTypeRef &&
|
||||
delegateProviderTypeRef !is FirErrorTypeRef &&
|
||||
delegateProviderTypeRef.type !is ConeKotlinErrorType
|
||||
return if (useDelegateProvider) delegateProvider.compose() else expression.compose()
|
||||
}
|
||||
}
|
||||
|
||||
override fun <F : FirVariable<F>> transformVariable(variable: FirVariable<F>, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
variable.transformChildrenWithoutAccessors(this, variable.returnTypeRef)
|
||||
if (variable.initializer != null) {
|
||||
@@ -1100,7 +1114,7 @@ open class FirBodyResolveTransformer(
|
||||
}
|
||||
|
||||
override fun transformExpression(expression: FirExpression, data: Any?): CompositeTransformResult<FirStatement> {
|
||||
if (expression.resultType is FirImplicitTypeRef && expression !is FirWrappedArgumentExpression) {
|
||||
if (expression.resultType is FirImplicitTypeRef && expression !is FirWrappedExpression) {
|
||||
val type = FirErrorTypeRefImpl(session, expression.psi, "Type calculating for ${expression::class} is not supported")
|
||||
expression.resultType = type
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class Delegate(val value: String) {
|
||||
operator fun getValue(thisRef: Any?, property: Any?) = value
|
||||
}
|
||||
|
||||
class DelegateProvider(val value: String) {
|
||||
operator fun provideDelegate(thisRef: Any?, property: Any?) = Delegate(value)
|
||||
}
|
||||
|
||||
val testTopLevel by DelegateProvider("OK")
|
||||
@@ -0,0 +1,31 @@
|
||||
FILE: simpleDelegateProvider.kt
|
||||
public final class Delegate : R|kotlin/Any| {
|
||||
public constructor(value: R|kotlin/String|): R|Delegate| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val value: R|kotlin/String| = R|<local>/value|
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public final operator fun getValue(thisRef: R|kotlin/Any|?, property: R|kotlin/Any|?): R|kotlin/String| {
|
||||
^getValue R|/Delegate.value|
|
||||
}
|
||||
|
||||
}
|
||||
public final class DelegateProvider : R|kotlin/Any| {
|
||||
public constructor(value: R|kotlin/String|): R|DelegateProvider| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val value: R|kotlin/String| = R|<local>/value|
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public final operator fun provideDelegate(thisRef: R|kotlin/Any|?, property: R|kotlin/Any|?): R|Delegate| {
|
||||
^provideDelegate R|/Delegate.Delegate|(R|/DelegateProvider.value|)
|
||||
}
|
||||
|
||||
}
|
||||
public final val testTopLevel: R|kotlin/String|by R|/DelegateProvider.DelegateProvider|(String(OK)).R|/DelegateProvider.provideDelegate|(Null(null), ::R|/testTopLevel|)
|
||||
public get(): R|kotlin/String| {
|
||||
^ D|/testTopLevel|.R|/Delegate.getValue|(Null(null), ::R|/testTopLevel|)
|
||||
}
|
||||
Generated
+5
@@ -94,6 +94,11 @@ public class FirResolveTestCaseWithStdlibGenerated extends AbstractFirResolveTes
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/reflectionClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleDelegateProvider.kt")
|
||||
public void testSimpleDelegateProvider() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/simpleDelegateProvider.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleDelegatedToMap.kt")
|
||||
public void testSimpleDelegatedToMap() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/simpleDelegatedToMap.kt");
|
||||
|
||||
@@ -625,6 +625,10 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
print("${constExpression.kind}(${constExpression.value})")
|
||||
}
|
||||
|
||||
override fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression) {
|
||||
wrappedDelegateExpression.expression.accept(this)
|
||||
}
|
||||
|
||||
override fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression) {
|
||||
print(namedArgumentExpression.name)
|
||||
print(" = ")
|
||||
|
||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.declarations.impl
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirVariable
|
||||
|
||||
+1
-12
@@ -13,24 +13,13 @@ import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
abstract class FirWrappedArgumentExpression(
|
||||
session: FirSession,
|
||||
psi: PsiElement?
|
||||
) : FirExpression(session, psi) {
|
||||
abstract val expression: FirExpression
|
||||
|
||||
) : FirWrappedExpression(session, psi) {
|
||||
open val isSpread: Boolean
|
||||
get() = false
|
||||
|
||||
override val typeRef: FirTypeRef
|
||||
get() = expression.typeRef
|
||||
|
||||
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
|
||||
throw AssertionError("We should not try to replace type reference in ${this::class}")
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitWrappedArgumentExpression(this, data)
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
expression.accept(visitor, data)
|
||||
super.acceptChildren(visitor, data)
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.expressions
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
abstract class FirWrappedDelegateExpression(
|
||||
session: FirSession,
|
||||
psi: PsiElement?
|
||||
) : FirWrappedExpression(session, psi) {
|
||||
abstract val delegateProvider: FirExpression
|
||||
|
||||
override val typeRef: FirTypeRef
|
||||
get() = expression.typeRef
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R {
|
||||
return visitor.visitWrappedDelegateExpression(this, data)
|
||||
}
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
delegateProvider.accept(visitor, data)
|
||||
super.acceptChildren(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.expressions
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
abstract class FirWrappedExpression(
|
||||
session: FirSession,
|
||||
psi: PsiElement?
|
||||
) : FirExpression(session, psi) {
|
||||
abstract val expression: FirExpression
|
||||
|
||||
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
|
||||
throw AssertionError("We should not try to replace type reference in ${this::class}")
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitWrappedExpression(this, data)
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
expression.accept(visitor, data)
|
||||
super.acceptChildren(visitor, data)
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.expressions.impl
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression
|
||||
import org.jetbrains.kotlin.fir.transformSingle
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
|
||||
class FirWrappedDelegateExpressionImpl(
|
||||
session: FirSession,
|
||||
psi: PsiElement?,
|
||||
override var expression: FirExpression
|
||||
) : FirWrappedDelegateExpression(session, psi) {
|
||||
override lateinit var delegateProvider: FirExpression
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
expression = expression.transformSingle(transformer, data)
|
||||
delegateProvider = delegateProvider.transformSingle(transformer, data)
|
||||
|
||||
return super.transformChildren(transformer, data)
|
||||
}
|
||||
}
|
||||
+17
-1
@@ -320,8 +320,12 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
|
||||
return transformUnknownTypeExpression(whenSubjectExpression, data)
|
||||
}
|
||||
|
||||
open fun transformWrappedExpression(wrappedExpression: FirWrappedExpression, data: D): CompositeTransformResult<FirStatement> {
|
||||
return transformExpression(wrappedExpression, data)
|
||||
}
|
||||
|
||||
open fun transformWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression, data: D): CompositeTransformResult<FirStatement> {
|
||||
return transformExpression(wrappedArgumentExpression, data)
|
||||
return transformWrappedExpression(wrappedArgumentExpression, data)
|
||||
}
|
||||
|
||||
open fun transformLambdaArgumentExpression(lambdaArgumentExpression: FirLambdaArgumentExpression, data: D): CompositeTransformResult<FirStatement> {
|
||||
@@ -336,6 +340,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
|
||||
return transformWrappedArgumentExpression(spreadArgumentExpression, data)
|
||||
}
|
||||
|
||||
open fun transformWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression, data: D): CompositeTransformResult<FirStatement> {
|
||||
return transformWrappedExpression(wrappedDelegateExpression, data)
|
||||
}
|
||||
|
||||
open fun transformClass(klass: FirClass, data: D): CompositeTransformResult<FirStatement> {
|
||||
return transformStatement(klass, data)
|
||||
}
|
||||
@@ -872,6 +880,14 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
|
||||
return transformWrappedArgumentExpression(wrappedArgumentExpression, data)
|
||||
}
|
||||
|
||||
final override fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression, data: D): CompositeTransformResult<FirElement> {
|
||||
return transformWrappedDelegateExpression(wrappedDelegateExpression, data)
|
||||
}
|
||||
|
||||
final override fun visitWrappedExpression(wrappedExpression: FirWrappedExpression, data: D): CompositeTransformResult<FirElement> {
|
||||
return transformWrappedExpression(wrappedExpression, data)
|
||||
}
|
||||
|
||||
final override fun visitElement(element: FirElement, data: D): CompositeTransformResult<FirElement> {
|
||||
return transformElement(element, data)
|
||||
}
|
||||
|
||||
@@ -320,8 +320,12 @@ abstract class FirVisitor<out R, in D> {
|
||||
return visitUnknownTypeExpression(whenSubjectExpression, data)
|
||||
}
|
||||
|
||||
open fun visitWrappedExpression(wrappedExpression: FirWrappedExpression, data: D): R {
|
||||
return visitExpression(wrappedExpression, data)
|
||||
}
|
||||
|
||||
open fun visitWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression, data: D): R {
|
||||
return visitExpression(wrappedArgumentExpression, data)
|
||||
return visitWrappedExpression(wrappedArgumentExpression, data)
|
||||
}
|
||||
|
||||
open fun visitLambdaArgumentExpression(lambdaArgumentExpression: FirLambdaArgumentExpression, data: D): R {
|
||||
@@ -336,6 +340,10 @@ abstract class FirVisitor<out R, in D> {
|
||||
return visitWrappedArgumentExpression(spreadArgumentExpression, data)
|
||||
}
|
||||
|
||||
open fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression, data: D): R {
|
||||
return visitWrappedExpression(wrappedDelegateExpression, data)
|
||||
}
|
||||
|
||||
open fun visitClass(klass: FirClass, data: D): R {
|
||||
return visitStatement(klass, data)
|
||||
}
|
||||
|
||||
+17
-1
@@ -320,8 +320,12 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitUnknownTypeExpression(whenSubjectExpression, null)
|
||||
}
|
||||
|
||||
open fun visitWrappedExpression(wrappedExpression: FirWrappedExpression) {
|
||||
visitExpression(wrappedExpression, null)
|
||||
}
|
||||
|
||||
open fun visitWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression) {
|
||||
visitExpression(wrappedArgumentExpression, null)
|
||||
visitWrappedExpression(wrappedArgumentExpression, null)
|
||||
}
|
||||
|
||||
open fun visitLambdaArgumentExpression(lambdaArgumentExpression: FirLambdaArgumentExpression) {
|
||||
@@ -336,6 +340,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitWrappedArgumentExpression(spreadArgumentExpression, null)
|
||||
}
|
||||
|
||||
open fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression) {
|
||||
visitWrappedExpression(wrappedDelegateExpression, null)
|
||||
}
|
||||
|
||||
open fun visitClass(klass: FirClass) {
|
||||
visitStatement(klass, null)
|
||||
}
|
||||
@@ -872,6 +880,14 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitWrappedArgumentExpression(wrappedArgumentExpression)
|
||||
}
|
||||
|
||||
final override fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression, data: Nothing?) {
|
||||
visitWrappedDelegateExpression(wrappedDelegateExpression)
|
||||
}
|
||||
|
||||
final override fun visitWrappedExpression(wrappedExpression: FirWrappedExpression, data: Nothing?) {
|
||||
visitWrappedExpression(wrappedExpression)
|
||||
}
|
||||
|
||||
final override fun visitElement(element: FirElement, data: Nothing?) {
|
||||
visitElement(element)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user