From 23fbb0df62a4e6af0f23b270c97ebf20ecc0d29c Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Mon, 27 Jan 2020 15:17:54 +0700 Subject: [PATCH] [Interop] Refactor IrProviderForInteropStubs 1. Move to separate package that will hold all interop providers. 2. Fix origin computation --- .../kotlin/backend/konan/ToplevelPhases.kt | 5 +- .../konan/ir/IrProviderForInteropStubs.kt | 107 -------------- .../ir/interop/IrProviderForInteropStubs.kt | 131 ++++++++++++++++++ 3 files changed, 134 insertions(+), 109 deletions(-) delete mode 100644 backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/IrProviderForInteropStubs.kt create mode 100644 backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForInteropStubs.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt index f4b38af573f..6aa3ad3e455 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt @@ -8,7 +8,7 @@ import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary -import org.jetbrains.kotlin.backend.konan.ir.IrProviderForInteropStubs +import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForInteropStubs import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier @@ -201,7 +201,8 @@ internal val psiToIrPhase = konanUnitPhase( val functionIrClassFactory = BuiltInFictitiousFunctionIrClassFactory( symbolTable, generatorContext.irBuiltIns, reflectionTypes) - val irProviderForInteropStubs = IrProviderForInteropStubs() + // TODO: Add special handling for enums and structs. + val irProviderForInteropStubs = IrProviderForInteropStubs { false } val symbols = KonanSymbols(this, symbolTable, symbolTable.lazyWrapper, functionIrClassFactory) val stubGenerator = DeclarationStubGenerator( moduleDescriptor, symbolTable, diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/IrProviderForInteropStubs.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/IrProviderForInteropStubs.kt deleted file mode 100644 index 92fdf319418..00000000000 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/IrProviderForInteropStubs.kt +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the LICENSE file. - */ -package org.jetbrains.kotlin.backend.konan.ir - -import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary -import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.lazy.* -import org.jetbrains.kotlin.ir.symbols.* -import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.resolve.descriptorUtil.module - -/** - * Generates external IR declarations for descriptors from interop libraries. - */ -class IrProviderForInteropStubs : LazyIrProvider { - - override lateinit var declarationStubGenerator: DeclarationStubGenerator - - override fun getDeclaration(symbol: IrSymbol): IrLazyDeclarationBase? = - if (symbol.descriptor.module.isFromInteropLibrary()) { - provideIrDeclaration(symbol) - } else { - null - } - - private fun provideIrDeclaration(symbol: IrSymbol): IrLazyDeclarationBase = when (symbol) { - is IrSimpleFunctionSymbol -> provideIrFunction(symbol) - is IrPropertySymbol -> provideIrProperty(symbol) - is IrTypeAliasSymbol -> provideIrTypeAlias(symbol) - is IrClassSymbol -> provideIrClass(symbol) - is IrConstructorSymbol -> provideIrConstructor(symbol) - else -> error("Unsupported interop declaration: symbol=$symbol, descriptor=${symbol.descriptor}") - } - - private fun provideIrFunction(symbol: IrSimpleFunctionSymbol): IrLazyFunction = - declarationStubGenerator.symbolTable.declareSimpleFunction( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, - symbol.descriptor, this::createFunctionDeclaration - ) as IrLazyFunction - - private fun createFunctionDeclaration(symbol: IrSimpleFunctionSymbol) = - IrLazyFunction( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, - symbol, declarationStubGenerator, declarationStubGenerator.typeTranslator - ) - - private fun provideIrProperty(symbol: IrPropertySymbol): IrLazyProperty = - declarationStubGenerator.symbolTable.declareProperty( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, - symbol.descriptor, propertyFactory = this::createPropertyDeclaration - ) as IrLazyProperty - - private fun provideIrClass(symbol: IrClassSymbol): IrLazyClass = - declarationStubGenerator.symbolTable.declareClass( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, - symbol.descriptor, classFactory = this::createClassDeclaration - ) as IrLazyClass - - private fun provideIrConstructor(symbol: IrConstructorSymbol): IrLazyConstructor = - declarationStubGenerator.symbolTable.declareConstructor( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, - symbol.descriptor, constructorFactory = this::createConstructorDeclaration - ) as IrLazyConstructor - - private fun createPropertyDeclaration(symbol: IrPropertySymbol) = - IrLazyProperty( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, - symbol, declarationStubGenerator, declarationStubGenerator.typeTranslator, null - ) - - private fun provideIrTypeAlias(symbol: IrTypeAliasSymbol): IrLazyTypeAlias = - declarationStubGenerator.symbolTable.declareTypeAlias( - symbol.descriptor, this::createTypeAlias - ) as IrLazyTypeAlias - - private fun createTypeAlias(symbol: IrTypeAliasSymbol): IrLazyTypeAlias = - IrLazyTypeAlias( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, - symbol, symbol.descriptor.name, - symbol.descriptor.visibility, symbol.descriptor.isActual, - declarationStubGenerator, declarationStubGenerator.typeTranslator - ) - - private fun createClassDeclaration(symbol: IrClassSymbol): IrLazyClass = - IrLazyClass( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, - symbol, declarationStubGenerator, declarationStubGenerator.typeTranslator - ) - - private fun createConstructorDeclaration(symbol: IrConstructorSymbol): IrLazyConstructor = - IrLazyConstructor( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, - symbol, declarationStubGenerator, declarationStubGenerator.typeTranslator - ) -} \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForInteropStubs.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForInteropStubs.kt new file mode 100644 index 00000000000..65101baa3d3 --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForInteropStubs.kt @@ -0,0 +1,131 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ +package org.jetbrains.kotlin.backend.konan.ir.interop + +import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.lazy.* +import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.resolve.descriptorUtil.module + +/** + * Generates external IR declarations for descriptors from interop libraries. + * [isSpecialInteropCase] allows to delegate providing of interop symbols to other providers. + * For example, for CEnums we need to generate non-lazy IR. + */ +class IrProviderForInteropStubs( + private val isSpecialInteropCase: (IrSymbol) -> Boolean +) : LazyIrProvider { + + override lateinit var declarationStubGenerator: DeclarationStubGenerator + + override fun getDeclaration(symbol: IrSymbol): IrLazyDeclarationBase? = + when { + // TODO: LazyIrProvider appears to be a bad interface. + // Incoming symbol might be already bound and we need to return its current owner. + // The problem is that it isn't necessary a LazyIr declaration. + // So for now we relate on correct behavior of subsequent providers. + symbol.isBound -> null + isSpecialInteropCase(symbol) -> null + symbol.descriptor.module.isFromInteropLibrary() -> provideIrDeclaration(symbol) + else -> null + } + + private fun provideIrDeclaration(symbol: IrSymbol): IrLazyDeclarationBase = when (symbol) { + is IrSimpleFunctionSymbol -> provideIrFunction(symbol) + is IrPropertySymbol -> provideIrProperty(symbol) + is IrTypeAliasSymbol -> provideIrTypeAlias(symbol) + is IrClassSymbol -> provideIrClass(symbol) + is IrConstructorSymbol -> provideIrConstructor(symbol) + is IrFieldSymbol -> provideIrField(symbol) + else -> error("Unsupported interop declaration: symbol=$symbol, descriptor=${symbol.descriptor}") + } + + private fun provideIrFunction(symbol: IrSimpleFunctionSymbol): IrLazyFunction { + val origin = computeOrigin(symbol.descriptor) + return declarationStubGenerator.symbolTable.declareSimpleFunction( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, symbol.descriptor + ) { + IrLazyFunction( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, + declarationStubGenerator, declarationStubGenerator.typeTranslator + ) + } as IrLazyFunction + } + + private fun provideIrProperty(symbol: IrPropertySymbol): IrLazyProperty { + val origin = computeOrigin(symbol.descriptor) + return declarationStubGenerator.symbolTable.declareProperty( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, symbol.descriptor + ) { + IrLazyProperty( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, symbol, + declarationStubGenerator, declarationStubGenerator.typeTranslator, null + ) + } as IrLazyProperty + } + + private fun provideIrClass(symbol: IrClassSymbol): IrLazyClass { + val origin = computeOrigin(symbol.descriptor) + return declarationStubGenerator.symbolTable.declareClass( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, symbol.descriptor + ) { + IrLazyClass( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, symbol, + declarationStubGenerator, declarationStubGenerator.typeTranslator + ) + } as IrLazyClass + } + + private fun provideIrConstructor(symbol: IrConstructorSymbol): IrLazyConstructor { + val origin = computeOrigin(symbol.descriptor) + return declarationStubGenerator.symbolTable.declareConstructor( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, symbol.descriptor + ) { + IrLazyConstructor( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, symbol, + declarationStubGenerator, declarationStubGenerator.typeTranslator + ) + } as IrLazyConstructor + } + + private fun provideIrTypeAlias(symbol: IrTypeAliasSymbol): IrLazyTypeAlias = + declarationStubGenerator.symbolTable.declareTypeAlias(symbol.descriptor) { + IrLazyTypeAlias( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + computeOrigin(symbol.descriptor), + symbol, symbol.descriptor.name, + symbol.descriptor.visibility, symbol.descriptor.isActual, + declarationStubGenerator, declarationStubGenerator.typeTranslator + ) + } as IrLazyTypeAlias + + private fun provideIrField(symbol: IrFieldSymbol): IrLazyField { + val type = declarationStubGenerator.typeTranslator.translateType(symbol.descriptor.type) + val origin = computeOrigin(symbol.descriptor) + return declarationStubGenerator.symbolTable.declareField( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, symbol.descriptor, type + ) { + IrLazyField( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, + symbol, declarationStubGenerator, declarationStubGenerator.typeTranslator + ) + } as IrLazyField + } + + private fun computeOrigin(descriptor: DeclarationDescriptor): IrDeclarationOrigin { + val nonDefaultOrigin = when (descriptor) { + is CallableMemberDescriptor -> if (descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) + IrDeclarationOrigin.FAKE_OVERRIDE else null + else -> null + } + return nonDefaultOrigin ?: IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB + } + +} \ No newline at end of file