From b28207decae04e2eba545016a559d44d58a87e39 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 15 May 2019 17:44:55 +0300 Subject: [PATCH] FIR2IR: support fields in Java FIR --- .../kotlin/fir/backend/ConversionUtils.kt | 6 +-- .../fir/backend/Fir2IrDeclarationStorage.kt | 46 +++++++++++++++++-- .../kotlin/fir/backend/Fir2IrVisitor.kt | 1 + compiler/testData/cli/jvm/firHello.kt | 1 + .../ir/irText/declarations/kt29833.fir.txt | 4 +- .../irText/expressions/coercionToUnit.fir.txt | 4 +- .../jvmInstanceFieldReference.fir.txt | 8 ++-- .../jvmStaticFieldReference.fir.txt | 10 ++-- .../ir/irText/expressions/kt16904.fir.txt | 3 +- .../expressions/propertyReferences.fir.txt | 4 +- .../setFieldWithImplicitCast.fir.txt | 3 +- .../testData/ir/irText/stubs/javaEnum.fir.txt | 2 +- 12 files changed, 67 insertions(+), 25 deletions(-) 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 7374537a9a1..39eb4078e57 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 @@ -105,7 +105,7 @@ fun FirNamedReference.toSymbol(declarationStorage: Fir2IrDeclarationStorage): Ir if (this is FirResolvedCallableReference) { when (val callableSymbol = this.coneSymbol) { is FirFunctionSymbol -> return callableSymbol.toFunctionSymbol(declarationStorage) - is FirPropertySymbol -> return callableSymbol.toPropertySymbol(declarationStorage) + is FirPropertySymbol -> return callableSymbol.toPropertyOrFieldSymbol(declarationStorage) is FirVariableSymbol -> return callableSymbol.toValueSymbol(declarationStorage) } } @@ -124,8 +124,8 @@ fun FirFunctionSymbol.toFunctionSymbol(declarationStorage: Fir2IrDeclarationStor return declarationStorage.getIrFunctionSymbol(this) } -fun FirPropertySymbol.toPropertySymbol(declarationStorage: Fir2IrDeclarationStorage): IrPropertySymbol { - return declarationStorage.getIrPropertySymbol(this) +fun FirPropertySymbol.toPropertyOrFieldSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbol { + return declarationStorage.getIrPropertyOrFieldSymbol(this) } fun FirVariableSymbol.toValueSymbol(declarationStorage: Fir2IrDeclarationStorage): IrValueSymbol { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 1b24489db36..01a807af6e6 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -48,6 +48,8 @@ class Fir2IrDeclarationStorage( private val propertyCache = mutableMapOf() + private val fieldCache = mutableMapOf() + private val localStorage = Fir2IrLocalStorage() fun enterScope(descriptor: DeclarationDescriptor) { @@ -358,6 +360,30 @@ class Fir2IrDeclarationStorage( } } + private fun getIrField(field: FirField): IrField { + return fieldCache.getOrPut(field) { + val descriptor = WrappedFieldDescriptor() + val origin = IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB + val type = field.returnTypeRef.toIrType(session, this) + field.convertWithOffsets { startOffset, endOffset -> + irSymbolTable.declareField( + startOffset, endOffset, + origin, descriptor, type + ) { symbol -> + IrFieldImpl( + startOffset, endOffset, origin, symbol, + field.name, type, field.visibility, + isFinal = field.modality == Modality.FINAL, + isExternal = false, + isStatic = field.isStatic + ).apply { + descriptor.bind(this) + } + } + } + } + } + private fun createAndSaveIrParameter(valueParameter: FirValueParameter, index: Int = -1): IrValueParameter { val descriptor = WrappedValueParameterDescriptor() val origin = IrDeclarationOrigin.DEFINED @@ -453,12 +479,22 @@ class Fir2IrDeclarationStorage( } } - fun getIrPropertySymbol(firPropertySymbol: FirPropertySymbol): IrPropertySymbol { - val firProperty = firPropertySymbol.fir as FirProperty - val irProperty = getIrProperty(firProperty).apply { - setAndModifyParent(findIrParent(firProperty)) + fun getIrPropertyOrFieldSymbol(firPropertySymbol: FirPropertySymbol): IrSymbol { + return when (val fir = firPropertySymbol.fir) { + is FirProperty -> { + val irProperty = getIrProperty(fir).apply { + setAndModifyParent(findIrParent(fir)) + } + irSymbolTable.referenceProperty(irProperty.descriptor) + } + is FirField -> { + val irField = getIrField(fir).apply { + setAndModifyParent(findIrParent(fir)) + } + irSymbolTable.referenceField(irField.descriptor) + } + else -> throw IllegalArgumentException("Unexpected fir in property symbol: ${fir.render()}") } - return irSymbolTable.referenceProperty(irProperty.descriptor) } private fun getIrVariableSymbol(firVariable: FirVariable): IrVariableSymbol { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index e8833fbc3ca..138bc103e63 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -654,6 +654,7 @@ internal class Fir2IrVisitor( IrErrorCallExpressionImpl(startOffset, endOffset, type, "No getter found for ${calleeReference.render()}") } } + symbol is IrFieldSymbol -> IrGetFieldImpl(startOffset, endOffset, symbol, type, origin = IrStatementOrigin.GET_PROPERTY) symbol is IrValueSymbol -> IrGetValueImpl( startOffset, endOffset, type, symbol, if (calleeReference is FirPropertyFromParameterCallableReference) { diff --git a/compiler/testData/cli/jvm/firHello.kt b/compiler/testData/cli/jvm/firHello.kt index f9f883a2ec7..ec9c9d29e05 100644 --- a/compiler/testData/cli/jvm/firHello.kt +++ b/compiler/testData/cli/jvm/firHello.kt @@ -7,6 +7,7 @@ class E(s: String) : Exception(s) { fun main(args: Array) { if (box() == "OK") { + System.out.println("Hello") throw E("Hello") } } \ No newline at end of file diff --git a/compiler/testData/ir/irText/declarations/kt29833.fir.txt b/compiler/testData/ir/irText/declarations/kt29833.fir.txt index ff1af81bd4d..090e91574da 100644 --- a/compiler/testData/ir/irText/declarations/kt29833.fir.txt +++ b/compiler/testData/ir/irText/declarations/kt29833.fir.txt @@ -8,7 +8,7 @@ FILE fqName:interop fileName:/Definitions.kt PROPERTY name:KT_CONSTANT visibility:public modality:FINAL [const,val] FIELD PROPERTY_BACKING_FIELD name:KT_CONSTANT type:kotlin.String? visibility:public [final] EXPRESSION_BODY - ERROR_CALL 'No getter found for R|interop/Interface.CONSTANT|' type=kotlin.String? + GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:CONSTANT type:kotlin.String? visibility:public [final,static] ' type=kotlin.String? origin=GET_PROPERTY FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:interop.Definitions) returnType:kotlin.String? correspondingProperty: PROPERTY name:KT_CONSTANT visibility:public modality:FINAL [const,val] $this: VALUE_PARAMETER name: type:interop.Definitions @@ -19,7 +19,7 @@ FILE fqName:interop fileName:/Definitions.kt PROPERTY name:ktValue visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:ktValue type:kotlin.String? visibility:public [final] EXPRESSION_BODY - ERROR_CALL 'No getter found for R|interop/Interface.CONSTANT|' type=kotlin.String? + GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:CONSTANT type:kotlin.String? visibility:public [final,static] ' type=kotlin.String? origin=GET_PROPERTY FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:interop.Definitions) returnType:kotlin.String? correspondingProperty: PROPERTY name:ktValue visibility:public modality:FINAL [val] $this: VALUE_PARAMETER name: type:interop.Definitions diff --git a/compiler/testData/ir/irText/expressions/coercionToUnit.fir.txt b/compiler/testData/ir/irText/expressions/coercionToUnit.fir.txt index 56c025976cf..b6d8de41f0e 100644 --- a/compiler/testData/ir/irText/expressions/coercionToUnit.fir.txt +++ b/compiler/testData/ir/irText/expressions/coercionToUnit.fir.txt @@ -21,9 +21,9 @@ FILE fqName: fileName:/coercionToUnit.kt FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY CALL 'public open fun println (x: kotlin.String?): kotlin.Unit declared in java.io.PrintStream' type=kotlin.Unit origin=null - $this: ERROR_CALL 'No getter found for R|java/lang/System.out|' type=java.io.PrintStream? + $this: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:out type:java.io.PrintStream? visibility:public [final,static] ' type=java.io.PrintStream? origin=GET_PROPERTY x: CONST String type=kotlin.String value="Hello," CALL 'public open fun println (x: kotlin.String?): kotlin.Unit declared in java.io.PrintStream' type=kotlin.Unit origin=null - $this: ERROR_CALL 'No getter found for R|java/lang/System.out|' type=java.io.PrintStream? + $this: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:out type:java.io.PrintStream? visibility:public [final,static] ' type=java.io.PrintStream? origin=GET_PROPERTY x: CONST String type=kotlin.String value="world!" diff --git a/compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.fir.txt b/compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.fir.txt index 4a9166292ce..141a6588102 100644 --- a/compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.fir.txt +++ b/compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.fir.txt @@ -7,17 +7,19 @@ FILE fqName: fileName:/Derived.kt INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Derived modality:FINAL visibility:public superTypes:[.Base]' ANONYMOUS_INITIALIZER isStatic=false BLOCK_BODY - ERROR_CALL 'Unresolved reference: R|/Base.value|' type=IrErrorType + SET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:value type:kotlin.Int visibility:public ' type=kotlin.Int origin=null + value: CONST Int type=kotlin.Int value=0 FUN name:getValue visibility:public modality:FINAL <> ($this:.Derived) returnType:kotlin.Int $this: VALUE_PARAMETER name: type:.Derived BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun getValue (): kotlin.Int declared in .Derived' - ERROR_CALL 'No getter found for R|/Base.value|' type=kotlin.Int + GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:value type:kotlin.Int visibility:public ' type=kotlin.Int origin=GET_PROPERTY FUN name:setValue visibility:public modality:FINAL <> ($this:.Derived, value:kotlin.Int) returnType:kotlin.Unit $this: VALUE_PARAMETER name: type:.Derived VALUE_PARAMETER name:value index:0 type:kotlin.Int BLOCK_BODY - ERROR_CALL 'Unresolved reference: R|/Base.value|' type=IrErrorType + SET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:value type:kotlin.Int visibility:public ' type=kotlin.Int origin=null + value: GET_VAR 'value: kotlin.Int declared in .Derived.setValue' type=kotlin.Int origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any diff --git a/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.fir.txt b/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.fir.txt index d71a3e281bf..075a69d3147 100644 --- a/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.fir.txt +++ b/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.fir.txt @@ -2,14 +2,14 @@ FILE fqName: fileName:/jvmStaticFieldReference.kt FUN name:testFun visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY CALL 'public open fun println (x: kotlin.String?): kotlin.Unit declared in java.io.PrintStream' type=kotlin.Unit origin=null - $this: ERROR_CALL 'No getter found for R|java/lang/System.out|' type=java.io.PrintStream? + $this: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:out type:java.io.PrintStream? visibility:public [final,static] ' type=java.io.PrintStream? origin=GET_PROPERTY x: CONST String type=kotlin.String value="testFun" PROPERTY name:testProp visibility:public modality:FINAL [var] FUN name: visibility:public modality:FINAL <> () returnType:kotlin.Any correspondingProperty: PROPERTY name:testProp visibility:public modality:FINAL [var] BLOCK_BODY CALL 'public open fun println (x: kotlin.String?): kotlin.Unit declared in java.io.PrintStream' type=kotlin.Unit origin=null - $this: ERROR_CALL 'No getter found for R|java/lang/System.out|' type=java.io.PrintStream? + $this: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:out type:java.io.PrintStream? visibility:public [final,static] ' type=java.io.PrintStream? origin=GET_PROPERTY x: CONST String type=kotlin.String value="testProp/get" RETURN type=kotlin.Nothing from='public final fun (): kotlin.Any declared in ' CONST Int type=kotlin.Any value=42 @@ -18,7 +18,7 @@ FILE fqName: fileName:/jvmStaticFieldReference.kt VALUE_PARAMETER name:value index:0 type:kotlin.Any BLOCK_BODY CALL 'public open fun println (x: kotlin.String?): kotlin.Unit declared in java.io.PrintStream' type=kotlin.Unit origin=null - $this: ERROR_CALL 'No getter found for R|java/lang/System.out|' type=java.io.PrintStream? + $this: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:out type:java.io.PrintStream? visibility:public [final,static] ' type=java.io.PrintStream? origin=GET_PROPERTY x: CONST String type=kotlin.String value="testProp/set" CLASS CLASS name:TestClass modality:FINAL visibility:public superTypes:[kotlin.Any] $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.TestClass @@ -34,7 +34,7 @@ FILE fqName: fileName:/jvmStaticFieldReference.kt if: CONST Boolean type=kotlin.Boolean value=true then: BLOCK type=kotlin.Int origin=null CALL 'public open fun println (x: kotlin.String?): kotlin.Unit declared in java.io.PrintStream' type=kotlin.Unit origin=null - $this: ERROR_CALL 'No getter found for R|java/lang/System.out|' type=java.io.PrintStream? + $this: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:out type:java.io.PrintStream? visibility:public [final,static] ' type=java.io.PrintStream? origin=GET_PROPERTY x: CONST String type=kotlin.String value="TestClass/test" CONST Int type=kotlin.Int value=42 FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.TestClass) returnType:kotlin.Int @@ -47,7 +47,7 @@ FILE fqName: fileName:/jvmStaticFieldReference.kt ANONYMOUS_INITIALIZER isStatic=false BLOCK_BODY CALL 'public open fun println (x: kotlin.String?): kotlin.Unit declared in java.io.PrintStream' type=kotlin.Unit origin=null - $this: ERROR_CALL 'No getter found for R|java/lang/System.out|' type=java.io.PrintStream? + $this: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:out type:java.io.PrintStream? visibility:public [final,static] ' type=java.io.PrintStream? origin=GET_PROPERTY x: CONST String type=kotlin.String value="TestClass/init" FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean overridden: diff --git a/compiler/testData/ir/irText/expressions/kt16904.fir.txt b/compiler/testData/ir/irText/expressions/kt16904.fir.txt index bb31ccfc75c..ca54d632b18 100644 --- a/compiler/testData/ir/irText/expressions/kt16904.fir.txt +++ b/compiler/testData/ir/irText/expressions/kt16904.fir.txt @@ -102,7 +102,8 @@ FILE fqName: fileName:/kt16904.kt INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test2 modality:FINAL visibility:public superTypes:[.J]' ANONYMOUS_INITIALIZER isStatic=false BLOCK_BODY - ERROR_CALL 'Unresolved reference: R|/J.field|' type=IrErrorType + SET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:field type:kotlin.Int visibility:public ' type=kotlin.Int origin=null + value: CONST Int type=kotlin.Int value=42 FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any diff --git a/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt b/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt index fb2bde39def..476146a319c 100644 --- a/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt +++ b/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt @@ -238,7 +238,7 @@ FILE fqName: fileName:/propertyReferences.kt PROPERTY name:test_J_CONST visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:kotlin.Int visibility:public [final,static] EXPRESSION_BODY - ERROR_CALL 'No getter found for R|/J.CONST|' type=kotlin.Int + GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:CONST type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=GET_PROPERTY FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Int correspondingProperty: PROPERTY name:test_J_CONST visibility:public modality:FINAL [val] BLOCK_BODY @@ -247,7 +247,7 @@ FILE fqName: fileName:/propertyReferences.kt PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.Int visibility:public [final,static] EXPRESSION_BODY - ERROR_CALL 'No getter found for R|/J.nonConst|' type=kotlin.Int + GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:nonConst type:kotlin.Int visibility:public [static] ' type=kotlin.Int origin=GET_PROPERTY FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Int correspondingProperty: PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val] BLOCK_BODY diff --git a/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.fir.txt b/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.fir.txt index dfca91c6de5..04f9900228a 100644 --- a/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.fir.txt +++ b/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.fir.txt @@ -14,7 +14,8 @@ FILE fqName: fileName:/Derived.kt if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String GET_VAR 'v: kotlin.Any declared in .Derived.setValue' type=kotlin.Any origin=null then: BLOCK type=kotlin.Unit origin=null - ERROR_CALL 'Unresolved reference: R|/Base.value|' type=IrErrorType + SET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:value type:kotlin.String? visibility:public ' type=kotlin.String? origin=null + value: GET_VAR 'v: kotlin.Any declared in .Derived.setValue' type=kotlin.Any origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any diff --git a/compiler/testData/ir/irText/stubs/javaEnum.fir.txt b/compiler/testData/ir/irText/stubs/javaEnum.fir.txt index ce943c26733..36b7ea2da8c 100644 --- a/compiler/testData/ir/irText/stubs/javaEnum.fir.txt +++ b/compiler/testData/ir/irText/stubs/javaEnum.fir.txt @@ -2,7 +2,7 @@ FILE fqName: fileName:/javaEnum.kt PROPERTY name:test visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test type:.JEnum? visibility:public [final,static] EXPRESSION_BODY - ERROR_CALL 'No getter found for R|/JEnum.ONE|' type=.JEnum? + GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:ONE type:.JEnum? visibility:public [final,static] ' type=.JEnum? origin=GET_PROPERTY FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:.JEnum? correspondingProperty: PROPERTY name:test visibility:public modality:FINAL [val] BLOCK_BODY