diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/AndroidConst.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/AndroidConst.kt index 85cf7b6a773..678d83799d2 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/AndroidConst.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/AndroidConst.kt @@ -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" diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/codegen/AndroidExpressionCodegenExtension.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/codegen/AndroidExpressionCodegenExtension.kt index 62b62e7b11f..0c3946a6d62 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/codegen/AndroidExpressionCodegenExtension.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/codegen/AndroidExpressionCodegenExtension.kt @@ -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) } diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/AndroidSyntheticPackageFragmentDescriptor.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/AndroidSyntheticPackageFragmentDescriptor.kt index 14d5b8c3a7e..a9a1a2a4989 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/AndroidSyntheticPackageFragmentDescriptor.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/AndroidSyntheticPackageFragmentDescriptor.kt @@ -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) } } } diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/LazySyntheticElementResolveContext.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/LazySyntheticElementResolveContext.kt index 93b23405d27..8506a29554f 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/LazySyntheticElementResolveContext.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/LazySyntheticElementResolveContext.kt @@ -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(3) - receivers += activityType - fragmentType?.let { receivers += it } - supportFragmentType?.let { receivers += it } + val receivers = ArrayList(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 { - if (forView) return listOf(viewType) + fun getWidgetReceivers(forView: Boolean): List { + if (forView) return listOf(WidgetReceiver(viewType, mayHaveCache = false)) return widgetReceivers } + } + +class WidgetReceiver(val type: SimpleType, val mayHaveCache: Boolean) \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/AndroidPackageFragmentProviderExtension.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/AndroidPackageFragmentProviderExtension.kt index 4246fbe3aa4..06100e0a12a 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/AndroidPackageFragmentProviderExtension.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/AndroidPackageFragmentProviderExtension.kt @@ -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 diff --git a/plugins/android-extensions/android-extensions-compiler/testData/codegen/android/FakeDialog.kt b/plugins/android-extensions/android-extensions-compiler/testData/codegen/android/FakeDialog.kt new file mode 100644 index 00000000000..9cf31a60ad5 --- /dev/null +++ b/plugins/android-extensions/android-extensions-compiler/testData/codegen/android/FakeDialog.kt @@ -0,0 +1,7 @@ +package android.app + +import android.view.View + +open class Dialog { + open fun findViewById(id: Int): View? = null +} diff --git a/plugins/android-extensions/android-extensions-compiler/testData/codegen/bytecodeShape/dialog/dialog.kt b/plugins/android-extensions/android-extensions-compiler/testData/codegen/bytecodeShape/dialog/dialog.kt new file mode 100644 index 00000000000..0341cbddf70 --- /dev/null +++ b/plugins/android-extensions/android-extensions-compiler/testData/codegen/bytecodeShape/dialog/dialog.kt @@ -0,0 +1,13 @@ +package test + +import android.app.Dialog +import kotlinx.android.synthetic.main.layout.* + +fun test(dialog: Dialog) { + dialog.login +} + +// 1 GETSTATIC test/R\$id\.login +// 1 INVOKEVIRTUAL android/app/Dialog\.findViewById +// 1 CHECKCAST android/widget/Button +// 0 _\$_findCachedViewById \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-compiler/testData/codegen/bytecodeShape/dialog/res/layout/layout.xml b/plugins/android-extensions/android-extensions-compiler/testData/codegen/bytecodeShape/dialog/res/layout/layout.xml new file mode 100644 index 00000000000..4d73173b521 --- /dev/null +++ b/plugins/android-extensions/android-extensions-compiler/testData/codegen/bytecodeShape/dialog/res/layout/layout.xml @@ -0,0 +1,17 @@ + + + + +