[Interop] Refactor IrProviderForInteropStubs

1. Move to separate package that will hold all interop providers.
2. Fix origin computation
This commit is contained in:
Sergey Bogolepov
2020-01-27 15:17:54 +07:00
committed by Sergey Bogolepov
parent 3574c4ea19
commit 23fbb0df62
3 changed files with 134 additions and 109 deletions
@@ -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,
@@ -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
)
}
@@ -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
}
}