Android Extensions: Generate proper receiver for clearFindViewByIdCache() call (KT-19742)

This commit is contained in:
Yan Zhulanow
2017-08-23 19:25:29 +03:00
committed by Yan Zhulanow
parent f84df6381e
commit 07be1e9d10
5 changed files with 20 additions and 9 deletions
@@ -1705,7 +1705,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject()); Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject());
if (!codegenExtensions.isEmpty() && resolvedCall != null) { if (!codegenExtensions.isEmpty() && resolvedCall != null) {
ExpressionCodegenExtension.Context context = new ExpressionCodegenExtension.Context(typeMapper, v); ExpressionCodegenExtension.Context context = new ExpressionCodegenExtension.Context(this, typeMapper, v);
KotlinType returnType = propertyDescriptor.getReturnType(); KotlinType returnType = propertyDescriptor.getReturnType();
for (ExpressionCodegenExtension extension : codegenExtensions) { for (ExpressionCodegenExtension extension : codegenExtensions) {
if (returnType != null) { if (returnType != null) {
@@ -2141,7 +2141,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject()); Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject());
if (!codegenExtensions.isEmpty()) { if (!codegenExtensions.isEmpty()) {
ExpressionCodegenExtension.Context context = new ExpressionCodegenExtension.Context(typeMapper, v); ExpressionCodegenExtension.Context context = new ExpressionCodegenExtension.Context(this, typeMapper, v);
for (ExpressionCodegenExtension extension : codegenExtensions) { for (ExpressionCodegenExtension extension : codegenExtensions) {
StackValue stackValue = extension.applyFunction(receiver, resolvedCall, context); StackValue stackValue = extension.applyFunction(receiver, resolvedCall, context);
if (stackValue != null) return stackValue; if (stackValue != null) return stackValue;
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.codegen.extensions package org.jetbrains.kotlin.codegen.extensions
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
@@ -28,6 +29,7 @@ interface ExpressionCodegenExtension {
"org.jetbrains.kotlin.expressionCodegenExtension", ExpressionCodegenExtension::class.java) "org.jetbrains.kotlin.expressionCodegenExtension", ExpressionCodegenExtension::class.java)
class Context( class Context(
val codegen: ExpressionCodegen,
val typeMapper: KotlinTypeMapper, val typeMapper: KotlinTypeMapper,
val v: InstructionAdapter val v: InstructionAdapter
) )
@@ -103,11 +103,12 @@ abstract class AbstractAndroidExtensionsExpressionCodegenExtension : ExpressionC
} }
if (containerOptions.containerType == AndroidContainerType.UNKNOWN) return null if (containerOptions.containerType == AndroidContainerType.UNKNOWN) return null
val actualReceiver = StackValue.receiver(resolvedCall, receiver, c.codegen, null)
return StackValue.functionCall(Type.VOID_TYPE) { return StackValue.functionCall(Type.VOID_TYPE) {
val bytecodeClassName = c.typeMapper.mapType(container).internalName val bytecodeClassName = c.typeMapper.mapType(container).internalName
receiver.put(c.typeMapper.mapType(container), it) actualReceiver.put(c.typeMapper.mapType(container), it)
it.invokevirtual(bytecodeClassName, CLEAR_CACHE_METHOD_NAME, "()V", false) it.invokevirtual(bytecodeClassName, CLEAR_CACHE_METHOD_NAME, "()V", false)
} }
} }
@@ -7,6 +7,7 @@ import android.view.View
import android.widget.* import android.widget.*
import org.my.cool.MyButton import org.my.cool.MyButton
import kotlinx.android.synthetic.main.layout.* import kotlinx.android.synthetic.main.layout.*
import kotlinx.android.synthetic.clearFindViewByIdCache
class R { class R {
class id { class id {
@@ -36,7 +37,9 @@ class MyFragment(): Fragment() {
override fun getView(): View = baseView override fun getView(): View = baseView
public fun box(): String { public fun box(): String {
return if (login.toString() == "MyButton") "OK" else "" val result = if (login.toString() == "MyButton") "OK" else ""
clearFindViewByIdCache()
return result
} }
} }
@@ -4,6 +4,7 @@ import android.app.Activity
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import kotlinx.android.synthetic.main.layout.* import kotlinx.android.synthetic.main.layout.*
import kotlinx.android.synthetic.clearFindViewByIdCache
class R { class R {
class id { class id {
@@ -32,11 +33,15 @@ class MyActivity(): Activity() {
} }
} }
public fun box(): String{ public fun box(): String {
return if (textView1.toString() == "TextView" && val result = when {
password.toString() == "EditText" && textView1.toString() == "TextView" && password.toString() == "EditText" && login.toString() == "Button" -> "OK"
login.toString() == "Button") else -> ""
"OK" else "" }
clearFindViewByIdCache()
return result
} }
} }