Android Synthetics: Resolve unbound symbols in the AndroidIrExtension
This commit is contained in:
committed by
Alexander Udalov
parent
fe466f3dc6
commit
56c4a27887
+49
-3
@@ -31,19 +31,34 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.isClass
|
|
||||||
import org.jetbrains.kotlin.ir.util.isObject
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||||
abstract class AndroidIrExtension : IrGenerationExtension {
|
abstract class AndroidIrExtension : IrGenerationExtension {
|
||||||
abstract fun isEnabled(declaration: IrClass): Boolean
|
abstract fun isEnabled(declaration: IrClass): Boolean
|
||||||
abstract fun isExperimental(declaration: IrClass): Boolean
|
abstract fun isExperimental(declaration: IrClass): Boolean
|
||||||
abstract fun getGlobalCacheImpl(declaration: IrClass): CacheImplementation
|
abstract fun getGlobalCacheImpl(declaration: IrClass): CacheImplementation
|
||||||
|
|
||||||
|
override fun resolveSymbol(symbol: IrSymbol, context: TranslationPluginContext): IrDeclaration? =
|
||||||
|
if (symbol !is IrSimpleFunctionSymbol ||
|
||||||
|
(symbol.descriptor !is AndroidSyntheticFunction
|
||||||
|
&& symbol.descriptor.safeAs<PropertyGetterDescriptor>()?.correspondingProperty !is AndroidSyntheticProperty)) {
|
||||||
|
super.resolveSymbol(symbol, context)
|
||||||
|
} else {
|
||||||
|
// Replace android synthetic functions with stubs, since they are essentially intrinsics and will be replaced in the plugin
|
||||||
|
context.declareFunctionStub(symbol.descriptor).also { symbol.bind(it) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
|
override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
|
||||||
moduleFragment.transform(AndroidIrTransformer(this, pluginContext), null)
|
moduleFragment.transform(AndroidIrTransformer(this, pluginContext), null)
|
||||||
}
|
}
|
||||||
@@ -214,3 +229,34 @@ private val IrClassifierSymbol.isFragment: Boolean
|
|||||||
get() = isClassWithFqName(FqNameUnsafe(AndroidConst.FRAGMENT_FQNAME)) ||
|
get() = isClassWithFqName(FqNameUnsafe(AndroidConst.FRAGMENT_FQNAME)) ||
|
||||||
isClassWithFqName(FqNameUnsafe(AndroidConst.SUPPORT_FRAGMENT_FQNAME)) ||
|
isClassWithFqName(FqNameUnsafe(AndroidConst.SUPPORT_FRAGMENT_FQNAME)) ||
|
||||||
isClassWithFqName(FqNameUnsafe(AndroidConst.ANDROIDX_SUPPORT_FRAGMENT_FQNAME))
|
isClassWithFqName(FqNameUnsafe(AndroidConst.ANDROIDX_SUPPORT_FRAGMENT_FQNAME))
|
||||||
|
|
||||||
|
private fun TranslationPluginContext.declareTypeParameterStub(typeParameterDescriptor: TypeParameterDescriptor): IrTypeParameter {
|
||||||
|
val symbol = IrTypeParameterSymbolImpl(typeParameterDescriptor)
|
||||||
|
return irFactory.createTypeParameter(
|
||||||
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.DEFINED, symbol, typeParameterDescriptor.name,
|
||||||
|
typeParameterDescriptor.index, typeParameterDescriptor.isReified, typeParameterDescriptor.variance
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TranslationPluginContext.declareParameterStub(parameterDescriptor: ParameterDescriptor): IrValueParameter {
|
||||||
|
val symbol = IrValueParameterSymbolImpl(parameterDescriptor)
|
||||||
|
val type = typeTranslator.translateType(parameterDescriptor.type)
|
||||||
|
val varargElementType = parameterDescriptor.varargElementType?.let { typeTranslator.translateType(it) }
|
||||||
|
return irFactory.createValueParameter(
|
||||||
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.DEFINED, symbol, parameterDescriptor.name,
|
||||||
|
parameterDescriptor.indexOrMinusOne, type, varargElementType, parameterDescriptor.isCrossinline, parameterDescriptor.isNoinline
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TranslationPluginContext.declareFunctionStub(descriptor: FunctionDescriptor): IrSimpleFunction =
|
||||||
|
irFactory.buildFun {
|
||||||
|
name = descriptor.name
|
||||||
|
visibility = descriptor.visibility
|
||||||
|
returnType = typeTranslator.translateType(descriptor.returnType!!)
|
||||||
|
modality = descriptor.modality
|
||||||
|
}.also {
|
||||||
|
it.typeParameters = descriptor.propertyIfAccessor.typeParameters.map(this::declareTypeParameterStub)
|
||||||
|
it.dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.let(this::declareParameterStub)
|
||||||
|
it.extensionReceiverParameter = descriptor.extensionReceiverParameter?.let(this::declareParameterStub)
|
||||||
|
it.valueParameters = descriptor.valueParameters.map(this::declareParameterStub)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user