Android Extensions: Do not upcast ViewStub to View (KT-10321)
This commit is contained in:
+1
-1
@@ -96,7 +96,7 @@ class AndroidExpressionCodegenExtension : ExpressionCodegenExtension {
|
|||||||
fun isCacheSupported(receiverDescriptor: ClassDescriptor, descriptor: PropertyDescriptor? = null): Boolean {
|
fun isCacheSupported(receiverDescriptor: ClassDescriptor, descriptor: PropertyDescriptor? = null): Boolean {
|
||||||
val receiverIsKotlinClass = receiverDescriptor.source is KotlinSourceElement
|
val receiverIsKotlinClass = receiverDescriptor.source is KotlinSourceElement
|
||||||
return receiverIsKotlinClass && when (descriptor) {
|
return receiverIsKotlinClass && when (descriptor) {
|
||||||
is AndroidSyntheticProperty -> !descriptor.alwaysCastToView
|
is AndroidSyntheticProperty -> descriptor.cacheView
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.utils.Printer
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class AndroidSyntheticPackageData(
|
class AndroidSyntheticPackageData(
|
||||||
|
val layoutName: String,
|
||||||
val moduleData: AndroidModuleData,
|
val moduleData: AndroidModuleData,
|
||||||
val forView: Boolean,
|
val forView: Boolean,
|
||||||
val isDeprecated: Boolean,
|
val isDeprecated: Boolean,
|
||||||
@@ -68,7 +69,7 @@ class AndroidSyntheticPackageFragmentDescriptor(
|
|||||||
}
|
}
|
||||||
is AndroidResource.Fragment -> if (!packageData.forView) {
|
is AndroidResource.Fragment -> if (!packageData.forView) {
|
||||||
for ((receiverType, type) in fragmentTypes) {
|
for ((receiverType, type) in fragmentTypes) {
|
||||||
properties += genPropertyForFragment(packageFragmentDescriptor, receiverType, type, resource, context)
|
properties += genPropertyForFragment(packageFragmentDescriptor, receiverType, type, resource)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ abstract class AndroidPackageFragmentProviderExtension : PackageFragmentProvider
|
|||||||
for ((layoutName, layouts) in variantData) {
|
for ((layoutName, layouts) in variantData) {
|
||||||
fun createPackageFragment(fqName: String, forView: Boolean, isDeprecated: Boolean = false) {
|
fun createPackageFragment(fqName: String, forView: Boolean, isDeprecated: Boolean = false) {
|
||||||
val resources = layoutXmlFileManager.extractResources(layouts, module)
|
val resources = layoutXmlFileManager.extractResources(layouts, module)
|
||||||
val packageData = AndroidSyntheticPackageData(moduleData, forView, isDeprecated, resources)
|
val packageData = AndroidSyntheticPackageData(layoutName, moduleData, forView, isDeprecated, resources)
|
||||||
val packageDescriptor = AndroidSyntheticPackageFragmentDescriptor(
|
val packageDescriptor = AndroidSyntheticPackageFragmentDescriptor(
|
||||||
module, FqName(fqName), packageData, lazyContext, storageManager)
|
module, FqName(fqName), packageData, lazyContext, storageManager)
|
||||||
packagesToLookupInCompletion += packageDescriptor
|
packagesToLookupInCompletion += packageDescriptor
|
||||||
|
|||||||
+9
-12
@@ -66,30 +66,28 @@ internal fun genPropertyForWidget(
|
|||||||
defaultType.constructor.parameters.map { StarProjectionImpl(it) })
|
defaultType.constructor.parameters.map { StarProjectionImpl(it) })
|
||||||
} ?: context.viewType
|
} ?: 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(
|
internal fun genPropertyForFragment(
|
||||||
packageFragmentDescriptor: PackageFragmentDescriptor,
|
packageFragmentDescriptor: AndroidSyntheticPackageFragmentDescriptor,
|
||||||
receiverType: KotlinType,
|
receiverType: KotlinType,
|
||||||
type: KotlinType,
|
type: KotlinType,
|
||||||
fragment: AndroidResource.Fragment,
|
fragment: AndroidResource.Fragment
|
||||||
context: SyntheticElementResolveContext
|
|
||||||
): PropertyDescriptor {
|
): PropertyDescriptor {
|
||||||
val sourceElement = fragment.sourceElement?.let { XmlSourceElement(it) } ?: SourceElement.NO_SOURCE
|
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(
|
private fun genProperty(
|
||||||
id: ResourceIdentifier,
|
id: ResourceIdentifier,
|
||||||
receiverType: KotlinType,
|
receiverType: KotlinType,
|
||||||
type: KotlinType,
|
type: KotlinType,
|
||||||
containingDeclaration: DeclarationDescriptor,
|
containingDeclaration: AndroidSyntheticPackageFragmentDescriptor,
|
||||||
sourceElement: SourceElement,
|
sourceElement: SourceElement,
|
||||||
context: SyntheticElementResolveContext,
|
|
||||||
errorType: String?
|
errorType: String?
|
||||||
): PropertyDescriptor {
|
): 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(
|
val property = object : AndroidSyntheticProperty, PropertyDescriptorImpl(
|
||||||
containingDeclaration,
|
containingDeclaration,
|
||||||
@@ -104,12 +102,11 @@ private fun genProperty(
|
|||||||
false,
|
false,
|
||||||
false) {
|
false) {
|
||||||
override val errorType = errorType
|
override val errorType = errorType
|
||||||
override val alwaysCastToView = alwaysCastToView
|
override val cacheView = cacheView
|
||||||
override val resourceId = id
|
override val resourceId = id
|
||||||
}
|
}
|
||||||
|
|
||||||
val actualType = if (alwaysCastToView) context.viewType else type
|
val flexibleType = DelegatingFlexibleType.create(type, type.makeNullable(), FlexibleTypeCapabilities.NONE)
|
||||||
val flexibleType = DelegatingFlexibleType.create(actualType, actualType.makeNullable(), FlexibleTypeCapabilities.NONE)
|
|
||||||
property.setType(
|
property.setType(
|
||||||
flexibleType,
|
flexibleType,
|
||||||
emptyList<TypeParameterDescriptor>(),
|
emptyList<TypeParameterDescriptor>(),
|
||||||
@@ -139,7 +136,7 @@ interface AndroidSyntheticFunction
|
|||||||
|
|
||||||
interface AndroidSyntheticProperty {
|
interface AndroidSyntheticProperty {
|
||||||
val errorType: String?
|
val errorType: String?
|
||||||
val alwaysCastToView: Boolean
|
val cacheView: Boolean
|
||||||
val resourceId: ResourceIdentifier
|
val resourceId: ResourceIdentifier
|
||||||
|
|
||||||
val isErrorType: Boolean
|
val isErrorType: Boolean
|
||||||
|
|||||||
+1
-1
@@ -14,5 +14,5 @@ public class MyActivity : Activity() {
|
|||||||
// 1 GETSTATIC test/R\$id\.stub
|
// 1 GETSTATIC test/R\$id\.stub
|
||||||
// 0 INVOKEVIRTUAL test/MyActivity\._\$_findCachedViewById
|
// 0 INVOKEVIRTUAL test/MyActivity\._\$_findCachedViewById
|
||||||
// 1 INVOKEVIRTUAL android/app/Activity\.findViewById
|
// 1 INVOKEVIRTUAL android/app/Activity\.findViewById
|
||||||
// 0 CHECKCAST android/view/ViewStub
|
// 1 CHECKCAST android/view/ViewStub
|
||||||
// 2 CHECKCAST android/view/View
|
// 2 CHECKCAST android/view/View
|
||||||
Vendored
+3
-3
@@ -15,10 +15,10 @@ kotlinx.android.synthetic.main
|
|||||||
|
|
||||||
kotlinx.android.synthetic.main.test
|
kotlinx.android.synthetic.main.test
|
||||||
|
|
||||||
public val android.app.Activity.stub: android.view.View!
|
public val android.app.Activity.stub: android.view.ViewStub!
|
||||||
public val android.app.Fragment.stub: android.view.View!
|
public val android.app.Fragment.stub: android.view.ViewStub!
|
||||||
|
|
||||||
|
|
||||||
kotlinx.android.synthetic.main.test.view
|
kotlinx.android.synthetic.main.test.view
|
||||||
|
|
||||||
public val android.view.View.stub: android.view.View!
|
public val android.view.View.stub: android.view.ViewStub!
|
||||||
|
|||||||
Reference in New Issue
Block a user