[K/N] Fix K2 ObjC interop: Fields are not supported for Companion of subclass of ObjC type
^KT-63048
This commit is contained in:
committed by
Space Team
parent
3ea4a6a937
commit
4d4ad6c0d8
+6
@@ -11,10 +11,12 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
|
|||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.JvmSerializeIrMode
|
import org.jetbrains.kotlin.config.JvmSerializeIrMode
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrConversionScope
|
import org.jetbrains.kotlin.fir.backend.Fir2IrConversionScope
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
|
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
|
||||||
import org.jetbrains.kotlin.fir.backend.InjectedValue
|
import org.jetbrains.kotlin.fir.backend.InjectedValue
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
import org.jetbrains.kotlin.fir.references.FirReference
|
||||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -95,4 +97,8 @@ class JvmFir2IrExtensions(
|
|||||||
irDeserializer.deserializeTopLevelClass(
|
irDeserializer.deserializeTopLevelClass(
|
||||||
irClass, components.irBuiltIns, components.symbolTable, components.irProviders, this
|
irClass, components.irBuiltIns, components.symbolTable, components.irProviders, this
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override fun hasBackingField(property: FirProperty, session: FirSession): Boolean =
|
||||||
|
// NOTE maybe there might be platform-specific logic, similar to JvmGeneratorExtensionsImpl.isPropertyWithPlatformField()
|
||||||
|
Fir2IrExtensions.Default.hasBackingField(property, session)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.backend
|
package org.jetbrains.kotlin.fir.backend
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
import org.jetbrains.kotlin.fir.references.FirReference
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrMemberWithContainerSource
|
import org.jetbrains.kotlin.ir.declarations.IrMemberWithContainerSource
|
||||||
@@ -20,6 +23,14 @@ interface Fir2IrExtensions {
|
|||||||
fun registerDeclarations(symbolTable: SymbolTable)
|
fun registerDeclarations(symbolTable: SymbolTable)
|
||||||
fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope): InjectedValue?
|
fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope): InjectedValue?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Platform-dependent logic to determine, whether a backing field is required.
|
||||||
|
* Should be called instead of `FirProperty.hasBackingField()` to decide whether to create a backing field.
|
||||||
|
* The implementation should return `true` in case platform-dependent condition for backing field existence is met,
|
||||||
|
* otherwise return a result of Fir2IrExtensions.Default.hasBackingField()
|
||||||
|
*/
|
||||||
|
fun hasBackingField(property: FirProperty, session: FirSession): Boolean
|
||||||
|
|
||||||
object Default : Fir2IrExtensions {
|
object Default : Fir2IrExtensions {
|
||||||
override val irNeedsDeserialization: Boolean
|
override val irNeedsDeserialization: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
@@ -29,5 +40,6 @@ interface Fir2IrExtensions {
|
|||||||
override fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents): Boolean = false
|
override fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents): Boolean = false
|
||||||
override fun registerDeclarations(symbolTable: SymbolTable) {}
|
override fun registerDeclarations(symbolTable: SymbolTable) {}
|
||||||
override fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope) = null
|
override fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope) = null
|
||||||
|
override fun hasBackingField(property: FirProperty, session: FirSession): Boolean = property.hasBackingField
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ class Fir2IrLazyProperty(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fir.hasBackingField && origin != IrDeclarationOrigin.FAKE_OVERRIDE -> {
|
extensions.hasBackingField(fir, session) && origin != IrDeclarationOrigin.FAKE_OVERRIDE -> {
|
||||||
with(declarationStorage) {
|
with(declarationStorage) {
|
||||||
callablesGenerator.createBackingField(
|
callablesGenerator.createBackingField(
|
||||||
this@Fir2IrLazyProperty,
|
this@Fir2IrLazyProperty,
|
||||||
|
|||||||
+1
-1
@@ -141,7 +141,7 @@ internal fun FirFunction.getInitMethodIfObjCConstructor(session: FirSession, sco
|
|||||||
else
|
else
|
||||||
this
|
this
|
||||||
|
|
||||||
internal fun FirProperty.isExternalObjCClassProperty(session: FirSession) =
|
fun FirProperty.isExternalObjCClassProperty(session: FirSession): Boolean =
|
||||||
(containingClassLookupTag()?.toSymbol(session) as? FirClassSymbol)?.isExternalObjCClass(session) == true
|
(containingClassLookupTag()?.toSymbol(session) as? FirClassSymbol)?.isExternalObjCClass(session) == true
|
||||||
|
|
||||||
internal fun FirClassSymbol<*>.isExternalObjCClass(session: FirSession): Boolean =
|
internal fun FirClassSymbol<*>.isExternalObjCClass(session: FirSession): Boolean =
|
||||||
|
|||||||
+9
@@ -22,8 +22,12 @@ import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
|||||||
import org.jetbrains.kotlin.descriptors.isEmpty
|
import org.jetbrains.kotlin.descriptors.isEmpty
|
||||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.backend.*
|
import org.jetbrains.kotlin.fir.backend.*
|
||||||
import org.jetbrains.kotlin.fir.backend.native.FirNativeKotlinMangler
|
import org.jetbrains.kotlin.fir.backend.native.FirNativeKotlinMangler
|
||||||
|
import org.jetbrains.kotlin.fir.backend.native.interop.isExternalObjCClassProperty
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isLateInit
|
||||||
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
||||||
import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
|
import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
import org.jetbrains.kotlin.fir.references.FirReference
|
||||||
@@ -51,6 +55,11 @@ internal object NativeFir2IrExtensions : Fir2IrExtensions {
|
|||||||
override fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents) = false
|
override fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents) = false
|
||||||
override fun registerDeclarations(symbolTable: SymbolTable) {}
|
override fun registerDeclarations(symbolTable: SymbolTable) {}
|
||||||
override fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope) = null
|
override fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope) = null
|
||||||
|
override fun hasBackingField(property: FirProperty, session: FirSession): Boolean =
|
||||||
|
if (property.isExternalObjCClassProperty(session))
|
||||||
|
property.isLateInit
|
||||||
|
else
|
||||||
|
Fir2IrExtensions.Default.hasBackingField(property, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun PhaseContext.fir2Ir(
|
internal fun PhaseContext.fir2Ir(
|
||||||
|
|||||||
+4
-3
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.konan.test.blackbox.support.TestCompilerArgs
|
|||||||
import org.jetbrains.kotlin.konan.test.blackbox.support.TestKind
|
import org.jetbrains.kotlin.konan.test.blackbox.support.TestKind
|
||||||
import org.jetbrains.kotlin.konan.test.blackbox.support.compilation.TestCompilationResult.Companion.assertSuccess
|
import org.jetbrains.kotlin.konan.test.blackbox.support.compilation.TestCompilationResult.Companion.assertSuccess
|
||||||
import org.jetbrains.kotlin.konan.test.blackbox.support.group.FirPipeline
|
import org.jetbrains.kotlin.konan.test.blackbox.support.group.FirPipeline
|
||||||
import org.jetbrains.kotlin.konan.test.blackbox.support.runner.TestExecutable
|
|
||||||
import org.jetbrains.kotlin.konan.test.blackbox.support.settings.PipelineType
|
import org.jetbrains.kotlin.konan.test.blackbox.support.settings.PipelineType
|
||||||
import org.jetbrains.kotlin.test.TestMetadata
|
import org.jetbrains.kotlin.test.TestMetadata
|
||||||
import org.junit.jupiter.api.Tag
|
import org.junit.jupiter.api.Tag
|
||||||
@@ -26,9 +25,12 @@ abstract class BaseCInteropCheckersTest : AbstractNativeSimpleTest() {
|
|||||||
@Test
|
@Test
|
||||||
@TestMetadata(TEST_DATA_DIR)
|
@TestMetadata(TEST_DATA_DIR)
|
||||||
fun testBuilding() {
|
fun testBuilding() {
|
||||||
|
val defFile = File(TEST_DATA_DIR, DEF_FILE)
|
||||||
|
muteCInteropTestIfNecessary(defFile, targets.testTarget)
|
||||||
|
|
||||||
val library = cinteropToLibrary(
|
val library = cinteropToLibrary(
|
||||||
targets = targets,
|
targets = targets,
|
||||||
defFile = File(TEST_DATA_DIR, DEF_FILE),
|
defFile = defFile,
|
||||||
outputDir = buildDir,
|
outputDir = buildDir,
|
||||||
freeCompilerArgs = TestCompilerArgs.EMPTY
|
freeCompilerArgs = TestCompilerArgs.EMPTY
|
||||||
).assertSuccess().resultingArtifact
|
).assertSuccess().resultingArtifact
|
||||||
@@ -42,7 +44,6 @@ abstract class BaseCInteropCheckersTest : AbstractNativeSimpleTest() {
|
|||||||
val compilationResult = compileToExecutable(testCase, library.asLibraryDependency()).assertSuccess()
|
val compilationResult = compileToExecutable(testCase, library.asLibraryDependency()).assertSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TEST_DATA_DIR = "native/native.tests/testData/CInterop/KT-63048"
|
const val TEST_DATA_DIR = "native/native.tests/testData/CInterop/KT-63048"
|
||||||
const val DEF_FILE = "library.def"
|
const val DEF_FILE = "library.def"
|
||||||
|
|||||||
Reference in New Issue
Block a user