From fcdbffde3f21ea532f2dae0b41526adcd7b8ec60 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 3 Apr 2020 15:59:36 +0300 Subject: [PATCH] [FIR2IR] Support Java synthetic properties --- .../kotlin/fir/backend/ConversionUtils.kt | 17 ++++++++++++++--- .../generators/CallAndReferenceGenerator.kt | 7 ++++++- .../javaSyntheticGenericPropertyAccess.fir.txt | 12 ++++++------ .../javaSyntheticPropertyAccess.fir.txt | 12 ++++++------ .../irText/stubs/javaSyntheticProperty.fir.txt | 11 ----------- .../ir/irText/stubs/javaSyntheticProperty.kt | 1 + .../stubs/jdkClassSyntheticProperty.fir.txt | 2 +- 7 files changed, 34 insertions(+), 28 deletions(-) delete mode 100644 compiler/testData/ir/irText/stubs/javaSyntheticProperty.fir.txt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 1bdd90214c9..f2ca2b2c76d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirVariable +import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.expressions.FirConstExpression import org.jetbrains.kotlin.fir.expressions.FirConstKind import org.jetbrains.kotlin.fir.psi @@ -97,7 +98,8 @@ fun FirReference.toSymbol( session: FirSession, classifierStorage: Fir2IrClassifierStorage, declarationStorage: Fir2IrDeclarationStorage, - conversionScope: Fir2IrConversionScope + conversionScope: Fir2IrConversionScope, + preferGetter: Boolean = true ): IrSymbol? { return when (this) { is FirResolvedNamedReference -> { @@ -105,7 +107,7 @@ fun FirReference.toSymbol( is FirCallableSymbol<*> -> { val originalCallableSymbol = resolvedSymbol.overriddenSymbol?.takeIf { it.callableId == resolvedSymbol.callableId } ?: resolvedSymbol - originalCallableSymbol.toSymbol(declarationStorage) + originalCallableSymbol.toSymbol(declarationStorage, preferGetter) } is FirClassifierSymbol<*> -> { resolvedSymbol.toSymbol(session, classifierStorage) @@ -130,8 +132,17 @@ fun FirReference.toSymbol( } } -private fun FirCallableSymbol<*>.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbol? = when (this) { +private fun FirCallableSymbol<*>.toSymbol(declarationStorage: Fir2IrDeclarationStorage, preferGetter: Boolean): IrSymbol? = when (this) { is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this) + is SyntheticPropertySymbol -> { + (fir as? FirSyntheticProperty)?.let { syntheticProperty -> + if (preferGetter) { + syntheticProperty.getter.delegate.symbol.toSymbol(declarationStorage, preferGetter) + } else { + syntheticProperty.setter!!.delegate.symbol.toSymbol(declarationStorage, preferGetter) + } + } ?: if (fir.isLocal) declarationStorage.getIrValueSymbol(this) else declarationStorage.getIrPropertyOrFieldSymbol(this) + } is FirPropertySymbol -> { if (fir.isLocal) declarationStorage.getIrValueSymbol(this) else declarationStorage.getIrPropertyOrFieldSymbol(this) } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 101a91f6774..6a50cbb25a6 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -193,7 +193,7 @@ internal class CallAndReferenceGenerator( fun convertToIrSetCall(variableAssignment: FirVariableAssignment): IrExpression { val type = irBuiltIns.unitType val calleeReference = variableAssignment.calleeReference - val symbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope) + val symbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope, preferGetter = false) val origin = IrStatementOrigin.EQ return variableAssignment.convertWithOffsets { startOffset, endOffset -> val assignedValue = visitor.convertToIrExpression(variableAssignment.rValue) @@ -216,6 +216,11 @@ internal class CallAndReferenceGenerator( else -> generateErrorCallExpression(startOffset, endOffset, calleeReference) } } + is IrSimpleFunctionSymbol -> { + IrCallImpl(startOffset, endOffset, type, symbol, origin).apply { + putValueArgument(0, assignedValue) + } + } is IrVariableSymbol -> IrSetVariableImpl(startOffset, endOffset, type, symbol, assignedValue, origin) else -> generateErrorCallExpression(startOffset, endOffset, calleeReference) } diff --git a/compiler/testData/ir/irText/expressions/javaSyntheticGenericPropertyAccess.fir.txt b/compiler/testData/ir/irText/expressions/javaSyntheticGenericPropertyAccess.fir.txt index 29f3668ba25..1329db49282 100644 --- a/compiler/testData/ir/irText/expressions/javaSyntheticGenericPropertyAccess.fir.txt +++ b/compiler/testData/ir/irText/expressions/javaSyntheticGenericPropertyAccess.fir.txt @@ -3,22 +3,22 @@ FILE fqName: fileName:/javaSyntheticGenericPropertyAccess.kt TYPE_PARAMETER name:F index:0 variance: superTypes:[kotlin.Any?] VALUE_PARAMETER name:j index:0 type:.J.test> BLOCK_BODY - CALL 'public open fun (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY + CALL 'public open fun getFoo (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY $this: GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null - CALL 'public open fun (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ + CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ $this: GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null x: CONST Int type=kotlin.Int value=1 VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] - CALL 'public open fun (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY + CALL 'public open fun getFoo (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY $this: GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null - CALL 'public open fun (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ + CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ $this: GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null x: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null - CALL 'public open fun (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ + CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ $this: GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null x: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CALL 'public open fun (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY + $this: CALL 'public open fun getFoo (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY $this: GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null other: CONST Int type=kotlin.Int value=1 diff --git a/compiler/testData/ir/irText/expressions/javaSyntheticPropertyAccess.fir.txt b/compiler/testData/ir/irText/expressions/javaSyntheticPropertyAccess.fir.txt index 4141f16f2a3..9f9196e3d52 100644 --- a/compiler/testData/ir/irText/expressions/javaSyntheticPropertyAccess.fir.txt +++ b/compiler/testData/ir/irText/expressions/javaSyntheticPropertyAccess.fir.txt @@ -2,22 +2,22 @@ FILE fqName: fileName:/javaSyntheticPropertyAccess.kt FUN name:test visibility:public modality:FINAL <> (j:.J) returnType:kotlin.Unit VALUE_PARAMETER name:j index:0 type:.J BLOCK_BODY - CALL 'public open fun (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY + CALL 'public open fun getFoo (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY $this: GET_VAR 'j: .J declared in .test' type=.J origin=null - CALL 'public open fun (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ + CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ $this: GET_VAR 'j: .J declared in .test' type=.J origin=null x: CONST Int type=kotlin.Int value=1 VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] - CALL 'public open fun (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY + CALL 'public open fun getFoo (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY $this: GET_VAR 'j: .J declared in .test' type=.J origin=null - CALL 'public open fun (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ + CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ $this: GET_VAR 'j: .J declared in .test' type=.J origin=null x: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null - CALL 'public open fun (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ + CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ $this: GET_VAR 'j: .J declared in .test' type=.J origin=null x: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CALL 'public open fun (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY + $this: CALL 'public open fun getFoo (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY $this: GET_VAR 'j: .J declared in .test' type=.J origin=null other: CONST Int type=kotlin.Int value=1 diff --git a/compiler/testData/ir/irText/stubs/javaSyntheticProperty.fir.txt b/compiler/testData/ir/irText/stubs/javaSyntheticProperty.fir.txt deleted file mode 100644 index 29327f42799..00000000000 --- a/compiler/testData/ir/irText/stubs/javaSyntheticProperty.fir.txt +++ /dev/null @@ -1,11 +0,0 @@ -FILE fqName: fileName:/javaSyntheticProperty.kt - PROPERTY name:test visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:test type:kotlin.String? visibility:private [final,static] - EXPRESSION_BODY - CALL 'public open fun (): kotlin.String? declared in .J' type=kotlin.String? origin=GET_PROPERTY - $this: CONSTRUCTOR_CALL 'public/*package*/ constructor () [primary] declared in .J' type=.J origin=null - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.String? - correspondingProperty: PROPERTY name:test visibility:public modality:FINAL [val] - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.String? declared in ' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test type:kotlin.String? visibility:private [final,static]' type=kotlin.String? origin=null diff --git a/compiler/testData/ir/irText/stubs/javaSyntheticProperty.kt b/compiler/testData/ir/irText/stubs/javaSyntheticProperty.kt index 3fed59d2988..682ee0fbff0 100644 --- a/compiler/testData/ir/irText/stubs/javaSyntheticProperty.kt +++ b/compiler/testData/ir/irText/stubs/javaSyntheticProperty.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DUMP_DEPENDENCIES // FILE: javaSyntheticProperty.kt val test = J().foo diff --git a/compiler/testData/ir/irText/stubs/jdkClassSyntheticProperty.fir.txt b/compiler/testData/ir/irText/stubs/jdkClassSyntheticProperty.fir.txt index d15468d56d6..9ae156405a8 100644 --- a/compiler/testData/ir/irText/stubs/jdkClassSyntheticProperty.fir.txt +++ b/compiler/testData/ir/irText/stubs/jdkClassSyntheticProperty.fir.txt @@ -5,5 +5,5 @@ FILE fqName: fileName:/jdkClassSyntheticProperty.kt $receiver: VALUE_PARAMETER name: type:java.lang.Class<*> BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun (): kotlin.Array? declared in ' - CALL 'public open fun (): kotlin.Array? declared in java.lang.Class' type=kotlin.Array? origin=GET_PROPERTY + CALL 'public open fun getDeclaredFields (): kotlin.Array? declared in java.lang.Class' type=kotlin.Array? origin=GET_PROPERTY $this: GET_VAR ': java.lang.Class<*> declared in .' type=java.lang.Class<*> origin=null