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.impl.*
|
||||
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.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.isClass
|
||||
import org.jetbrains.kotlin.ir.util.isObject
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
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 fun isEnabled(declaration: IrClass): Boolean
|
||||
abstract fun isExperimental(declaration: IrClass): Boolean
|
||||
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) {
|
||||
moduleFragment.transform(AndroidIrTransformer(this, pluginContext), null)
|
||||
}
|
||||
@@ -214,3 +229,34 @@ private val IrClassifierSymbol.isFragment: Boolean
|
||||
get() = isClassWithFqName(FqNameUnsafe(AndroidConst.FRAGMENT_FQNAME)) ||
|
||||
isClassWithFqName(FqNameUnsafe(AndroidConst.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