Android Extensions: Support smart-casted receivers (KT-18545)

This commit is contained in:
Yan Zhulanow
2017-06-27 19:52:21 +03:00
parent 9e9c4f79f5
commit bf2bc1fdc7
4 changed files with 52 additions and 1 deletions
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_PUBLIC
@@ -128,7 +129,23 @@ abstract class AbstractAndroidExtensionsExpressionCodegenExtension : ExpressionC
}
private fun ResolvedCall<*>.getReceiverDeclarationDescriptor(): ClassifierDescriptor? {
return (extensionReceiver as ReceiverValue).type.constructor.declarationDescriptor
val fromDeclarationSite = resultingDescriptor.extensionReceiverParameter?.type?.constructor?.declarationDescriptor
val fromCallSite = (extensionReceiver as ReceiverValue).type.constructor.declarationDescriptor
if (fromDeclarationSite == null && fromCallSite == null)
return null
else if (fromDeclarationSite != null && fromCallSite == null)
return fromDeclarationSite
else if (fromDeclarationSite == null && fromCallSite != null)
return fromCallSite
fromDeclarationSite as ClassifierDescriptor
fromCallSite as ClassifierDescriptor
return if (fromCallSite.defaultType.isSubtypeOf(fromDeclarationSite.defaultType))
fromCallSite
else
fromDeclarationSite
}
override fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) {
@@ -0,0 +1,11 @@
package test
import android.app.Activity
import android.os.Bundle
import java.io.File
import kotlinx.android.synthetic.main.layout.*
fun test(obj: Any?) {
obj as Activity
obj.login
}
@@ -0,0 +1,17 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ItemDetailActivity"
tools:ignore="MergeRootFrame" >
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sign in" />
</FrameLayout>