Call findViewById if invoked on anything but our Activity class
This commit is contained in:
@@ -403,7 +403,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
genClosureFields(context.closure, v, typeMapper);
|
genClosureFields(context.closure, v, typeMapper);
|
||||||
|
|
||||||
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Default.getInstances(state.getProject())) {
|
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Default.getInstances(state.getProject())) {
|
||||||
extension.generateClassSyntheticParts(v, myClass, descriptor);
|
extension.generateClassSyntheticParts(v, bindingContext, myClass, descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -23,7 +23,8 @@ import org.jetbrains.kotlin.codegen.StackValue
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||||
import org.jetbrains.kotlin.psi.JetClassOrObject
|
import org.jetbrains.kotlin.psi.JetClassOrObject
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.resolve.*
|
||||||
|
|
||||||
public trait ExpressionCodegenExtension {
|
public trait ExpressionCodegenExtension {
|
||||||
class object : ProjectExtensionDescriptor<ExpressionCodegenExtension>("org.jetbrains.kotlin.expressionCodegenExtension", javaClass<ExpressionCodegenExtension>())
|
class object : ProjectExtensionDescriptor<ExpressionCodegenExtension>("org.jetbrains.kotlin.expressionCodegenExtension", javaClass<ExpressionCodegenExtension>())
|
||||||
@@ -36,7 +37,10 @@ public trait ExpressionCodegenExtension {
|
|||||||
// return null if not applicable
|
// return null if not applicable
|
||||||
public fun apply(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue?
|
public fun apply(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue?
|
||||||
|
|
||||||
public fun generateClassSyntheticParts(codegen: ClassBuilder, clazz: JetClassOrObject, descriptor: DeclarationDescriptor) {
|
public fun generateClassSyntheticParts(
|
||||||
|
classBuilder: ClassBuilder,
|
||||||
}
|
bindingContext: BindingContext,
|
||||||
|
classOrObject: JetClassOrObject,
|
||||||
|
descriptor: ClassDescriptor
|
||||||
|
) {}
|
||||||
}
|
}
|
||||||
@@ -31,26 +31,27 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
|||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.psi.JetFile
|
import org.jetbrains.kotlin.psi.JetFile
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
|
||||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor
|
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
|
||||||
import org.jetbrains.kotlin.psi.JetClassOrObject
|
import org.jetbrains.kotlin.psi.JetClassOrObject
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.psi.JetClass
|
import org.jetbrains.kotlin.psi.JetClass
|
||||||
import org.jetbrains.kotlin.psi.JetClassBody
|
import org.jetbrains.kotlin.psi.JetClassBody
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.codegen.FunctionCodegen
|
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||||
import org.jetbrains.kotlin.lang.resolve.android.AndroidConst
|
import org.jetbrains.kotlin.lang.resolve.android.AndroidConst
|
||||||
import org.jetbrains.kotlin.lang.resolve.android.AndroidUIXmlProcessor
|
import org.jetbrains.kotlin.lang.resolve.android.AndroidUIXmlProcessor
|
||||||
import org.jetbrains.kotlin.lang.resolve.android.CliAndroidUIXmlProcessor
|
import org.jetbrains.kotlin.lang.resolve.android.CliAndroidUIXmlProcessor
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
|
import org.jetbrains.kotlin.psi.JetThisExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.codegen.state.*
|
||||||
|
import org.jetbrains.kotlin.codegen.*
|
||||||
|
import org.jetbrains.kotlin.resolve.*
|
||||||
|
|
||||||
public object AndroidConfigurationKeys {
|
public object AndroidConfigurationKeys {
|
||||||
|
|
||||||
@@ -88,8 +89,10 @@ public class CliAndroidDeclarationsProvider(private val project: Project) : Exte
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class AndroidExpressionCodegen : ExpressionCodegenExtension {
|
public class AndroidExpressionCodegen : ExpressionCodegenExtension {
|
||||||
val propertyName = "_\$_findViewByIdCache"
|
class object {
|
||||||
val methodName = "_\$_findCachedViewById"
|
private val PROPERTY_NAME = "_\$_findViewCache"
|
||||||
|
private val METHOD_NAME = "_\$_findCachedViewById"
|
||||||
|
}
|
||||||
|
|
||||||
override fun apply(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: ExpressionCodegenExtension.Context): StackValue? {
|
override fun apply(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: ExpressionCodegenExtension.Context): StackValue? {
|
||||||
if (resolvedCall.getResultingDescriptor() !is PropertyDescriptor) return null
|
if (resolvedCall.getResultingDescriptor() !is PropertyDescriptor) return null
|
||||||
@@ -102,16 +105,33 @@ public class AndroidExpressionCodegen : ExpressionCodegenExtension {
|
|||||||
val androidPackage = file.getUserData<String>(AndroidConst.ANDROID_USER_PACKAGE)
|
val androidPackage = file.getUserData<String>(AndroidConst.ANDROID_USER_PACKAGE)
|
||||||
if (androidPackage == null) return null
|
if (androidPackage == null) return null
|
||||||
|
|
||||||
val className = DescriptorUtils.getFqName(
|
|
||||||
resolvedCall.getExtensionReceiver().getType().getConstructor().getDeclarationDescriptor()).toString()
|
|
||||||
val bytecodeClassName = className.replace('.', '/')
|
|
||||||
|
|
||||||
val retType = c.typeMapper.mapType(propertyDescriptor.getReturnType()!!)
|
val retType = c.typeMapper.mapType(propertyDescriptor.getReturnType()!!)
|
||||||
receiver.put(Type.getType("L$bytecodeClassName;"), c.v)
|
|
||||||
c.v.getstatic(androidPackage.replace(".", "/") + "/R\$id", propertyDescriptor.getName().asString(), "I")
|
|
||||||
c.v.invokevirtual(bytecodeClassName, methodName, "(I)Landroid/view/View;", false)
|
|
||||||
c.v.checkcast(retType)
|
|
||||||
|
|
||||||
|
val extensionReceiver = resolvedCall.getExtensionReceiver()
|
||||||
|
val declarationDescriptor = extensionReceiver.getType().getConstructor().getDeclarationDescriptor()
|
||||||
|
|
||||||
|
val supportsCache = when {
|
||||||
|
extensionReceiver is ClassReceiver && declarationDescriptor != null -> true
|
||||||
|
else -> {
|
||||||
|
val source = declarationDescriptor?.getSource()
|
||||||
|
if (source is KotlinSourceElement) true else false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportsCache) {
|
||||||
|
val className = DescriptorUtils.getFqName(declarationDescriptor!!).toString()
|
||||||
|
val bytecodeClassName = className.replace('.', '/')
|
||||||
|
|
||||||
|
receiver.put(Type.getType("L$bytecodeClassName;"), c.v)
|
||||||
|
c.v.getstatic(androidPackage.replace(".", "/") + "/R\$id", propertyDescriptor.getName().asString(), "I")
|
||||||
|
c.v.invokevirtual(bytecodeClassName, METHOD_NAME, "(I)Landroid/view/View;", false)
|
||||||
|
} else {
|
||||||
|
receiver.put(Type.getType("Landroid/app/Activity;"), c.v)
|
||||||
|
c.v.getstatic(androidPackage.replace(".", "/") + "/R\$id", propertyDescriptor.getName().asString(), "I")
|
||||||
|
c.v.invokevirtual("android/app/Activity", "findViewById", "(I)" + "Landroid/view/View;", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.v.checkcast(retType)
|
||||||
return StackValue.onStack(retType)
|
return StackValue.onStack(retType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,76 +150,76 @@ public class AndroidExpressionCodegen : ExpressionCodegenExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return descriptor.getTypeConstructor().getSupertypes().any {
|
return descriptor.getTypeConstructor().getSupertypes().any {
|
||||||
isClassSupported(it.getConstructor().getDeclarationDescriptor())
|
val declarationDescriptor = it.getConstructor().getDeclarationDescriptor()
|
||||||
|
declarationDescriptor != null && isClassSupported(declarationDescriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun generateClassSyntheticParts(codegen: ClassBuilder, clazz: JetClassOrObject, descriptor: DeclarationDescriptor) {
|
override fun generateClassSyntheticParts(
|
||||||
if (clazz !is JetClass || (clazz.getParent() is JetClassBody) || descriptor !is LazyClassDescriptor) return
|
classBuilder: ClassBuilder,
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
classOrObject: JetClassOrObject,
|
||||||
|
descriptor: ClassDescriptor
|
||||||
|
) {
|
||||||
|
if (descriptor.getKind() != ClassKind.CLASS || descriptor.isInner() || DescriptorUtils.isLocal(descriptor)) return
|
||||||
|
|
||||||
// Do not generate anything if class is not supported
|
// Do not generate anything if class is not supported
|
||||||
if (clazz.isEnum() || clazz.isTrait() || clazz.isAnnotation() || clazz.isInner() || !isClassSupported(descriptor))
|
if (!isClassSupported(descriptor)) return
|
||||||
return
|
|
||||||
|
|
||||||
val className = clazz.getFqName().toString().replace('.', '/')
|
val classType = JetTypeMapper(bindingContext, ClassBuilderMode.FULL).mapClass(descriptor)
|
||||||
|
val className = classType.getInternalName()
|
||||||
|
|
||||||
val classType = Type.getType(className)
|
val viewType = Type.getObjectType("android/view/View")
|
||||||
val viewType = Type.getType("Landroid/view/View;")
|
|
||||||
|
|
||||||
codegen.newField(JvmDeclarationOrigin.NO_ORIGIN, ACC_PRIVATE, propertyName, "Ljava/util/HashMap;", null, null)
|
classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, ACC_PRIVATE, PROPERTY_NAME, "Ljava/util/HashMap;", null, null)
|
||||||
|
|
||||||
val methodVisitor = codegen.newMethod(
|
val methodVisitor = classBuilder.newMethod(
|
||||||
JvmDeclarationOrigin.NO_ORIGIN, ACC_PUBLIC, methodName, "(I)Landroid/view/View;", null, null)
|
JvmDeclarationOrigin.NO_ORIGIN, ACC_PUBLIC, METHOD_NAME, "(I)Landroid/view/View;", null, null)
|
||||||
methodVisitor.visitCode()
|
methodVisitor.visitCode()
|
||||||
val iv = InstructionAdapter(methodVisitor)
|
val iv = InstructionAdapter(methodVisitor)
|
||||||
|
|
||||||
fun getCache() {
|
fun loadCache() {
|
||||||
iv.load(0, classType)
|
iv.load(0, classType)
|
||||||
iv.getfield(className, propertyName, "Ljava/util/HashMap;")
|
iv.getfield(className, PROPERTY_NAME, "Ljava/util/HashMap;")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getId() = iv.load(1, Type.INT_TYPE)
|
fun loadId() = iv.load(1, Type.INT_TYPE)
|
||||||
|
|
||||||
// Get cache property
|
// Get cache property
|
||||||
iv.visitLabel(Label())
|
loadCache()
|
||||||
getCache()
|
|
||||||
|
|
||||||
val lCacheIsNull = Label()
|
|
||||||
val lCacheNonNull = Label()
|
val lCacheNonNull = Label()
|
||||||
iv.ifnonnull(lCacheNonNull)
|
iv.ifnonnull(lCacheNonNull)
|
||||||
|
|
||||||
// Init cache if null
|
// Init cache if null
|
||||||
iv.visitLabel(lCacheIsNull)
|
|
||||||
iv.load(0, classType)
|
iv.load(0, classType)
|
||||||
iv.anew(Type.getType("Ljava/util/HashMap;"))
|
iv.anew(Type.getType("Ljava/util/HashMap;"))
|
||||||
iv.dup()
|
iv.dup()
|
||||||
iv.invokespecial("java/util/HashMap", "<init>", "()V", false)
|
iv.invokespecial("java/util/HashMap", "<init>", "()V", false)
|
||||||
iv.putfield(className, propertyName, "Ljava/util/HashMap;")
|
iv.putfield(className, PROPERTY_NAME, "Ljava/util/HashMap;")
|
||||||
|
|
||||||
// Get View from cache
|
// Get View from cache
|
||||||
iv.visitLabel(lCacheNonNull)
|
iv.visitLabel(lCacheNonNull)
|
||||||
getCache()
|
loadCache()
|
||||||
getId()
|
loadId()
|
||||||
iv.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false)
|
iv.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false)
|
||||||
iv.invokevirtual("java/util/HashMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", false)
|
iv.invokevirtual("java/util/HashMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", false)
|
||||||
iv.checkcast(viewType)
|
iv.checkcast(viewType)
|
||||||
iv.store(2, viewType)
|
iv.store(2, viewType)
|
||||||
|
|
||||||
val lViewIsNull = Label()
|
|
||||||
val lViewNonNull = Label()
|
val lViewNonNull = Label()
|
||||||
iv.load(2, viewType)
|
iv.load(2, viewType)
|
||||||
iv.ifnonnull(lViewNonNull)
|
iv.ifnonnull(lViewNonNull)
|
||||||
|
|
||||||
// Resolve View via findViewById if not in cache
|
// Resolve View via findViewById if not in cache
|
||||||
iv.visitLabel(lViewIsNull)
|
|
||||||
iv.load(0, classType)
|
iv.load(0, classType)
|
||||||
getId()
|
loadId()
|
||||||
iv.invokevirtual(className, "findViewById", "(I)Landroid/view/View;", false)
|
iv.invokevirtual(className, "findViewById", "(I)Landroid/view/View;", false)
|
||||||
iv.store(2, viewType)
|
iv.store(2, viewType)
|
||||||
|
|
||||||
// Store resolved View in cache
|
// Store resolved View in cache
|
||||||
getCache()
|
loadCache()
|
||||||
getId()
|
loadId()
|
||||||
iv.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false)
|
iv.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false)
|
||||||
iv.load(2, viewType)
|
iv.load(2, viewType)
|
||||||
iv.invokevirtual("java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", false)
|
iv.invokevirtual("java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", false)
|
||||||
@@ -209,7 +229,7 @@ public class AndroidExpressionCodegen : ExpressionCodegenExtension {
|
|||||||
iv.load(2, viewType)
|
iv.load(2, viewType)
|
||||||
iv.areturn(viewType)
|
iv.areturn(viewType)
|
||||||
|
|
||||||
FunctionCodegen.endVisit(methodVisitor, methodName, clazz)
|
FunctionCodegen.endVisit(methodVisitor, METHOD_NAME, classOrObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.myapp
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import kotlinx.android.synthetic.layout.*
|
||||||
|
|
||||||
|
fun Activity.a() {
|
||||||
|
val x = login
|
||||||
|
val y = this.login
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 GETSTATIC
|
||||||
|
// 2 INVOKEVIRTUAL
|
||||||
|
// 2 CHECKCAST
|
||||||
|
// 0 _\$_findCachedViewById
|
||||||
|
// 2 findViewById
|
||||||
+17
@@ -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>
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package com.myapp
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Bundle
|
||||||
|
import java.io.File
|
||||||
|
import kotlinx.android.synthetic.layout.*
|
||||||
|
|
||||||
|
public class MyActivity : Activity() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MyActivity.b() {
|
||||||
|
val x = login
|
||||||
|
val y = this.login
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 GETSTATIC
|
||||||
|
// 5 INVOKEVIRTUAL
|
||||||
|
// 3 CHECKCAST
|
||||||
|
// 3 _\$_findCachedViewById
|
||||||
|
// 1 findViewById
|
||||||
+17
@@ -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>
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package com.myapp
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Bundle
|
||||||
|
import java.io.File
|
||||||
|
import kotlinx.android.synthetic.layout.*
|
||||||
|
|
||||||
|
public class MyActivity : Activity() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Activity.b() {
|
||||||
|
val x = login
|
||||||
|
val y = this.login
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 GETSTATIC
|
||||||
|
// 5 INVOKEVIRTUAL
|
||||||
|
// 3 CHECKCAST
|
||||||
|
// 1 _\$_findCachedViewById
|
||||||
|
// 3 findViewById
|
||||||
+17
@@ -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>
|
||||||
+6
-3
@@ -5,8 +5,11 @@ import kotlinx.android.synthetic.layout.*
|
|||||||
|
|
||||||
class MyActivity: Activity() {
|
class MyActivity: Activity() {
|
||||||
val button = this.MyButton
|
val button = this.MyButton
|
||||||
|
val button2 = MyButton
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 GETSTATIC
|
// 2 GETSTATIC
|
||||||
// 4 INVOKEVIRTUAL
|
// 5 INVOKEVIRTUAL
|
||||||
// 2 CHECKCAST
|
// 3 CHECKCAST
|
||||||
|
// 3 _\$_findCachedViewById
|
||||||
|
// 1 findViewById
|
||||||
+6
-3
@@ -5,8 +5,11 @@ import kotlinx.android.synthetic.layout.*
|
|||||||
|
|
||||||
class MyActivity: Activity() {
|
class MyActivity: Activity() {
|
||||||
val button = this.MyButton
|
val button = this.MyButton
|
||||||
|
val button2 = MyButton
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 GETSTATIC
|
// 2 GETSTATIC
|
||||||
// 4 INVOKEVIRTUAL
|
// 5 INVOKEVIRTUAL
|
||||||
// 2 CHECKCAST
|
// 3 CHECKCAST
|
||||||
|
// 3 _\$_findCachedViewById
|
||||||
|
// 1 findViewById
|
||||||
@@ -12,3 +12,5 @@ class MyActivity: Activity() {
|
|||||||
// 2 GETSTATIC
|
// 2 GETSTATIC
|
||||||
// 5 INVOKEVIRTUAL
|
// 5 INVOKEVIRTUAL
|
||||||
// 3 CHECKCAST
|
// 3 CHECKCAST
|
||||||
|
// 3 _\$_findCachedViewById
|
||||||
|
// 1 findViewById
|
||||||
@@ -12,3 +12,5 @@ public class MyActivity : Activity() {
|
|||||||
// 1 GETSTATIC
|
// 1 GETSTATIC
|
||||||
// 4 INVOKEVIRTUAL
|
// 4 INVOKEVIRTUAL
|
||||||
// 2 CHECKCAST
|
// 2 CHECKCAST
|
||||||
|
// 2 _\$_findCachedViewById
|
||||||
|
// 1 findViewById
|
||||||
+12
@@ -36,6 +36,18 @@ public class AndroidBytecodeShapeTestGenerated extends AbstractAndroidBytecodeSh
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/android-compiler-plugin/testData/codegen/bytecodeShape"), Pattern.compile("^([^\\.]+)$"), false);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/android-compiler-plugin/testData/codegen/bytecodeShape"), Pattern.compile("^([^\\.]+)$"), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("baseClass")
|
||||||
|
public void testBaseClass() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("plugins/android-compiler-plugin/testData/codegen/bytecodeShape/baseClass/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionFunctions")
|
||||||
|
public void testExtensionFunctions() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctions/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("fqNameInAttr")
|
@TestMetadata("fqNameInAttr")
|
||||||
public void testFqNameInAttr() throws Exception {
|
public void testFqNameInAttr() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInAttr/");
|
String fileName = JetTestUtils.navigationMetadata("plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInAttr/");
|
||||||
|
|||||||
Reference in New Issue
Block a user