From 371e80bcba9873251b5bc162aa624769b2cf75bb Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 25 Mar 2016 17:58:56 +0300 Subject: [PATCH] Android Extensions: Do not upcast ViewStub to View (KT-10321) --- .../AndroidExpressionCodegenExtension.kt | 2 +- ...droidSyntheticPackageFragmentDescriptor.kt | 3 ++- ...AndroidPackageFragmentProviderExtension.kt | 2 +- .../res/syntheticDescriptorGeneration.kt | 21 ++++++++----------- .../bytecodeShape/viewStub/viewStub.kt | 2 +- .../testData/descriptors/viewStub/result.txt | 6 +++--- 6 files changed, 17 insertions(+), 19 deletions(-) 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 3c56a8e3efc..0500c1042f6 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 @@ -96,7 +96,7 @@ class AndroidExpressionCodegenExtension : ExpressionCodegenExtension { fun isCacheSupported(receiverDescriptor: ClassDescriptor, descriptor: PropertyDescriptor? = null): Boolean { val receiverIsKotlinClass = receiverDescriptor.source is KotlinSourceElement return receiverIsKotlinClass && when (descriptor) { - is AndroidSyntheticProperty -> !descriptor.alwaysCastToView + is AndroidSyntheticProperty -> descriptor.cacheView else -> true } } 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 9d92ad06873..cd4567886d7 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 @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.utils.Printer import java.util.* class AndroidSyntheticPackageData( + val layoutName: String, val moduleData: AndroidModuleData, val forView: Boolean, val isDeprecated: Boolean, @@ -68,7 +69,7 @@ class AndroidSyntheticPackageFragmentDescriptor( } is AndroidResource.Fragment -> if (!packageData.forView) { for ((receiverType, type) in fragmentTypes) { - properties += genPropertyForFragment(packageFragmentDescriptor, receiverType, type, resource, context) + properties += genPropertyForFragment(packageFragmentDescriptor, receiverType, type, resource) } } } 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 fcd49dfa00a..4246fbe3aa4 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 @@ -52,7 +52,7 @@ abstract class AndroidPackageFragmentProviderExtension : PackageFragmentProvider for ((layoutName, layouts) in variantData) { fun createPackageFragment(fqName: String, forView: Boolean, isDeprecated: Boolean = false) { val resources = layoutXmlFileManager.extractResources(layouts, module) - val packageData = AndroidSyntheticPackageData(moduleData, forView, isDeprecated, resources) + val packageData = AndroidSyntheticPackageData(layoutName, moduleData, forView, isDeprecated, resources) val packageDescriptor = AndroidSyntheticPackageFragmentDescriptor( module, FqName(fqName), packageData, lazyContext, storageManager) packagesToLookupInCompletion += packageDescriptor diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/syntheticDescriptorGeneration.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/syntheticDescriptorGeneration.kt index c8a6470c956..bba34927bf4 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/syntheticDescriptorGeneration.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/syntheticDescriptorGeneration.kt @@ -66,30 +66,28 @@ internal fun genPropertyForWidget( defaultType.constructor.parameters.map { StarProjectionImpl(it) }) } ?: context.viewType - return genProperty(resolvedWidget.widget.id, receiverType, type, packageFragmentDescriptor, sourceEl, context, resolvedWidget.errorType) + return genProperty(resolvedWidget.widget.id, receiverType, type, packageFragmentDescriptor, sourceEl, resolvedWidget.errorType) } internal fun genPropertyForFragment( - packageFragmentDescriptor: PackageFragmentDescriptor, + packageFragmentDescriptor: AndroidSyntheticPackageFragmentDescriptor, receiverType: KotlinType, type: KotlinType, - fragment: AndroidResource.Fragment, - context: SyntheticElementResolveContext + fragment: AndroidResource.Fragment ): PropertyDescriptor { val sourceElement = fragment.sourceElement?.let { XmlSourceElement(it) } ?: SourceElement.NO_SOURCE - return genProperty(fragment.id, receiverType, type, packageFragmentDescriptor, sourceElement, context, null) + return genProperty(fragment.id, receiverType, type, packageFragmentDescriptor, sourceElement, null) } private fun genProperty( id: ResourceIdentifier, receiverType: KotlinType, type: KotlinType, - containingDeclaration: DeclarationDescriptor, + containingDeclaration: AndroidSyntheticPackageFragmentDescriptor, sourceElement: SourceElement, - context: SyntheticElementResolveContext, errorType: String? ): PropertyDescriptor { - val alwaysCastToView = type.constructor.declarationDescriptor?.fqNameUnsafe?.asString() == AndroidConst.VIEWSTUB_FQNAME + val cacheView = type.constructor.declarationDescriptor?.fqNameUnsafe?.asString() != AndroidConst.VIEWSTUB_FQNAME val property = object : AndroidSyntheticProperty, PropertyDescriptorImpl( containingDeclaration, @@ -104,12 +102,11 @@ private fun genProperty( false, false) { override val errorType = errorType - override val alwaysCastToView = alwaysCastToView + override val cacheView = cacheView override val resourceId = id } - val actualType = if (alwaysCastToView) context.viewType else type - val flexibleType = DelegatingFlexibleType.create(actualType, actualType.makeNullable(), FlexibleTypeCapabilities.NONE) + val flexibleType = DelegatingFlexibleType.create(type, type.makeNullable(), FlexibleTypeCapabilities.NONE) property.setType( flexibleType, emptyList(), @@ -139,7 +136,7 @@ interface AndroidSyntheticFunction interface AndroidSyntheticProperty { val errorType: String? - val alwaysCastToView: Boolean + val cacheView: Boolean val resourceId: ResourceIdentifier val isErrorType: Boolean diff --git a/plugins/android-extensions/android-extensions-compiler/testData/codegen/bytecodeShape/viewStub/viewStub.kt b/plugins/android-extensions/android-extensions-compiler/testData/codegen/bytecodeShape/viewStub/viewStub.kt index 40f701398b9..81c59765e96 100644 --- a/plugins/android-extensions/android-extensions-compiler/testData/codegen/bytecodeShape/viewStub/viewStub.kt +++ b/plugins/android-extensions/android-extensions-compiler/testData/codegen/bytecodeShape/viewStub/viewStub.kt @@ -14,5 +14,5 @@ public class MyActivity : Activity() { // 1 GETSTATIC test/R\$id\.stub // 0 INVOKEVIRTUAL test/MyActivity\._\$_findCachedViewById // 1 INVOKEVIRTUAL android/app/Activity\.findViewById -// 0 CHECKCAST android/view/ViewStub +// 1 CHECKCAST android/view/ViewStub // 2 CHECKCAST android/view/View \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-compiler/testData/descriptors/viewStub/result.txt b/plugins/android-extensions/android-extensions-compiler/testData/descriptors/viewStub/result.txt index c4f583276cd..3d96bc7e014 100644 --- a/plugins/android-extensions/android-extensions-compiler/testData/descriptors/viewStub/result.txt +++ b/plugins/android-extensions/android-extensions-compiler/testData/descriptors/viewStub/result.txt @@ -15,10 +15,10 @@ kotlinx.android.synthetic.main kotlinx.android.synthetic.main.test - public val android.app.Activity.stub: android.view.View! - public val android.app.Fragment.stub: android.view.View! + public val android.app.Activity.stub: android.view.ViewStub! + public val android.app.Fragment.stub: android.view.ViewStub! kotlinx.android.synthetic.main.test.view - public val android.view.View.stub: android.view.View! \ No newline at end of file + public val android.view.View.stub: android.view.ViewStub!