[K/N] Refactor KonanSymbols to avoid descriptors when built over FIR
^KT-58437
This commit is contained in:
committed by
Space Team
parent
7f9118d0f2
commit
68a68b2763
@@ -61,10 +61,10 @@ open class BuiltinSymbolsBase(val irBuiltIns: IrBuiltIns, private val symbolTabl
|
||||
// The "...OrNull" variants are used for the classes below because the minimal stdlib used in tests do not include those classes.
|
||||
// It was not feasible to add them to the JS reduced runtime because all its transitive dependencies also need to be
|
||||
// added, which would include a lot of the full stdlib.
|
||||
open val uByte = irBuiltIns.findClass(Name.identifier("UByte"), "kotlin")
|
||||
open val uShort = irBuiltIns.findClass(Name.identifier("UShort"), "kotlin")
|
||||
open val uInt = irBuiltIns.findClass(Name.identifier("UInt"), "kotlin")
|
||||
open val uLong = irBuiltIns.findClass(Name.identifier("ULong"), "kotlin")
|
||||
val uByte = irBuiltIns.findClass(Name.identifier("UByte"), "kotlin")
|
||||
val uShort = irBuiltIns.findClass(Name.identifier("UShort"), "kotlin")
|
||||
val uInt = irBuiltIns.findClass(Name.identifier("UInt"), "kotlin")
|
||||
val uLong = irBuiltIns.findClass(Name.identifier("ULong"), "kotlin")
|
||||
val uIntProgression = progressionOrNull("UIntProgression")
|
||||
val uLongProgression = progressionOrNull("ULongProgression")
|
||||
val uIntRange = progressionOrNull("UIntRange")
|
||||
|
||||
+2
-2
@@ -176,7 +176,7 @@ internal class UIntProgressionType(symbols: Symbols, allowUnsignedBounds: Boolea
|
||||
maxValueAsLong = UInt.MAX_VALUE.toLong(),
|
||||
// Uses `getProgressionLastElement(UInt, UInt, Int): UInt`
|
||||
getProgressionLastElementFunction = symbols.getProgressionLastElementByReturnType[symbols.uInt!!],
|
||||
unsignedType = symbols.uInt!!.defaultType,
|
||||
unsignedType = symbols.uInt.defaultType,
|
||||
unsignedConversionFunction = symbols.toUIntByExtensionReceiver.getValue(symbols.int)
|
||||
) {
|
||||
|
||||
@@ -192,7 +192,7 @@ internal class ULongProgressionType(symbols: Symbols, allowUnsignedBounds: Boole
|
||||
maxValueAsLong = ULong.MAX_VALUE.toLong(),
|
||||
// Uses `getProgressionLastElement(ULong, ULong, Long): ULong`
|
||||
getProgressionLastElementFunction = symbols.getProgressionLastElementByReturnType[symbols.uLong!!],
|
||||
unsignedType = symbols.uLong!!.defaultType,
|
||||
unsignedType = symbols.uLong.defaultType,
|
||||
unsignedConversionFunction = symbols.toULongByExtensionReceiver.getValue(symbols.long)
|
||||
) {
|
||||
|
||||
|
||||
+5
-9
@@ -6,7 +6,8 @@ import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDes
|
||||
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
|
||||
import org.jetbrains.kotlin.backend.konan.driver.phases.Fir2IrOutput
|
||||
import org.jetbrains.kotlin.backend.konan.driver.phases.FirOutput
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbolsOverFir
|
||||
import org.jetbrains.kotlin.backend.konan.ir.SymbolOverIrLookupUtils
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr
|
||||
@@ -28,10 +29,8 @@ import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
||||
import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
|
||||
import org.jetbrains.kotlin.fir.signaturer.Ir2FirManglerAdapter
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
|
||||
@@ -118,7 +117,7 @@ internal fun PhaseContext.fir2Ir(
|
||||
}.map { it.second }.toSet()
|
||||
|
||||
|
||||
val symbols = createKonanSymbols(irModuleFragment, components, pluginContext)
|
||||
val symbols = createKonanSymbols(components, pluginContext)
|
||||
|
||||
val renderDiagnosticNames = configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME)
|
||||
FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector, renderDiagnosticNames)
|
||||
@@ -131,13 +130,10 @@ internal fun PhaseContext.fir2Ir(
|
||||
}
|
||||
|
||||
private fun PhaseContext.createKonanSymbols(
|
||||
irModuleFragment: IrModuleFragment,
|
||||
components: Fir2IrComponents,
|
||||
pluginContext: Fir2IrPluginContext,
|
||||
): KonanSymbolsOverFir {
|
||||
val moduleDescriptor = irModuleFragment.descriptor
|
||||
): KonanSymbols {
|
||||
val symbolTable = SymbolTable(KonanIdSignaturer(KonanManglerDesc), pluginContext.irFactory)
|
||||
val descriptorsLookup = DescriptorsLookup(moduleDescriptor.builtIns as KonanBuiltIns)
|
||||
|
||||
return KonanSymbolsOverFir(this, descriptorsLookup, components.irBuiltIns, symbolTable, symbolTable.lazyWrapper)
|
||||
return KonanSymbols(this, SymbolOverIrLookupUtils(), components.irBuiltIns, symbolTable.lazyWrapper)
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ object InteropFqNames {
|
||||
const val cStructVarName = "CStructVar"
|
||||
const val cEnumVarName = "CEnumVar"
|
||||
const val cPrimitiveVarName = "CPrimitiveVar"
|
||||
private const val cPointedName = "CPointed"
|
||||
const val cPointedName = "CPointed"
|
||||
|
||||
const val interopStubsName = "InteropStubs"
|
||||
const val managedTypeName = "ManagedType"
|
||||
|
||||
+3
-3
@@ -13,7 +13,8 @@ import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrContext
|
||||
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrInput
|
||||
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrOutput
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbolsOverDescriptors
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
||||
import org.jetbrains.kotlin.backend.konan.ir.SymbolOverDescriptorsLookupUtils
|
||||
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
|
||||
import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.*
|
||||
@@ -92,8 +93,7 @@ internal fun PsiToIrContext.psiToIr(
|
||||
else
|
||||
BuiltInFictitiousFunctionIrClassFactory(symbolTable, irBuiltInsOverDescriptors, reflectionTypes)
|
||||
irBuiltInsOverDescriptors.functionFactory = functionIrClassFactory
|
||||
val descriptorsLookup = DescriptorsLookup(this.builtIns)
|
||||
val symbols = KonanSymbolsOverDescriptors(this, descriptorsLookup, generatorContext.irBuiltIns, symbolTable, symbolTable.lazyWrapper)
|
||||
val symbols = KonanSymbols(this, SymbolOverDescriptorsLookupUtils(generatorContext.symbolTable), generatorContext.irBuiltIns, symbolTable.lazyWrapper)
|
||||
|
||||
val irDeserializer = if (isProducingLibrary && !useLinkerWhenProducingLibrary) {
|
||||
// Enable lazy IR generation for newly-created symbols inside BE
|
||||
|
||||
+268
-251
@@ -10,32 +10,21 @@ import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.findMainEntryPoint
|
||||
import org.jetbrains.kotlin.backend.konan.lower.TestProcessor
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.constructClassLikeType
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.findDeclaration
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.getKotlinTypeFqName
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
object KonanNameConventions {
|
||||
@@ -43,28 +32,74 @@ object KonanNameConventions {
|
||||
val getWithoutBoundCheck = Name.special("<getWithoutBoundCheck>")
|
||||
}
|
||||
|
||||
internal interface SymbolLookupUtils {
|
||||
fun findMemberFunction(clazz: IrClassSymbol, name: Name): IrSimpleFunctionSymbol?
|
||||
fun findMemberProperty(clazz: IrClassSymbol, name: Name): IrPropertySymbol?
|
||||
fun findMemberPropertyGetter(clazz: IrClassSymbol, name: Name): IrSimpleFunctionSymbol?
|
||||
fun findPrimaryConstructor(clazz: IrClassSymbol): IrConstructorSymbol?
|
||||
fun findNoParametersConstructor(clazz: IrClassSymbol): IrConstructorSymbol?
|
||||
fun findNestedClass(clazz: IrClassSymbol, name: Name): IrClassSymbol?
|
||||
fun findGetter(property: IrPropertySymbol): IrSimpleFunctionSymbol?
|
||||
|
||||
fun getName(clazz: IrClassSymbol): Name
|
||||
fun isExtensionReceiverClass(property: IrPropertySymbol, expected: IrClassSymbol?): Boolean
|
||||
fun isExtensionReceiverClass(function: IrFunctionSymbol, expected: IrClassSymbol?): Boolean
|
||||
fun isExtensionReceiverNullable(function: IrFunctionSymbol): Boolean?
|
||||
fun getValueParametersCount(function: IrFunctionSymbol): Int
|
||||
fun getTypeParametersCount(function: IrFunctionSymbol): Int
|
||||
fun isTypeParameterUpperBoundClass(property: IrPropertySymbol, index: Int, expected: IrClassSymbol): Boolean
|
||||
fun isValueParameterClass(function: IrFunctionSymbol, index: Int, expected: IrClassSymbol?): Boolean
|
||||
fun isReturnClass(function: IrFunctionSymbol, expected: IrClassSymbol): Boolean
|
||||
fun isValueParameterTypeArgumentClass(function: IrFunctionSymbol, index: Int, argumentIndex: Int, expected: IrClassSymbol?): Boolean
|
||||
fun isValueParameterNullable(function: IrFunctionSymbol, index: Int): Boolean?
|
||||
fun isExpect(function: IrFunctionSymbol): Boolean
|
||||
fun isSuspend(functionSymbol: IrFunctionSymbol): Boolean
|
||||
fun getVisibility(function: IrFunctionSymbol): DescriptorVisibility
|
||||
fun getValueParameterPrimitiveBinaryType(function: IrFunctionSymbol, index: Int): PrimitiveBinaryType?
|
||||
}
|
||||
|
||||
// This is what Context collects about IR.
|
||||
internal class KonanIr(context: Context, override val symbols: KonanSymbols): Ir<Context>(context)
|
||||
|
||||
internal abstract class KonanSymbols(
|
||||
internal class KonanSymbols(
|
||||
context: PhaseContext,
|
||||
val descriptorsLookup: DescriptorsLookup, // Please don't add usages of `descriptorsLookup` and `descriptorsLookup.builtIns` to this class anymore.
|
||||
val lookup: SymbolLookupUtils,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
internal val symbolTable: SymbolTable, // Please don't add usages of `symbolTable` to this class anymore.
|
||||
lazySymbolTable: ReferenceSymbolTable
|
||||
symbolTable: ReferenceSymbolTable,
|
||||
): Symbols(irBuiltIns, symbolTable) {
|
||||
protected abstract fun IrClassSymbol.findMemberSimpleFunction(name: Name): IrSimpleFunctionSymbol?
|
||||
protected abstract fun IrClassSymbol.findMemberProperty(name: Name): IrPropertySymbol?
|
||||
protected abstract fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol?
|
||||
protected abstract fun findDefaultConstructor(className: String): IrConstructorSymbol
|
||||
protected abstract fun findDefaultConstructor(className: String, nestedClassName: String): IrConstructorSymbol
|
||||
protected abstract fun findTopLevelExtensionPropertyGetter(packageName: FqName, name: Name, extensionParameterClassID: ClassId): IrSimpleFunctionSymbol?
|
||||
private fun findInteropExtensionPropertyGetter(name: Name, extensionClassID: ClassId): IrSimpleFunctionSymbol? =
|
||||
findTopLevelExtensionPropertyGetter(InteropFqNames.packageName, name, extensionClassID)
|
||||
val entryPoint = run {
|
||||
val config = context.config.configuration
|
||||
if (config.get(KonanConfigKeys.PRODUCE) != CompilerOutputKind.PROGRAM) return@run null
|
||||
|
||||
val entryPoint = findMainEntryPoint(context, descriptorsLookup.builtIns)?.let { symbolTable.referenceSimpleFunction(it) }
|
||||
val entryPoint = FqName(config.get(KonanConfigKeys.ENTRY) ?: when (config.get(KonanConfigKeys.GENERATE_TEST_RUNNER)) {
|
||||
TestRunnerKind.MAIN_THREAD -> "kotlin.native.internal.test.main"
|
||||
TestRunnerKind.WORKER -> "kotlin.native.internal.test.worker"
|
||||
TestRunnerKind.MAIN_THREAD_NO_EXIT -> "kotlin.native.internal.test.mainNoExit"
|
||||
else -> "main"
|
||||
})
|
||||
|
||||
override val externalSymbolTable = lazySymbolTable
|
||||
val entryName = entryPoint.shortName()
|
||||
val packageName = entryPoint.parent()
|
||||
|
||||
fun IrSimpleFunctionSymbol.isArrayStringMain() =
|
||||
lookup.getValueParametersCount(this) == 1 &&
|
||||
lookup.isValueParameterClass(this, 0, array) &&
|
||||
lookup.isValueParameterTypeArgumentClass(this, 0, 0, string)
|
||||
|
||||
fun IrSimpleFunctionSymbol.isNoArgsMain() = lookup.getValueParametersCount(this) == 0
|
||||
|
||||
val candidates = irBuiltIns.findFunctions(entryName, packageName)
|
||||
.filter {
|
||||
lookup.isReturnClass(it, unit) &&
|
||||
lookup.getTypeParametersCount(it) == 0 &&
|
||||
lookup.getVisibility(it).isPublicAPI
|
||||
}
|
||||
|
||||
val main = candidates.singleOrNull { it.isArrayStringMain() } ?: candidates.singleOrNull { it.isNoArgsMain() }
|
||||
if (main == null) context.reportCompilationError("Could not find '$entryName' in '$packageName' package.")
|
||||
if (lookup.isSuspend(main)) context.reportCompilationError("Entry point can not be a suspend function.")
|
||||
main
|
||||
}
|
||||
|
||||
val nothing get() = irBuiltIns.nothingClass
|
||||
val throwable get() = irBuiltIns.throwableClass
|
||||
@@ -80,8 +115,8 @@ internal abstract class KonanSymbols(
|
||||
|
||||
val allIntegerClasses = signedIntegerClasses + unsignedIntegerClasses
|
||||
|
||||
val unsignedToSignedOfSameBitWidth = unsignedIntegerClasses.associate {
|
||||
it to when (it) {
|
||||
val unsignedToSignedOfSameBitWidth = unsignedIntegerClasses.associateWith {
|
||||
when (it) {
|
||||
uByte -> byte
|
||||
uShort -> short
|
||||
uInt -> int
|
||||
@@ -92,11 +127,11 @@ internal abstract class KonanSymbols(
|
||||
|
||||
val integerConversions = allIntegerClasses.flatMap { fromClass ->
|
||||
allIntegerClasses.map { toClass ->
|
||||
val name = Name.identifier("to${toClass.descriptor.name.asString().replaceFirstChar(Char::uppercaseChar)}")
|
||||
val name = Name.identifier("to${lookup.getName(toClass).asString().replaceFirstChar(Char::uppercaseChar)}")
|
||||
val symbol = if (fromClass in signedIntegerClasses && toClass in unsignedIntegerClasses) {
|
||||
irBuiltIns.getNonBuiltInFunctionsByExtensionReceiver(name, "kotlin")[fromClass]!!
|
||||
} else {
|
||||
fromClass.findMemberSimpleFunction(name)!!
|
||||
lookup.findMemberFunction(fromClass, name)!!
|
||||
}
|
||||
|
||||
(fromClass to toClass) to symbol
|
||||
@@ -113,21 +148,32 @@ internal abstract class KonanSymbols(
|
||||
val processUnhandledException = irBuiltIns.findFunctions(Name.identifier("processUnhandledException"), "kotlin", "native").single()
|
||||
val terminateWithUnhandledException = irBuiltIns.findFunctions(Name.identifier("terminateWithUnhandledException"), "kotlin", "native").single()
|
||||
|
||||
abstract val interopNativePointedGetRawPointer: IrSimpleFunctionSymbol
|
||||
val interopNativePointedGetRawPointer = interopFunctions(InteropFqNames.nativePointedGetRawPointerFunName).single {
|
||||
lookup.isExtensionReceiverClass(it, nativePointed)
|
||||
}
|
||||
|
||||
val interopCPointer = interopClass(InteropFqNames.cPointerName)
|
||||
val interopCstr = findInteropExtensionPropertyGetter(Name.identifier(InteropFqNames.cstrPropertyName), StandardClassIds.String)!!
|
||||
val interopWcstr = findInteropExtensionPropertyGetter(Name.identifier(InteropFqNames.wcstrPropertyName), StandardClassIds.String)!!
|
||||
val interopCPointed = interopClass(InteropFqNames.cPointedName)
|
||||
val interopCstr = findTopLevelPropertyGetter(InteropFqNames.packageName, Name.identifier(InteropFqNames.cstrPropertyName), string)
|
||||
val interopWcstr = findTopLevelPropertyGetter(InteropFqNames.packageName, Name.identifier(InteropFqNames.wcstrPropertyName), string)
|
||||
val interopMemScope = interopClass(InteropFqNames.memScopeName)
|
||||
val interopCValue = interopClass(InteropFqNames.cValueName)
|
||||
val interopCValuesRef = interopClass(InteropFqNames.cValuesRefName)
|
||||
abstract val interopCValueWrite: IrSimpleFunctionSymbol
|
||||
abstract val interopCValueRead: IrSimpleFunctionSymbol
|
||||
abstract val interopAllocType: IrSimpleFunctionSymbol
|
||||
val interopCValueWrite = interopFunctions(InteropFqNames.cValueWriteFunName).single {
|
||||
lookup.isExtensionReceiverClass(it, interopCValue)
|
||||
}
|
||||
val interopCValueRead = interopFunctions(InteropFqNames.cValueReadFunName).single {
|
||||
lookup.getValueParametersCount(it) == 1
|
||||
}
|
||||
val interopAllocType = interopFunctions(InteropFqNames.allocTypeFunName).single {
|
||||
lookup.getTypeParametersCount(it) == 0
|
||||
}
|
||||
|
||||
val interopTypeOf = interopFunction(InteropFqNames.typeOfFunName)
|
||||
|
||||
abstract val interopCPointerGetRawValue: IrSimpleFunctionSymbol
|
||||
val interopCPointerGetRawValue = interopFunctions(InteropFqNames.cPointerGetRawValueFunName).single {
|
||||
lookup.isExtensionReceiverClass(it, interopCPointer)
|
||||
}
|
||||
|
||||
val interopAllocObjCObject = interopFunction(InteropFqNames.allocObjCObjectFunName)
|
||||
|
||||
@@ -164,11 +210,9 @@ internal abstract class KonanSymbols(
|
||||
val interopObjCObjectInitBy = interopFunction(InteropFqNames.objCObjectInitByFunName)
|
||||
val interopObjCObjectRawValueGetter = interopFunction(InteropFqNames.objCObjectRawPtrFunName)
|
||||
|
||||
val interopNativePointedRawPtrGetter = interopClass(InteropFqNames.nativePointedName)
|
||||
.findMemberPropertyGetter(Name.identifier(InteropFqNames.nativePointedRawPtrPropertyName))!!
|
||||
val interopNativePointedRawPtrGetter = lookup.findMemberPropertyGetter(interopClass(InteropFqNames.nativePointedName), Name.identifier(InteropFqNames.nativePointedRawPtrPropertyName))!!
|
||||
|
||||
val interopCPointerRawValue: IrPropertySymbol = interopClass(InteropFqNames.cPointerName)
|
||||
.findMemberProperty(Name.identifier(InteropFqNames.cPointerRawValuePropertyName))!!
|
||||
val interopCPointerRawValue: IrPropertySymbol = lookup.findMemberProperty(interopClass(InteropFqNames.cPointerName), Name.identifier(InteropFqNames.cPointerRawValuePropertyName))!!
|
||||
|
||||
val interopInterpretObjCPointer = interopFunction(InteropFqNames.interpretObjCPointerFunName)
|
||||
val interopInterpretObjCPointerOrNull = interopFunction(InteropFqNames.interpretObjCPointerOrNullFunName)
|
||||
@@ -182,10 +226,21 @@ internal abstract class KonanSymbols(
|
||||
val nativeMemUtils = interopClass(InteropFqNames.nativeMemUtilsName)
|
||||
val nativeHeap = interopClass(InteropFqNames.nativeHeapName)
|
||||
|
||||
abstract val interopGetPtr: IrSimpleFunctionSymbol
|
||||
abstract val interopManagedGetPtr: IrSimpleFunctionSymbol
|
||||
val cStuctVar = interopClass(InteropFqNames.cStructVarName)
|
||||
val cStructVarConstructorSymbol = lookup.findPrimaryConstructor(cStuctVar)!!
|
||||
val managedTypeConstructor = lookup.findPrimaryConstructor(interopClass(InteropFqNames.managedTypeName))!!
|
||||
val structVarPrimaryConstructor = lookup.findPrimaryConstructor(lookup.findNestedClass(cStuctVar, Name.identifier(InteropFqNames.TypeName))!!)!!
|
||||
|
||||
val interopGetPtr = findTopLevelPropertyGetter(InteropFqNames.packageName, Name.identifier("ptr")) {
|
||||
lookup.isTypeParameterUpperBoundClass(it, 0, interopCPointed)
|
||||
}
|
||||
|
||||
val interopManagedType = interopClass(InteropFqNames.managedTypeName)
|
||||
|
||||
val interopManagedGetPtr = findTopLevelPropertyGetter(InteropFqNames.packageName, Name.identifier("ptr")) {
|
||||
lookup.isTypeParameterUpperBoundClass(it, 0, cStuctVar) && lookup.isExtensionReceiverClass(it, interopManagedType)
|
||||
}
|
||||
|
||||
val interopCPlusPlusClass = interopClass(InteropFqNames.cPlusPlusClassName)
|
||||
val interopSkiaRefCnt = interopClass(InteropFqNames.skiaRefCntName)
|
||||
|
||||
@@ -216,8 +271,9 @@ internal abstract class KonanSymbols(
|
||||
val createCleaner =
|
||||
irBuiltIns.findFunctions(Name.identifier("createCleaner"),"kotlin", "native", "ref").single()
|
||||
|
||||
// TODO: this is strange. It should be a map from IrClassSymbol
|
||||
val areEqualByValue = internalFunctions("areEqualByValue").associateBy {
|
||||
it.descriptor.valueParameters[0].type.computePrimitiveBinaryTypeOrNull()!!
|
||||
lookup.getValueParameterPrimitiveBinaryType(it, 0)!!
|
||||
}
|
||||
|
||||
val reinterpret = internalFunction("reinterpret")
|
||||
@@ -226,7 +282,7 @@ internal abstract class KonanSymbols(
|
||||
|
||||
val ieee754Equals = internalFunctions("ieee754Equals")
|
||||
|
||||
val equals = any.findMemberSimpleFunction(Name.identifier("equals"))!!
|
||||
val equals = lookup.findMemberFunction(any, Name.identifier("equals"))!!
|
||||
|
||||
val throwArithmeticException = internalFunction("ThrowArithmeticException")
|
||||
|
||||
@@ -256,45 +312,41 @@ internal abstract class KonanSymbols(
|
||||
|
||||
override val defaultConstructorMarker = internalClass("DefaultConstructorMarker")
|
||||
|
||||
private fun arrayToExtensionSymbolMap(name: String, filter: (FunctionDescriptor) -> Boolean = { true }) =
|
||||
private fun arrayToExtensionSymbolMap(name: String, filter: (IrFunctionSymbol) -> Boolean = { true }) =
|
||||
arrays.associateWith { classSymbol ->
|
||||
irBuiltIns.findFunctions(Name.identifier(name), "kotlin", "collections")
|
||||
.singleOrNull { function ->
|
||||
function.descriptor.let {
|
||||
it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor == classSymbol.descriptor
|
||||
&& !it.isExpect
|
||||
&& filter(it)
|
||||
}
|
||||
} ?: error(classSymbol.toString())
|
||||
lookup.isExtensionReceiverClass(function, classSymbol) && !lookup.isExpect(function) && filter(function)
|
||||
} ?: error("No function $name for $classSymbol")
|
||||
}
|
||||
|
||||
val arrayContentToString = arrayToExtensionSymbolMap("contentToString") {
|
||||
it.extensionReceiverParameter?.type?.isMarkedNullable == false
|
||||
lookup.isExtensionReceiverNullable(it) == false
|
||||
}
|
||||
val arrayContentHashCode = arrayToExtensionSymbolMap("contentHashCode") {
|
||||
it.extensionReceiverParameter?.type?.isMarkedNullable == false
|
||||
lookup.isExtensionReceiverNullable(it) == false
|
||||
}
|
||||
val arrayContentEquals = arrayToExtensionSymbolMap("contentEquals") {
|
||||
it.extensionReceiverParameter?.type?.isMarkedNullable == false
|
||||
lookup.isExtensionReceiverNullable(it) == false
|
||||
}
|
||||
|
||||
override val arraysContentEquals by lazy { arrayContentEquals.mapKeys { it.key.defaultType } }
|
||||
|
||||
val copyInto = arrayToExtensionSymbolMap("copyInto")
|
||||
val copyOf = arrayToExtensionSymbolMap("copyOf") { it.valueParameters.isEmpty() }
|
||||
val copyOf = arrayToExtensionSymbolMap("copyOf") { lookup.getValueParametersCount(it) == 0 }
|
||||
|
||||
val arrayGet = arrays.associateWith { it.findMemberSimpleFunction(Name.identifier("get"))!! }
|
||||
val arrayGet = arrays.associateWith { lookup.findMemberFunction(it, Name.identifier("get"))!! }
|
||||
|
||||
val arraySet = arrays.associateWith { it.findMemberSimpleFunction(Name.identifier("set"))!! }
|
||||
val arraySet = arrays.associateWith { lookup.findMemberFunction(it, Name.identifier("set"))!! }
|
||||
|
||||
val arraySize = arrays.associateWith { it.findMemberPropertyGetter(Name.identifier("size"))!! }
|
||||
val arraySize = arrays.associateWith { lookup.findMemberPropertyGetter(it, Name.identifier("size"))!! }
|
||||
|
||||
val valuesForEnum = internalFunction("valuesForEnum")
|
||||
|
||||
val valueOfForEnum = internalFunction("valueOfForEnum")
|
||||
|
||||
val createEnumEntries = irBuiltIns.findFunctions(Name.identifier("enumEntries"), "kotlin", "enums")
|
||||
.single { it.descriptor.valueParameters.singleOrNull()?.type?.constructor?.declarationDescriptor == array.descriptor }
|
||||
.single { lookup.getValueParametersCount(it) == 1 && lookup.isValueParameterClass(it, 0, array) }
|
||||
|
||||
val enumEntriesInterface = irBuiltIns.findClass(Name.identifier("EnumEntries"), "kotlin", "enums")!!
|
||||
|
||||
@@ -303,7 +355,7 @@ internal abstract class KonanSymbols(
|
||||
val initInstance = internalFunction("initInstance")
|
||||
|
||||
val println = irBuiltIns.findFunctions(Name.identifier("println"), "kotlin", "io")
|
||||
.single { it.descriptor.valueParameters.singleOrNull()?.type?.constructor?.declarationDescriptor == string.descriptor }
|
||||
.single { lookup.getValueParametersCount(it) == 1 && lookup.isValueParameterClass(it, 0, string) }
|
||||
|
||||
override val getContinuation = internalFunction("getContinuation")
|
||||
|
||||
@@ -313,17 +365,8 @@ internal abstract class KonanSymbols(
|
||||
|
||||
override val suspendCoroutineUninterceptedOrReturn = internalFunction("suspendCoroutineUninterceptedOrReturn")
|
||||
|
||||
private val coroutinesIntrinsicsPackage =
|
||||
descriptorsLookup.builtIns.builtInsModule.getPackage(StandardNames.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope
|
||||
|
||||
private val coroutinesPackage =
|
||||
descriptorsLookup.builtIns.builtInsModule.getPackage(StandardNames.COROUTINES_PACKAGE_FQ_NAME).memberScope
|
||||
|
||||
override val coroutineContextGetter = symbolTable.referenceSimpleFunction(
|
||||
coroutinesPackage
|
||||
.getContributedVariables(Name.identifier("coroutineContext"), NoLookupLocation.FROM_BACKEND)
|
||||
.single()
|
||||
.getter!!)
|
||||
override val coroutineContextGetter =
|
||||
findTopLevelPropertyGetter(StandardNames.COROUTINES_PACKAGE_FQ_NAME, Name.identifier("coroutineContext"), null)
|
||||
|
||||
override val coroutineGetContext = internalFunction("getCoroutineContext")
|
||||
|
||||
@@ -335,23 +378,17 @@ internal abstract class KonanSymbols(
|
||||
|
||||
val continuationImpl = internalCoroutinesClass("ContinuationImpl")
|
||||
|
||||
val invokeSuspendFunction =
|
||||
baseContinuationImpl.findMemberSimpleFunction(Name.identifier("invokeSuspend"))!!
|
||||
val invokeSuspendFunction = lookup.findMemberFunction(baseContinuationImpl, Name.identifier("invokeSuspend"))!!
|
||||
|
||||
override val coroutineSuspendedGetter = symbolTable.referenceSimpleFunction(
|
||||
coroutinesIntrinsicsPackage
|
||||
.getContributedVariables(COROUTINE_SUSPENDED_NAME, NoLookupLocation.FROM_BACKEND)
|
||||
.filterNot { it.isExpect }.single().getter!!
|
||||
)
|
||||
override val coroutineSuspendedGetter =
|
||||
findTopLevelPropertyGetter(StandardNames.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME, COROUTINE_SUSPENDED_NAME, null)
|
||||
|
||||
val cancellationException = topLevelClass(KonanFqNames.cancellationException)
|
||||
|
||||
val kotlinResult = irBuiltIns.findClass(Name.identifier("Result"))!!
|
||||
|
||||
val kotlinResultGetOrThrow = irBuiltIns.findFunctions(Name.identifier("getOrThrow"))
|
||||
.single {
|
||||
it.descriptor.extensionReceiverParameter?.type?.constructor?.declarationDescriptor == kotlinResult.descriptor
|
||||
}
|
||||
.single { lookup.isExtensionReceiverClass(it, kotlinResult) }
|
||||
|
||||
override val functionAdapter = internalClass("FunctionAdapter")
|
||||
|
||||
@@ -380,12 +417,12 @@ internal abstract class KonanSymbols(
|
||||
val kType = reflectionClass("KType")
|
||||
val getObjectTypeInfo = internalFunction("getObjectTypeInfo")
|
||||
val kClassImpl = internalClass("KClassImpl")
|
||||
val kClassImplConstructor by lazy { kClassImpl.constructors.single { it.descriptor.isPrimary } }
|
||||
val kClassImplIntrinsicConstructor by lazy { kClassImpl.constructors.single { it.descriptor.valueParameters.isEmpty() } }
|
||||
val kClassImplConstructor = lookup.findPrimaryConstructor(kClassImpl)!!
|
||||
val kClassImplIntrinsicConstructor = lookup.findNoParametersConstructor(kClassImpl)!!
|
||||
val kClassUnsupportedImpl = internalClass("KClassUnsupportedImpl")
|
||||
val kTypeParameterImpl = internalClass("KTypeParameterImpl")
|
||||
val kTypeImpl = internalClass("KTypeImpl")
|
||||
val kTypeImplIntrinsicConstructor by lazy { kTypeImpl.constructors.single { it.descriptor.valueParameters.isEmpty() } }
|
||||
val kTypeImplIntrinsicConstructor = lookup.findNoParametersConstructor(kTypeImpl)!!
|
||||
val kTypeImplForTypeParametersWithRecursiveBounds = internalClass("KTypeImplForTypeParametersWithRecursiveBounds")
|
||||
val kTypeProjectionList = internalClass("KTypeProjectionList")
|
||||
|
||||
@@ -395,14 +432,17 @@ internal abstract class KonanSymbols(
|
||||
|
||||
val eagerInitialization = topLevelClass(KonanFqNames.eagerInitialization)
|
||||
|
||||
val cStructVarConstructorSymbol = findDefaultConstructor(InteropFqNames.cStructVarName)
|
||||
val managedTypeConstructor = findDefaultConstructor(InteropFqNames.managedTypeName)
|
||||
val enumVarConstructorSymbol = findDefaultConstructor(InteropFqNames.cEnumVarName)
|
||||
val primitiveVarPrimaryConstructor = findDefaultConstructor(InteropFqNames.cPrimitiveVarName, InteropFqNames.TypeName)
|
||||
val structVarPrimaryConstructor = findDefaultConstructor(InteropFqNames.cStructVarName, InteropFqNames.TypeName)
|
||||
val enumVarConstructorSymbol = lookup.findPrimaryConstructor(interopClass(InteropFqNames.cEnumVarName))!!
|
||||
val primitiveVarPrimaryConstructor = lookup.findPrimaryConstructor(lookup.findNestedClass(interopClass(InteropFqNames.cPrimitiveVarName), Name.identifier(InteropFqNames.TypeName))!!)!!
|
||||
|
||||
private fun topLevelClass(fqName: FqName): IrClassSymbol = irBuiltIns.findClass(fqName.shortName(), fqName.parent())!!
|
||||
|
||||
private fun findTopLevelPropertyGetter(packageName: FqName, name: Name, extensionReceiverClass: IrClassSymbol?) =
|
||||
findTopLevelPropertyGetter(packageName, name) { lookup.isExtensionReceiverClass(it, extensionReceiverClass) }
|
||||
|
||||
private fun findTopLevelPropertyGetter(packageName: FqName, name: Name, predicate: (IrPropertySymbol) -> Boolean) =
|
||||
lookup.findGetter(irBuiltIns.findProperties(name, packageName).single(predicate))!!
|
||||
|
||||
private fun nativeFunction(name: String) =
|
||||
irBuiltIns.findFunctions(Name.identifier(name), KonanFqNames.packageName).single()
|
||||
|
||||
@@ -421,10 +461,12 @@ internal abstract class KonanSymbols(
|
||||
private fun getKonanTestClass(className: String) =
|
||||
irBuiltIns.findClass(Name.identifier(className), "kotlin", "native", "internal", "test")!!
|
||||
|
||||
private fun interopFunction(name: String) =
|
||||
irBuiltIns.findFunctions(Name.identifier(name), InteropFqNames.packageName).single()
|
||||
private fun interopFunctions(name: String) =
|
||||
irBuiltIns.findFunctions(Name.identifier(name), InteropFqNames.packageName)
|
||||
|
||||
protected fun interopClass(name: String) =
|
||||
private fun interopFunction(name: String) = interopFunctions(name).single()
|
||||
|
||||
private fun interopClass(name: String) =
|
||||
irBuiltIns.findClass(Name.identifier(name), InteropFqNames.packageName)!!
|
||||
|
||||
fun kFunctionN(n: Int) = irBuiltIns.kFunctionN(n).symbol
|
||||
@@ -457,180 +499,155 @@ internal abstract class KonanSymbols(
|
||||
fun getTestFunctionKind(kind: TestProcessor.FunctionKind) = testFunctionKindCache[kind]!!
|
||||
}
|
||||
|
||||
// WARNING: override protected functions are called from base class(`KonanSymbols`) constructor,
|
||||
// so its functionality must be independent of the derived object(`KonanSymbolsOverDescriptors`)'s state, which is uninitialized at the invocation moment
|
||||
internal class KonanSymbolsOverDescriptors(
|
||||
context: PhaseContext,
|
||||
descriptorsLookup: DescriptorsLookup,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
symbolTable: SymbolTable,
|
||||
lazySymbolTable: ReferenceSymbolTable
|
||||
) : KonanSymbols(context, descriptorsLookup, irBuiltIns, symbolTable, lazySymbolTable) {
|
||||
override fun IrClassSymbol.findMemberSimpleFunction(name: Name): IrSimpleFunctionSymbol? =
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
internal class SymbolOverDescriptorsLookupUtils(val symbolTable: SymbolTable) : SymbolLookupUtils {
|
||||
override fun findMemberFunction(clazz: IrClassSymbol, name: Name): IrSimpleFunctionSymbol? =
|
||||
// inspired by: irBuiltIns.findBuiltInClassMemberFunctions(this, name).singleOrNull()
|
||||
descriptor.unsubstitutedMemberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
|
||||
clazz.descriptor.unsubstitutedMemberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
|
||||
.singleOrNull()
|
||||
?.let { symbolTable.referenceSimpleFunction(it) }
|
||||
|
||||
override fun IrClassSymbol.findMemberProperty(name: Name): IrPropertySymbol? =
|
||||
descriptor.unsubstitutedMemberScope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND)
|
||||
override fun findMemberProperty(clazz: IrClassSymbol, name: Name): IrPropertySymbol? =
|
||||
clazz.descriptor.unsubstitutedMemberScope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND)
|
||||
.singleOrNull()
|
||||
?.let { symbolTable.referenceProperty(it) }
|
||||
|
||||
override fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol? =
|
||||
descriptor.unsubstitutedMemberScope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND)
|
||||
override fun findMemberPropertyGetter(clazz: IrClassSymbol, name: Name): IrSimpleFunctionSymbol? =
|
||||
clazz.descriptor.unsubstitutedMemberScope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND)
|
||||
.singleOrNull()
|
||||
?.getter
|
||||
?.let { symbolTable.referenceSimpleFunction(it) }
|
||||
|
||||
override fun findTopLevelExtensionPropertyGetter(packageName: FqName, name: Name, extensionParameterClassID: ClassId): IrSimpleFunctionSymbol? {
|
||||
val extensionParameterFqNameString = extensionParameterClassID.asFqNameString()
|
||||
return descriptorsLookup.builtIns.builtInsModule.getPackage(InteropFqNames.packageName).memberScope
|
||||
.getContributedVariables(name, NoLookupLocation.FROM_BACKEND)
|
||||
.singleOrNull {
|
||||
it.extensionReceiverParameter?.type?.getKotlinTypeFqName(true) == extensionParameterFqNameString
|
||||
}?.getter
|
||||
?.let { symbolTable.referenceSimpleFunction(it) }
|
||||
override fun getName(clazz: IrClassSymbol) = clazz.descriptor.name
|
||||
override fun isExtensionReceiverClass(property: IrPropertySymbol, expected: IrClassSymbol?): Boolean {
|
||||
return property.descriptor.extensionReceiverParameter?.type?.let { TypeUtils.getClassDescriptor(it) } == expected?.descriptor
|
||||
}
|
||||
|
||||
override val interopNativePointedGetRawPointer = symbolTable.referenceSimpleFunction(
|
||||
descriptorsLookup.interopBuiltIns.getContributedFunctions(InteropFqNames.nativePointedGetRawPointerFunName).single {
|
||||
val extensionReceiverParameter = it.extensionReceiverParameter
|
||||
extensionReceiverParameter != null &&
|
||||
TypeUtils.getClassDescriptor(extensionReceiverParameter.type)?.fqNameUnsafe == InteropFqNames.nativePointed
|
||||
})
|
||||
override val interopCValueWrite = symbolTable.referenceSimpleFunction(
|
||||
descriptorsLookup.interopBuiltIns.getContributedFunctions(InteropFqNames.cValueWriteFunName).single {
|
||||
it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor?.fqNameSafe == InteropFqNames.cValue
|
||||
})
|
||||
override val interopCValueRead = symbolTable.referenceSimpleFunction(
|
||||
descriptorsLookup.interopBuiltIns.getContributedFunctions(InteropFqNames.cValueReadFunName).single {
|
||||
it.valueParameters.size == 1
|
||||
})
|
||||
override val interopAllocType = symbolTable.referenceSimpleFunction(
|
||||
descriptorsLookup.interopBuiltIns.getContributedFunctions(InteropFqNames.allocTypeFunName).single {
|
||||
it.extensionReceiverParameter != null && it.valueParameters.singleOrNull()?.name?.toString() == "type"
|
||||
})
|
||||
override val interopCPointerGetRawValue = symbolTable.referenceSimpleFunction(
|
||||
descriptorsLookup.interopBuiltIns.getContributedFunctions(InteropFqNames.cPointerGetRawValueFunName).single {
|
||||
val extensionReceiverParameter = it.extensionReceiverParameter
|
||||
extensionReceiverParameter != null &&
|
||||
TypeUtils.getClassDescriptor(extensionReceiverParameter.type)?.fqNameUnsafe == InteropFqNames.cPointer
|
||||
})
|
||||
|
||||
override fun findDefaultConstructor(className: String): IrConstructorSymbol = symbolTable.referenceConstructor(
|
||||
descriptorsLookup.interopBuiltIns.getContributedClass(className)
|
||||
.unsubstitutedPrimaryConstructor!!
|
||||
)
|
||||
|
||||
override fun findDefaultConstructor(className: String, nestedClassName: String): IrConstructorSymbol = symbolTable.referenceConstructor(
|
||||
descriptorsLookup.interopBuiltIns.getContributedClass(className)
|
||||
.defaultType.memberScope.getContributedClass(nestedClassName)
|
||||
.unsubstitutedPrimaryConstructor!!
|
||||
)
|
||||
|
||||
override val interopGetPtr = descriptorsLookup.interopBuiltIns.getContributedVariables("ptr").single {
|
||||
val singleTypeParameter = it.typeParameters.singleOrNull()
|
||||
val singleTypeParameterUpperBound = singleTypeParameter?.upperBounds?.singleOrNull()
|
||||
val extensionReceiverParameter = it.extensionReceiverParameter
|
||||
|
||||
singleTypeParameterUpperBound != null &&
|
||||
extensionReceiverParameter != null &&
|
||||
TypeUtils.getClassDescriptor(singleTypeParameterUpperBound)?.fqNameSafe == InteropFqNames.cPointed &&
|
||||
extensionReceiverParameter.type == singleTypeParameter.defaultType
|
||||
}.getter!!.let { symbolTable.referenceSimpleFunction(it) }
|
||||
|
||||
override val interopManagedGetPtr = descriptorsLookup.interopBuiltIns.getContributedVariables("ptr").single {
|
||||
val singleTypeParameter = it.typeParameters.singleOrNull()
|
||||
val singleTypeParameterUpperBound = singleTypeParameter?.upperBounds?.singleOrNull()
|
||||
val extensionReceiverParameter = it.extensionReceiverParameter
|
||||
|
||||
singleTypeParameterUpperBound != null &&
|
||||
extensionReceiverParameter != null &&
|
||||
TypeUtils.getClassDescriptor(singleTypeParameterUpperBound)?.fqNameSafe == InteropFqNames.cStructVar &&
|
||||
TypeUtils.getClassDescriptor(extensionReceiverParameter.type)?.fqNameSafe == InteropFqNames.managedType
|
||||
}.getter!!.let { symbolTable.referenceSimpleFunction(it) }
|
||||
}
|
||||
|
||||
// WARNING: override protected functions are called from base class(`KonanSymbols`) constructor,
|
||||
// so its functionality must be independent of the derived object(`KonanSymbolsOverFir`)'s state, which is uninitialized at the invocation moment
|
||||
internal class KonanSymbolsOverFir(
|
||||
context: PhaseContext,
|
||||
descriptorsLookup: DescriptorsLookup,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
symbolTable: SymbolTable,
|
||||
lazySymbolTable: ReferenceSymbolTable
|
||||
) : KonanSymbols(context, descriptorsLookup, irBuiltIns, symbolTable, lazySymbolTable) {
|
||||
override fun IrClassSymbol.findMemberSimpleFunction(name: Name): IrSimpleFunctionSymbol? =
|
||||
owner.findDeclaration<IrSimpleFunction> { it.name == name }?.symbol
|
||||
|
||||
override fun IrClassSymbol.findMemberProperty(name: Name): IrPropertySymbol? =
|
||||
owner.findDeclaration<IrProperty> { it.name == name }?.symbol
|
||||
|
||||
override fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol? =
|
||||
owner.findDeclaration<IrProperty> { it.name == name }?.getter?.symbol
|
||||
|
||||
override fun findTopLevelExtensionPropertyGetter(packageName: FqName, name: Name, extensionParameterClassID: ClassId): IrSimpleFunctionSymbol? {
|
||||
val extensionParameterConeKotlinType = extensionParameterClassID.constructClassLikeType(arrayOf(), false).type
|
||||
return irBuiltIns.findProperties(name, packageName).singleOrNull {
|
||||
((it.owner as Fir2IrLazyProperty).fir.receiverParameter?.typeRef as FirResolvedTypeRef).type == extensionParameterConeKotlinType
|
||||
}?.owner?.getter?.symbol
|
||||
override fun isExtensionReceiverClass(function: IrFunctionSymbol, expected: IrClassSymbol?): Boolean {
|
||||
return function.descriptor.extensionReceiverParameter?.type?.let { TypeUtils.getClassDescriptor(it) } == expected?.descriptor
|
||||
}
|
||||
|
||||
override val interopNativePointedGetRawPointer = findSingleInteropFunction(InteropFqNames.nativePointedGetRawPointerFunName) {
|
||||
val extensionReceiverParameter = it.owner.extensionReceiverParameter
|
||||
extensionReceiverParameter != null &&
|
||||
extensionReceiverParameter.type.classFqName?.toUnsafe() == InteropFqNames.nativePointed
|
||||
}
|
||||
override val interopCValueWrite = findSingleInteropFunction(InteropFqNames.cValueWriteFunName) {
|
||||
it.owner.extensionReceiverParameter?.type?.classFqName == InteropFqNames.cValue
|
||||
}
|
||||
override val interopCValueRead = findSingleInteropFunction(InteropFqNames.cValueReadFunName) {
|
||||
it.owner.valueParameters.size == 1
|
||||
}
|
||||
override val interopAllocType = findSingleInteropFunction(InteropFqNames.allocTypeFunName) {
|
||||
it.owner.extensionReceiverParameter != null && it.owner.valueParameters.singleOrNull()?.name?.toString() == "type"
|
||||
}
|
||||
override val interopCPointerGetRawValue = findSingleInteropFunction(InteropFqNames.cPointerGetRawValueFunName) {
|
||||
it.owner.extensionReceiverParameter?.type?.classFqName?.toUnsafe() == InteropFqNames.cPointer
|
||||
override fun findGetter(property: IrPropertySymbol): IrSimpleFunctionSymbol = symbolTable.referenceSimpleFunction(property.descriptor.getter!!)
|
||||
|
||||
override fun isExtensionReceiverNullable(function: IrFunctionSymbol): Boolean? {
|
||||
return function.descriptor.extensionReceiverParameter?.type?.isMarkedNullable
|
||||
}
|
||||
|
||||
override val interopGetPtr = irBuiltIns.findProperties(Name.identifier("ptr"), InteropFqNames.packageName).single {
|
||||
val singleTypeParameter = it.owner.getter?.typeParameters?.singleOrNull()
|
||||
val singleTypeParameterUpperBound = singleTypeParameter?.symbol?.superTypes()?.singleOrNull()
|
||||
val extensionReceiverParameter = it.owner.getter?.extensionReceiverParameter
|
||||
override fun getValueParametersCount(function: IrFunctionSymbol): Int = function.descriptor.valueParameters.size
|
||||
|
||||
singleTypeParameterUpperBound != null &&
|
||||
extensionReceiverParameter != null &&
|
||||
singleTypeParameterUpperBound.classFqName == InteropFqNames.cPointed &&
|
||||
extensionReceiverParameter.type.classFqName == singleTypeParameter.defaultType.classFqName
|
||||
}.owner.getter!!.symbol
|
||||
override fun getTypeParametersCount(function: IrFunctionSymbol): Int = function.descriptor.typeParameters.size
|
||||
|
||||
override val interopManagedGetPtr = irBuiltIns.findProperties(Name.identifier("ptr"), InteropFqNames.packageName).single {
|
||||
val singleTypeParameter = it.owner.getter?.typeParameters?.singleOrNull()
|
||||
val singleTypeParameterUpperBound = singleTypeParameter?.symbol?.superTypes()?.singleOrNull()
|
||||
val extensionReceiverParameter = it.owner.getter?.extensionReceiverParameter
|
||||
private fun match(type: KotlinType?, symbol: IrClassSymbol?) =
|
||||
if (type == null)
|
||||
symbol == null
|
||||
else
|
||||
TypeUtils.getClassDescriptor(type) == symbol?.descriptor
|
||||
|
||||
singleTypeParameterUpperBound != null &&
|
||||
extensionReceiverParameter != null &&
|
||||
singleTypeParameterUpperBound.classFqName == InteropFqNames.cStructVar &&
|
||||
extensionReceiverParameter.type.classFqName == InteropFqNames.managedType
|
||||
}.owner.getter!!.symbol
|
||||
override fun isTypeParameterUpperBoundClass(property: IrPropertySymbol, index: Int, expected: IrClassSymbol): Boolean {
|
||||
return property.descriptor.typeParameters.getOrNull(index)?.upperBounds?.any { match(it, expected) } ?: false
|
||||
}
|
||||
|
||||
private fun findSingleInteropFunction(name: String, predicate: (IrSimpleFunctionSymbol) -> Boolean) =
|
||||
irBuiltIns.findFunctions(Name.identifier(name), InteropFqNames.packageName).single(predicate)
|
||||
override fun isValueParameterClass(function: IrFunctionSymbol, index: Int, expected: IrClassSymbol?): Boolean {
|
||||
return match(function.descriptor.valueParameters.getOrNull(index)?.type, expected)
|
||||
}
|
||||
|
||||
override fun findDefaultConstructor(className: String): IrConstructorSymbol =
|
||||
interopClass(className).owner.declarations.single {
|
||||
it is IrConstructor && it.isPrimary
|
||||
}.symbol as IrConstructorSymbol
|
||||
override fun isReturnClass(function: IrFunctionSymbol, expected: IrClassSymbol): Boolean {
|
||||
return match(function.descriptor.returnType, expected)
|
||||
}
|
||||
|
||||
override fun findDefaultConstructor(className: String, nestedClassName: String): IrConstructorSymbol {
|
||||
val nested = interopClass(className).owner.declarations.single {
|
||||
it is IrClass && it.name == Name.identifier(nestedClassName)
|
||||
}.symbol as IrClassSymbol
|
||||
return nested.owner.declarations.single {
|
||||
it is IrConstructor && it.isPrimary
|
||||
}.symbol as IrConstructorSymbol
|
||||
override fun isValueParameterTypeArgumentClass(function: IrFunctionSymbol, index: Int, argumentIndex: Int, expected: IrClassSymbol?): Boolean {
|
||||
return match(function.descriptor.valueParameters.getOrNull(index)?.type?.arguments?.getOrNull(argumentIndex)?.type, expected)
|
||||
}
|
||||
|
||||
override fun isValueParameterNullable(function: IrFunctionSymbol, index: Int): Boolean? {
|
||||
return function.descriptor.valueParameters.getOrNull(index)?.type?.isMarkedNullable
|
||||
}
|
||||
|
||||
override fun isExpect(function: IrFunctionSymbol): Boolean = function.descriptor.isExpect
|
||||
|
||||
override fun isSuspend(functionSymbol: IrFunctionSymbol): Boolean = functionSymbol.descriptor.isSuspend
|
||||
override fun getVisibility(function: IrFunctionSymbol): DescriptorVisibility = function.descriptor.visibility
|
||||
|
||||
override fun findPrimaryConstructor(clazz: IrClassSymbol) = clazz.descriptor.unsubstitutedPrimaryConstructor?.let { symbolTable.referenceConstructor(it) }
|
||||
override fun findNoParametersConstructor(clazz: IrClassSymbol) = clazz.descriptor.constructors.singleOrNull { it.valueParameters.size == 0 }?.let { symbolTable.referenceConstructor(it) }
|
||||
|
||||
override fun findNestedClass(clazz: IrClassSymbol, name: Name): IrClassSymbol? {
|
||||
val classDescriptor = clazz.descriptor.defaultType.memberScope.getContributedClassifier(name, NoLookupLocation.FROM_BUILTINS) as? ClassDescriptor
|
||||
return classDescriptor?.let {
|
||||
symbolTable.referenceClass(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getValueParameterPrimitiveBinaryType(function: IrFunctionSymbol, index: Int): PrimitiveBinaryType? {
|
||||
return function.descriptor.valueParameters[0].type.computePrimitiveBinaryTypeOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
internal class SymbolOverIrLookupUtils() : SymbolLookupUtils {
|
||||
override fun findMemberFunction(clazz: IrClassSymbol, name: Name): IrSimpleFunctionSymbol? =
|
||||
clazz.owner.findDeclaration<IrSimpleFunction> { it.name == name }?.symbol
|
||||
|
||||
override fun findMemberProperty(clazz: IrClassSymbol, name: Name): IrPropertySymbol? =
|
||||
clazz.owner.findDeclaration<IrProperty> { it.name == name }?.symbol
|
||||
|
||||
override fun findMemberPropertyGetter(clazz: IrClassSymbol, name: Name): IrSimpleFunctionSymbol? =
|
||||
clazz.owner.findDeclaration<IrProperty> { it.name == name }?.getter?.symbol
|
||||
|
||||
override fun findPrimaryConstructor(clazz: IrClassSymbol): IrConstructorSymbol? = clazz.owner.primaryConstructor?.symbol
|
||||
override fun findNoParametersConstructor(clazz: IrClassSymbol): IrConstructorSymbol? = clazz.owner.constructors.singleOrNull { it.valueParameters.isEmpty() }?.symbol
|
||||
|
||||
override fun findNestedClass(clazz: IrClassSymbol, name: Name): IrClassSymbol? {
|
||||
return clazz.owner.declarations.filterIsInstance<IrClass>().singleOrNull { it.name == name }?.symbol
|
||||
}
|
||||
|
||||
override fun getName(clazz: IrClassSymbol): Name = clazz.owner.name
|
||||
|
||||
override fun isExtensionReceiverClass(property: IrPropertySymbol, expected: IrClassSymbol?): Boolean {
|
||||
return property.owner.getter?.extensionReceiverParameter?.type?.classOrNull == expected
|
||||
}
|
||||
|
||||
override fun isExtensionReceiverClass(function: IrFunctionSymbol, expected: IrClassSymbol?): Boolean {
|
||||
return function.owner.extensionReceiverParameter?.type?.classOrNull == expected
|
||||
}
|
||||
|
||||
override fun findGetter(property: IrPropertySymbol): IrSimpleFunctionSymbol? = property.owner.getter?.symbol
|
||||
|
||||
override fun isExtensionReceiverNullable(function: IrFunctionSymbol): Boolean? {
|
||||
return function.owner.extensionReceiverParameter?.type?.isMarkedNullable()
|
||||
}
|
||||
|
||||
override fun getValueParametersCount(function: IrFunctionSymbol): Int = function.owner.valueParameters.size
|
||||
|
||||
override fun getTypeParametersCount(function: IrFunctionSymbol): Int = function.owner.typeParameters.size
|
||||
|
||||
override fun isTypeParameterUpperBoundClass(property: IrPropertySymbol, index: Int, expected: IrClassSymbol): Boolean {
|
||||
return property.owner.getter?.typeParameters?.getOrNull(index)?.superTypes?.any { it.classOrNull == expected } ?: false
|
||||
}
|
||||
|
||||
override fun isValueParameterClass(function: IrFunctionSymbol, index: Int, expected: IrClassSymbol?): Boolean {
|
||||
return function.owner.valueParameters.getOrNull(index)?.type?.classOrNull == expected
|
||||
}
|
||||
|
||||
override fun isReturnClass(function: IrFunctionSymbol, expected: IrClassSymbol): Boolean {
|
||||
return function.owner.returnType.classOrNull == expected
|
||||
}
|
||||
|
||||
override fun isValueParameterTypeArgumentClass(function: IrFunctionSymbol, index: Int, argumentIndex: Int, expected: IrClassSymbol?): Boolean {
|
||||
val type = function.owner.valueParameters.getOrNull(index)?.type as? IrSimpleType ?: return false
|
||||
val argumentType = type.arguments.getOrNull(argumentIndex) as? IrSimpleType ?: return false
|
||||
return argumentType.classOrNull == expected
|
||||
}
|
||||
|
||||
override fun isValueParameterNullable(function: IrFunctionSymbol, index: Int): Boolean? {
|
||||
return function.owner.valueParameters.getOrNull(index)?.type?.isMarkedNullable()
|
||||
}
|
||||
|
||||
override fun isExpect(function: IrFunctionSymbol): Boolean = function.owner.isExpect
|
||||
|
||||
override fun isSuspend(functionSymbol: IrFunctionSymbol): Boolean = functionSymbol.owner.isSuspend
|
||||
override fun getVisibility(function: IrFunctionSymbol): DescriptorVisibility = function.owner.visibility
|
||||
|
||||
override fun getValueParameterPrimitiveBinaryType(function: IrFunctionSymbol, index: Int): PrimitiveBinaryType? {
|
||||
return function.owner.valueParameters[0].type.computePrimitiveBinaryTypeOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.llvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isArray
|
||||
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
|
||||
internal fun findMainEntryPoint(context: PhaseContext, builtIns: KotlinBuiltIns): FunctionDescriptor? {
|
||||
|
||||
val config = context.config.configuration
|
||||
if (config.get(KonanConfigKeys.PRODUCE) != PROGRAM) return null
|
||||
|
||||
val entryPoint = FqName(config.get(KonanConfigKeys.ENTRY) ?: defaultEntryName(config))
|
||||
|
||||
val entryName = entryPoint.shortName()
|
||||
val packageName = entryPoint.parent()
|
||||
|
||||
val packageScope = builtIns.builtInsModule.getPackage(packageName).memberScope
|
||||
|
||||
val candidates = packageScope.getContributedFunctions(entryName,
|
||||
NoLookupLocation.FROM_BACKEND).filter {
|
||||
it.returnType?.isUnit() == true &&
|
||||
it.typeParameters.isEmpty() &&
|
||||
it.visibility.isPublicAPI
|
||||
}
|
||||
|
||||
val main =
|
||||
candidates.singleOrNull { it.hasSingleArrayOfStringParameter } ?:
|
||||
candidates.singleOrNull { it.hasNoParameters } ?:
|
||||
context.reportCompilationError("Could not find '$entryName' in '$packageName' package.")
|
||||
|
||||
if (main.isSuspend)
|
||||
context.reportCompilationError("Entry point can not be a suspend function.")
|
||||
|
||||
return main
|
||||
}
|
||||
|
||||
private fun defaultEntryName(config: CompilerConfiguration): String =
|
||||
when (config.get(KonanConfigKeys.GENERATE_TEST_RUNNER)) {
|
||||
TestRunnerKind.MAIN_THREAD -> "kotlin.native.internal.test.main"
|
||||
TestRunnerKind.WORKER -> "kotlin.native.internal.test.worker"
|
||||
TestRunnerKind.MAIN_THREAD_NO_EXIT -> "kotlin.native.internal.test.mainNoExit"
|
||||
else -> "main"
|
||||
}
|
||||
|
||||
private val KotlinType.filterClass: ClassDescriptor?
|
||||
get() {
|
||||
val constr = constructor.declarationDescriptor
|
||||
return constr as? ClassDescriptor
|
||||
}
|
||||
|
||||
private val ClassDescriptor.isString
|
||||
get() = fqNameSafe.asString() == "kotlin.String"
|
||||
|
||||
private val KotlinType.isString
|
||||
get() = filterClass?.isString ?: false
|
||||
|
||||
private val KotlinType.isArrayOfString: Boolean
|
||||
get() = (filterClass?.isArray ?: false) &&
|
||||
(arguments.singleOrNull()?.type?.isString ?: false)
|
||||
|
||||
private val FunctionDescriptor.hasSingleArrayOfStringParameter: Boolean
|
||||
get() = valueParameters.singleOrNull()?.type?.isArrayOfString ?: false
|
||||
|
||||
private val FunctionDescriptor.hasNoParameters: Boolean
|
||||
get() = valueParameters.isEmpty()
|
||||
Reference in New Issue
Block a user