diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/codegen/AndroidIrExtension.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/codegen/AndroidIrExtension.kt index 140624fc4c0..eab35a39547 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/codegen/AndroidIrExtension.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/codegen/AndroidIrExtension.kt @@ -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()?.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) + }