Android Extensions: Support Dialog classes (KT-16957)

This commit is contained in:
Yan Zhulanow
2017-03-21 18:46:38 +03:00
parent f1e303e18d
commit cba523958e
23 changed files with 101 additions and 11 deletions
@@ -45,6 +45,7 @@ object AndroidConst {
val ACTIVITY_FQNAME = "android.app.Activity"
val FRAGMENT_FQNAME = "android.app.Fragment"
val DIALOG_FQNAME = "android.app.Dialog"
val SUPPORT_V4_PACKAGE = "android.support.v4"
val SUPPORT_FRAGMENT_FQNAME = "$SUPPORT_V4_PACKAGE.app.Fragment"
val SUPPORT_FRAGMENT_ACTIVITY_FQNAME = "$SUPPORT_V4_PACKAGE.app.FragmentActivity"
@@ -48,6 +48,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
enum class AndroidClassType(className: String, val supportsCache: Boolean = false, val fragment: Boolean = false) {
ACTIVITY(AndroidConst.ACTIVITY_FQNAME, supportsCache = true),
FRAGMENT(AndroidConst.FRAGMENT_FQNAME, supportsCache = true, fragment = true),
DIALOG(AndroidConst.DIALOG_FQNAME, supportsCache = false),
SUPPORT_FRAGMENT_ACTIVITY(AndroidConst.SUPPORT_FRAGMENT_ACTIVITY_FQNAME, supportsCache = true),
SUPPORT_FRAGMENT(AndroidConst.SUPPORT_FRAGMENT_FQNAME, supportsCache = true, fragment = true),
VIEW(AndroidConst.VIEW_FQNAME),
@@ -60,6 +61,7 @@ enum class AndroidClassType(className: String, val supportsCache: Boolean = fals
fun getClassTypeInternal(name: String): AndroidClassType? = when (name) {
AndroidConst.ACTIVITY_FQNAME -> AndroidClassType.ACTIVITY
AndroidConst.FRAGMENT_FQNAME -> AndroidClassType.FRAGMENT
AndroidConst.DIALOG_FQNAME -> AndroidClassType.DIALOG
AndroidConst.SUPPORT_FRAGMENT_ACTIVITY_FQNAME -> AndroidClassType.SUPPORT_FRAGMENT_ACTIVITY
AndroidConst.SUPPORT_FRAGMENT_FQNAME -> AndroidClassType.SUPPORT_FRAGMENT
AndroidConst.VIEW_FQNAME -> AndroidClassType.VIEW
@@ -194,7 +196,7 @@ class AndroidExpressionCodegenExtension : ExpressionCodegenExtension {
}
else {
when (androidClassType) {
AndroidClassType.ACTIVITY, AndroidClassType.SUPPORT_FRAGMENT_ACTIVITY, AndroidClassType.VIEW -> {
AndroidClassType.ACTIVITY, AndroidClassType.SUPPORT_FRAGMENT_ACTIVITY, AndroidClassType.VIEW, AndroidClassType.DIALOG -> {
receiver.put(Type.getType("L${androidClassType.internalClassName};"), v)
getResourceId(v)
v.invokevirtual(androidClassType.internalClassName, "findViewById", "(I)Landroid/view/View;", false)
@@ -370,7 +372,7 @@ class AndroidExpressionCodegenExtension : ExpressionCodegenExtension {
// Resolve View via findViewById if not in cache
iv.load(0, classType)
when (androidClassType) {
AndroidClassType.ACTIVITY, AndroidClassType.SUPPORT_FRAGMENT_ACTIVITY, AndroidClassType.VIEW -> {
AndroidClassType.ACTIVITY, AndroidClassType.SUPPORT_FRAGMENT_ACTIVITY, AndroidClassType.VIEW, AndroidClassType.DIALOG -> {
loadId()
iv.invokevirtual(className, "findViewById", "(I)Landroid/view/View;", false)
}
@@ -63,7 +63,7 @@ class AndroidSyntheticPackageFragmentDescriptor(
val resolvedWidget = resource.resolve(module)
if (resolvedWidget != null) {
for (receiver in widgetReceivers) {
properties += genPropertyForWidget(packageFragmentDescriptor, receiver, resolvedWidget, context)
properties += genPropertyForWidget(packageFragmentDescriptor, receiver.type, resolvedWidget, context)
}
}
}
@@ -41,6 +41,7 @@ class LazySyntheticElementResolveContext(private val module: ModuleDescriptor, s
val viewDescriptor = find(AndroidConst.VIEW_FQNAME) ?: return SyntheticElementResolveContext.ERROR_CONTEXT
val activityDescriptor = find(AndroidConst.ACTIVITY_FQNAME) ?: return SyntheticElementResolveContext.ERROR_CONTEXT
val fragmentDescriptor = find(AndroidConst.FRAGMENT_FQNAME)
val dialogDescriptor = find(AndroidConst.DIALOG_FQNAME) ?: return SyntheticElementResolveContext.ERROR_CONTEXT
val supportActivityDescriptor = find(AndroidConst.SUPPORT_FRAGMENT_ACTIVITY_FQNAME)
val supportFragmentDescriptor = find(AndroidConst.SUPPORT_FRAGMENT_FQNAME)
@@ -48,6 +49,7 @@ class LazySyntheticElementResolveContext(private val module: ModuleDescriptor, s
viewDescriptor.defaultType,
activityDescriptor.defaultType,
fragmentDescriptor?.defaultType,
dialogDescriptor.defaultType,
supportActivityDescriptor?.defaultType,
supportFragmentDescriptor?.defaultType)
}
@@ -57,18 +59,20 @@ internal class SyntheticElementResolveContext(
val viewType: SimpleType,
val activityType: SimpleType,
val fragmentType: SimpleType?,
val dialogType: SimpleType,
val supportActivityType: SimpleType?,
val supportFragmentType: SimpleType?) {
companion object {
private fun errorType() = ErrorUtils.createErrorType("")
val ERROR_CONTEXT = SyntheticElementResolveContext(errorType(), errorType(), null, null, null)
val ERROR_CONTEXT = SyntheticElementResolveContext(errorType(), errorType(), null, errorType(), null, null)
}
private val widgetReceivers by lazy {
val receivers = ArrayList<KotlinType>(3)
receivers += activityType
fragmentType?.let { receivers += it }
supportFragmentType?.let { receivers += it }
val receivers = ArrayList<WidgetReceiver>(4)
receivers += WidgetReceiver(activityType, mayHaveCache = true)
receivers += WidgetReceiver(dialogType, mayHaveCache = false)
fragmentType?.let { receivers += WidgetReceiver(it, mayHaveCache = true) }
supportFragmentType?.let { receivers += WidgetReceiver(it, mayHaveCache = true) }
receivers
}
@@ -88,8 +92,11 @@ internal class SyntheticElementResolveContext(
}
}
fun getWidgetReceivers(forView: Boolean): List<KotlinType> {
if (forView) return listOf(viewType)
fun getWidgetReceivers(forView: Boolean): List<WidgetReceiver> {
if (forView) return listOf(WidgetReceiver(viewType, mayHaveCache = false))
return widgetReceivers
}
}
class WidgetReceiver(val type: SimpleType, val mayHaveCache: Boolean)
@@ -79,7 +79,7 @@ abstract class AndroidPackageFragmentProviderExtension : PackageFragmentProvider
// Package with clearFindViewByIdCache()
AndroidConst.SYNTHETIC_SUBPACKAGES.last().let { s ->
val packageDescriptor = PredefinedPackageFragmentDescriptor(s, module, storageManager, packagesToLookupInCompletion) { descriptor ->
lazyContext().getWidgetReceivers(false).map { genClearCacheFunction(descriptor, it) }
lazyContext().getWidgetReceivers(false).filter { it.mayHaveCache }.map { genClearCacheFunction(descriptor, it.type) }
}
packagesToLookupInCompletion += packageDescriptor
allPackageDescriptors += packageDescriptor