diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 90ba9dc699e..34f2ddd9114 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -1447,8 +1447,9 @@ public class ExpressionCodegen extends JetVisitor implem List superValueParameters = superConstructor.getValueParameters(); int params = superValueParameters.size(); List superMappedTypes = typeMapper.mapToCallableMethod(superConstructor).getValueParameterTypes(); - assert superMappedTypes.size() >= params : String.format("Incorrect number of mapped parameters vs arguments: %d < %d for %s", - superMappedTypes.size(), params, classDescriptor); + assert superMappedTypes.size() >= params : String + .format("Incorrect number of mapped parameters vs arguments: %d < %d for %s", + superMappedTypes.size(), params, classDescriptor); List valueArguments = new ArrayList(params); List valueParameters = new ArrayList(params); @@ -1461,7 +1462,8 @@ public class ExpressionCodegen extends JetVisitor implem mappedTypes.add(superMappedTypes.get(parameter.getIndex())); } } - ArgumentGenerator argumentGenerator = new CallBasedArgumentGenerator(ExpressionCodegen.this, defaultCallGenerator, valueParameters, mappedTypes); + ArgumentGenerator argumentGenerator = + new CallBasedArgumentGenerator(ExpressionCodegen.this, defaultCallGenerator, valueParameters, mappedTypes); argumentGenerator.generate(valueArguments); } @@ -1904,10 +1906,15 @@ public class ExpressionCodegen extends JetVisitor implem if (descriptor instanceof PropertyDescriptor) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; - for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.OBJECT$.getInstances(state.getProject())) { - StackValue result = extension.apply(receiver, resolvedCall, new ExpressionCodegenExtension.Context(typeMapper, v)); - - if (result != null) return result; + Collection codegenExtensions = ExpressionCodegenExtension.Default.getInstances(state.getProject()); + if (!codegenExtensions.isEmpty() && resolvedCall != null) { + ExpressionCodegenExtension.Context context = new ExpressionCodegenExtension.Context(typeMapper, v); + JetType returnType = propertyDescriptor.getReturnType(); + for (ExpressionCodegenExtension extension : codegenExtensions) { + if (returnType != null && extension.apply(receiver, resolvedCall, context)) { + return StackValue.onStack(typeMapper.mapType(returnType)); + } + } } boolean directToField = @@ -2338,6 +2345,15 @@ public class ExpressionCodegen extends JetVisitor implem ) { if (!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod); + + Collection codegenExtensions = ExpressionCodegenExtension.Default.getInstances(state.getProject()); + if (!codegenExtensions.isEmpty()) { + ExpressionCodegenExtension.Context context = new ExpressionCodegenExtension.Context(typeMapper, v); + for (ExpressionCodegenExtension extension : codegenExtensions) { + if (extension.apply(receiver, resolvedCall, context)) return; + } + } + receiver.put(receiver.type, v); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/extensions/ExpressionCodegenExtension.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/extensions/ExpressionCodegenExtension.kt index 4e031c4d2d0..845b8655a00 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/extensions/ExpressionCodegenExtension.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/extensions/ExpressionCodegenExtension.kt @@ -35,8 +35,9 @@ public trait ExpressionCodegenExtension { public val v: InstructionAdapter ) - // return null if not applicable - public fun apply(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? + // Function is responsible to put the value on stack by itself. + // Returns false if not applicable, and if stack was not modified. + public fun apply(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): Boolean public fun generateClassSyntheticParts( classBuilder: ClassBuilder, diff --git a/plugins/android-compiler-plugin/src/AndroidExpressionCodegenExtension.kt b/plugins/android-compiler-plugin/src/AndroidExpressionCodegenExtension.kt index b7bceb3cb96..df4f1a80e3b 100644 --- a/plugins/android-compiler-plugin/src/AndroidExpressionCodegenExtension.kt +++ b/plugins/android-compiler-plugin/src/AndroidExpressionCodegenExtension.kt @@ -23,20 +23,20 @@ import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.JetTypeMapper -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.ClassifierDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.lang.resolve.android.AndroidConst import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor import org.jetbrains.kotlin.psi.JetClassOrObject +import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor import org.jetbrains.kotlin.resolve.scopes.receivers.ClassReceiver import org.jetbrains.kotlin.resolve.source.KotlinSourceElement +import org.jetbrains.kotlin.types.Flexibility 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 @@ -53,60 +53,103 @@ private enum class AndroidClassType(val internalClassName: String, val supportsC public class AndroidExpressionCodegenExtension : ExpressionCodegenExtension { default object { private val PROPERTY_NAME = "_\$_findViewCache" - private val METHOD_NAME = "_\$_findCachedViewById" + private val CACHED_FIND_VIEW_BY_ID_METHOD_NAME = "_\$_findCachedViewById" + private val CLEAR_CACHE_METHOD_NAME = "_\$_clearFindViewByIdCache" } - override fun apply(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: ExpressionCodegenExtension.Context): StackValue? { - if (resolvedCall.getResultingDescriptor() !is PropertyDescriptor) return null + private class SyntheticPartsGenerateContext( + val classBuilder: ClassBuilder, + val state: GenerationState, + val descriptor: ClassDescriptor, + val classOrObject: JetClassOrObject, + val androidClassType: AndroidClassType) { - val propertyDescriptor = resolvedCall.getResultingDescriptor() as PropertyDescriptor + } - val file = DescriptorToSourceUtils.getContainingFile(propertyDescriptor) - if (file == null) return null + override fun apply(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: ExpressionCodegenExtension.Context): Boolean { + val resultingDescriptor = resolvedCall.getResultingDescriptor() + return when (resultingDescriptor) { + is PropertyDescriptor -> generateSyntheticPropertyCall(receiver, resolvedCall, c, resultingDescriptor) + is FunctionDescriptor -> generateSyntheticFunctionCall(receiver, resolvedCall, c, resultingDescriptor) + else -> false + } + } - val androidPackage = file.getUserData(AndroidConst.ANDROID_USER_PACKAGE) - if (androidPackage == null) return null + private fun generateSyntheticFunctionCall( + receiver: StackValue, + resolvedCall: ResolvedCall<*>, + c: ExpressionCodegenExtension.Context, + descriptor: FunctionDescriptor + ): Boolean { + if (descriptor.getAndroidPackage() == null) return false + if (descriptor.getName().asString() != AndroidConst.CLEAR_FUNCTION_NAME) return false - val retType = c.typeMapper.mapType(propertyDescriptor.getReturnType()!!) - - val extensionReceiver = resolvedCall.getExtensionReceiver() - val declarationDescriptor = extensionReceiver.getType().getConstructor().getDeclarationDescriptor() - - if (declarationDescriptor == null) return null - - val supportsCache = declarationDescriptor.getSource() is KotlinSourceElement + val declarationDescriptor = resolvedCall.getReceiverDeclarationDescriptor() ?: return false + if (!isCacheSupported(declarationDescriptor)) return true val androidClassType = getClassType(declarationDescriptor) - if (supportsCache && androidClassType.supportsCache) { + if (androidClassType == AndroidClassType.UNKNOWN) return false + + val bytecodeClassName = DescriptorUtils.getFqName(declarationDescriptor).asString().replace('.', '/') + + receiver.put(c.typeMapper.mapType(declarationDescriptor), c.v) + c.v.invokevirtual(bytecodeClassName, CLEAR_CACHE_METHOD_NAME, "()V", false) + + return true + } + + private fun generateSyntheticPropertyCall( + receiver: StackValue, + resolvedCall: ResolvedCall<*>, + c: ExpressionCodegenExtension.Context, + descriptor: PropertyDescriptor + ): Boolean { + val androidPackage = descriptor.getAndroidPackage() ?: return false + val declarationDescriptor = resolvedCall.getReceiverDeclarationDescriptor() ?: return false + + val androidClassType = getClassType(declarationDescriptor) + if (androidClassType.supportsCache && isCacheSupported(declarationDescriptor)) { 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(c.typeMapper.mapType(declarationDescriptor), c.v) + c.v.getstatic(androidPackage.replace(".", "/") + "/R\$id", descriptor.getName().asString(), "I") + c.v.invokevirtual(bytecodeClassName, CACHED_FIND_VIEW_BY_ID_METHOD_NAME, "(I)Landroid/view/View;", false) + } + else { when (androidClassType) { AndroidClassType.ACTIVITY, AndroidClassType.VIEW -> { receiver.put(Type.getType("L${androidClassType.internalClassName};"), c.v) - c.v.getstatic(androidPackage.replace(".", "/") + "/R\$id", propertyDescriptor.getName().asString(), "I") + c.v.getstatic(androidPackage.replace(".", "/") + "/R\$id", descriptor.getName().asString(), "I") c.v.invokevirtual(androidClassType.internalClassName, "findViewById", "(I)Landroid/view/View;", false) } AndroidClassType.FRAGMENT -> { receiver.put(Type.getType("L${androidClassType.internalClassName};"), c.v) c.v.invokevirtual(androidClassType.internalClassName, "getView", "()Landroid/view/View;", false) - c.v.getstatic(androidPackage.replace(".", "/") + "/R\$id", propertyDescriptor.getName().asString(), "I") + c.v.getstatic(androidPackage.replace(".", "/") + "/R\$id", descriptor.getName().asString(), "I") c.v.invokevirtual("android/view/View", "findViewById", "(I)Landroid/view/View;", false) } - else -> return null + else -> return false } } + val retType = c.typeMapper.mapType(descriptor.getReturnType()!!) c.v.checkcast(retType) - return StackValue.onStack(retType) + return true } + private fun CallableDescriptor.getAndroidPackage(): String? { + return DescriptorToSourceUtils.getContainingFile(this)?.getUserData(AndroidConst.ANDROID_USER_PACKAGE) + } + + private fun ResolvedCall<*>.getReceiverDeclarationDescriptor(): ClassifierDescriptor? { + return getExtensionReceiver().getType().getConstructor().getDeclarationDescriptor() + } + + private fun isCacheSupported(descriptor: ClassifierDescriptor) = descriptor.getSource() is KotlinSourceElement + private fun getClassType(descriptor: ClassifierDescriptor): AndroidClassType { fun getClassTypeInternal(name: String): AndroidClassType? = when (name) { "android.app.Activity" -> AndroidClassType.ACTIVITY @@ -118,7 +161,8 @@ public class AndroidExpressionCodegenExtension : ExpressionCodegenExtension { if (descriptor is LazyJavaClassDescriptor) { val androidClassType = getClassTypeInternal(descriptor.fqName.asString()) if (androidClassType != null) return androidClassType - } else if (descriptor is LazyClassDescriptor) { // For tests (FakeActivity) + } + else if (descriptor is LazyClassDescriptor) { // For tests (FakeActivity) val androidClassType = getClassTypeInternal(DescriptorUtils.getFqName(descriptor).toString()) if (androidClassType != null) return androidClassType } @@ -146,15 +190,47 @@ public class AndroidExpressionCodegenExtension : ExpressionCodegenExtension { val androidClassType = getClassType(descriptor) if (androidClassType == AndroidClassType.UNKNOWN) return + val context = SyntheticPartsGenerateContext(classBuilder, state, descriptor, classOrObject, androidClassType) + context.generateCachedFindViewByIdFunction() + context.generateClearCacheFunction() + + classBuilder.newField(JvmDeclarationOrigin.Default.NO_ORIGIN, ACC_PRIVATE, PROPERTY_NAME, "Ljava/util/HashMap;", null, null) + } + + private fun SyntheticPartsGenerateContext.generateClearCacheFunction() { + val methodVisitor = classBuilder.newMethod( + JvmDeclarationOrigin.Default.NO_ORIGIN, ACC_PUBLIC, CLEAR_CACHE_METHOD_NAME, "()V", null, null) + methodVisitor.visitCode() + val iv = InstructionAdapter(methodVisitor) + + val classType = state.getTypeMapper().mapClass(descriptor) + val className = classType.getInternalName() + + fun loadCache() { + iv.load(0, classType) + iv.getfield(className, PROPERTY_NAME, "Ljava/util/HashMap;") + } + + loadCache() + val lCacheIsNull = Label() + iv.ifnull(lCacheIsNull) + + loadCache() + iv.invokevirtual("java/util/HashMap", "clear", "()V", false) + + iv.visitLabel(lCacheIsNull) + iv.areturn(Type.VOID_TYPE) + FunctionCodegen.endVisit(methodVisitor, CLEAR_CACHE_METHOD_NAME, classOrObject) + } + + private fun SyntheticPartsGenerateContext.generateCachedFindViewByIdFunction() { val classType = state.getTypeMapper().mapClass(descriptor) val className = classType.getInternalName() val viewType = Type.getObjectType("android/view/View") - classBuilder.newField(org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Default.NO_ORIGIN, ACC_PRIVATE, PROPERTY_NAME, "Ljava/util/HashMap;", null, null) - val methodVisitor = classBuilder.newMethod( - org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Default.NO_ORIGIN, ACC_PUBLIC, METHOD_NAME, "(I)Landroid/view/View;", null, null) + JvmDeclarationOrigin.Default.NO_ORIGIN, ACC_PUBLIC, CACHED_FIND_VIEW_BY_ID_METHOD_NAME, "(I)Landroid/view/View;", null, null) methodVisitor.visitCode() val iv = InstructionAdapter(methodVisitor) @@ -218,6 +294,6 @@ public class AndroidExpressionCodegenExtension : ExpressionCodegenExtension { iv.load(2, viewType) iv.areturn(viewType) - FunctionCodegen.endVisit(methodVisitor, METHOD_NAME, classOrObject) + FunctionCodegen.endVisit(methodVisitor, CACHED_FIND_VIEW_BY_ID_METHOD_NAME, classOrObject) } } \ No newline at end of file diff --git a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidConst.kt b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidConst.kt index 7645c6a2b9b..01d38440e40 100644 --- a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidConst.kt +++ b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidConst.kt @@ -30,6 +30,8 @@ public object AndroidConst { val ID_DECLARATION_PREFIX = "@+id/" val ID_USAGE_PREFIX = "@id/" + + val CLEAR_FUNCTION_NAME = "clearFindViewByIdCache" } public fun nameToIdDeclaration(name: String): String = AndroidConst.ID_DECLARATION_PREFIX + name diff --git a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidUIXmlProcessor.kt b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidUIXmlProcessor.kt index e23dccf5eee..3d379fcf604 100644 --- a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidUIXmlProcessor.kt +++ b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidUIXmlProcessor.kt @@ -87,7 +87,13 @@ public abstract class AndroidUIXmlProcessor(protected val project: Project) { } } - public fun parse(): List { + public fun parse(generateCommonFiles: Boolean = true): List { + val commonFiles = if (generateCommonFiles) { + val clearCacheFile = renderLayoutFile("kotlinx.android.synthetic") {} + + renderClearCacheFunction("Activity") + renderClearCacheFunction("Fragment") + listOf(clearCacheFile) + } else listOf() + return resourceManager.getLayoutXmlFiles().flatMap { file -> val widgets = parseSingleFile(file) if (widgets.isNotEmpty()) { @@ -104,7 +110,7 @@ public abstract class AndroidUIXmlProcessor(protected val project: Project) { listOf(mainLayoutFile, viewLayoutFile) } else listOf() - }.filterNotNull() + }.filterNotNull() + commonFiles } public fun parseToPsi(): List? = cachedJetFiles.getValue() @@ -113,7 +119,7 @@ public abstract class AndroidUIXmlProcessor(protected val project: Project) { private fun renderLayoutFile( packageName: String, - widgets: List, + widgets: List = listOf(), widgetWriter: KotlinStringWriter.(AndroidWidget) -> Unit ): String { val stringWriter = KotlinStringWriter() @@ -141,6 +147,8 @@ public abstract class AndroidUIXmlProcessor(protected val project: Project) { getterBody = body) } + private fun renderClearCacheFunction(receiver: String) = "public fun $receiver.${AndroidConst.CLEAR_FUNCTION_NAME}() {}\n" + private fun cachedValue(result: () -> CachedValueProvider.Result): CachedValue { return CachedValuesManager.getManager(project).createCachedValue(result, false) } diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCache/clearCache.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCache/clearCache.kt new file mode 100644 index 00000000000..5ea50a48ee6 --- /dev/null +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCache/clearCache.kt @@ -0,0 +1,14 @@ +package com.myapp + +import android.app.Activity +import android.os.Bundle +import java.io.File +import kotlinx.android.synthetic.* + +public class MyActivity : Activity() { + {clearFindViewByIdCache()} +} + +// 5 INVOKEVIRTUAL +// 1 CHECKCAST +// 2 _\$_clearFindViewByIdCache \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCache/res/layout/layout.xml b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCache/res/layout/layout.xml new file mode 100644 index 00000000000..9674eb7c5ef --- /dev/null +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCache/res/layout/layout.xml @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCacheBaseClass/clearCacheBaseClass.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCacheBaseClass/clearCacheBaseClass.kt new file mode 100644 index 00000000000..97f1ae17cf6 --- /dev/null +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCacheBaseClass/clearCacheBaseClass.kt @@ -0,0 +1,12 @@ +package com.myapp + +import android.app.Activity +import android.os.Bundle +import java.io.File +import kotlinx.android.synthetic.* + +public fun Activity.a() { + clearFindViewByIdCache() +} + +// 0 clearFindViewByIdCache \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCacheBaseClass/res/layout/layout.xml b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCacheBaseClass/res/layout/layout.xml new file mode 100644 index 00000000000..9674eb7c5ef --- /dev/null +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCacheBaseClass/res/layout/layout.xml @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctions/extensionFunctions.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctions/extensionFunctions.kt index d31dda81e06..fec92fcb0e0 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctions/extensionFunctions.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctions/extensionFunctions.kt @@ -15,7 +15,7 @@ fun MyActivity.b() { } // 2 GETSTATIC -// 5 INVOKEVIRTUAL +// 6 INVOKEVIRTUAL // 3 CHECKCAST // 3 _\$_findCachedViewById // 1 findViewById \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsBaseClass/extensionFunctionsBaseClass.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsBaseClass/extensionFunctionsBaseClass.kt index fd2a2afda32..8d45c659bbc 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsBaseClass/extensionFunctionsBaseClass.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsBaseClass/extensionFunctionsBaseClass.kt @@ -15,7 +15,7 @@ fun Activity.b() { } // 2 GETSTATIC -// 5 INVOKEVIRTUAL +// 6 INVOKEVIRTUAL // 3 CHECKCAST // 1 _\$_findCachedViewById // 3 findViewById \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsBaseClassFragment/extensionFunctionsBaseClassFragment.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsBaseClassFragment/extensionFunctionsBaseClassFragment.kt index 0d293339196..4245529dffe 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsBaseClassFragment/extensionFunctionsBaseClassFragment.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsBaseClassFragment/extensionFunctionsBaseClassFragment.kt @@ -15,7 +15,7 @@ fun Fragment.b() { } // 2 GETSTATIC -// 8 INVOKEVIRTUAL +// 9 INVOKEVIRTUAL // 3 CHECKCAST // 1 _\$_findCachedViewById // 3 findViewById diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsFragment/extensionFunctionsFragment.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsFragment/extensionFunctionsFragment.kt index d31dda81e06..fec92fcb0e0 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsFragment/extensionFunctionsFragment.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctionsFragment/extensionFunctionsFragment.kt @@ -15,7 +15,7 @@ fun MyActivity.b() { } // 2 GETSTATIC -// 5 INVOKEVIRTUAL +// 6 INVOKEVIRTUAL // 3 CHECKCAST // 3 _\$_findCachedViewById // 1 findViewById \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInAttr/fqNameInAttr.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInAttr/fqNameInAttr.kt index a8f15880d84..16d6bbd7401 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInAttr/fqNameInAttr.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInAttr/fqNameInAttr.kt @@ -9,7 +9,7 @@ class MyActivity: Activity() { } // 2 GETSTATIC -// 5 INVOKEVIRTUAL +// 6 INVOKEVIRTUAL // 3 CHECKCAST // 3 _\$_findCachedViewById // 1 findViewById \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInAttrFragment/fqNameInAttrFragment.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInAttrFragment/fqNameInAttrFragment.kt index 934e6251a80..58f79d7a266 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInAttrFragment/fqNameInAttrFragment.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInAttrFragment/fqNameInAttrFragment.kt @@ -9,7 +9,7 @@ class MyFragment: Fragment() { } // 2 GETSTATIC -// 6 INVOKEVIRTUAL +// 7 INVOKEVIRTUAL // 3 CHECKCAST // 3 _\$_findCachedViewById // 1 findViewById diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInTag/fqNameInTag.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInTag/fqNameInTag.kt index a8f15880d84..16d6bbd7401 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInTag/fqNameInTag.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInTag/fqNameInTag.kt @@ -9,7 +9,7 @@ class MyActivity: Activity() { } // 2 GETSTATIC -// 5 INVOKEVIRTUAL +// 6 INVOKEVIRTUAL // 3 CHECKCAST // 3 _\$_findCachedViewById // 1 findViewById \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInTagFragment/fqNameInTagFragment.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInTagFragment/fqNameInTagFragment.kt index 934e6251a80..58f79d7a266 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInTagFragment/fqNameInTagFragment.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/fqNameInTagFragment/fqNameInTagFragment.kt @@ -9,7 +9,7 @@ class MyFragment: Fragment() { } // 2 GETSTATIC -// 6 INVOKEVIRTUAL +// 7 INVOKEVIRTUAL // 3 CHECKCAST // 3 _\$_findCachedViewById // 1 findViewById diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/multiFile/multiFile.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/multiFile/multiFile.kt index 31762fc38aa..7a3c286eef7 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/multiFile/multiFile.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/multiFile/multiFile.kt @@ -10,7 +10,7 @@ class MyActivity: Activity() { } // 2 GETSTATIC -// 5 INVOKEVIRTUAL +// 6 INVOKEVIRTUAL // 3 CHECKCAST // 3 _\$_findCachedViewById // 1 findViewById \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/multiFileFragment/multiFileFragment.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/multiFileFragment/multiFileFragment.kt index 8de17aaa9cb..f9310d768d9 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/multiFileFragment/multiFileFragment.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/multiFileFragment/multiFileFragment.kt @@ -14,7 +14,7 @@ class MyFragment: Fragment() { } // 2 GETSTATIC -// 9 INVOKEVIRTUAL +// 11 INVOKEVIRTUAL // 4 CHECKCAST // 4 _\$_findCachedViewById // 2 findViewById diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simple/simple.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simple/simple.kt index 5ba5523cbb7..ee901e8e592 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simple/simple.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simple/simple.kt @@ -10,7 +10,7 @@ public class MyActivity : Activity() { } // 1 GETSTATIC -// 4 INVOKEVIRTUAL +// 5 INVOKEVIRTUAL // 2 CHECKCAST // 2 _\$_findCachedViewById // 1 findViewById \ No newline at end of file diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simpleFragment/simpleFragment.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simpleFragment/simpleFragment.kt index 02a17349a3d..d4d737be36c 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simpleFragment/simpleFragment.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simpleFragment/simpleFragment.kt @@ -9,7 +9,7 @@ public class MyFragment : Fragment() { } // 1 GETSTATIC -// 5 INVOKEVIRTUAL +// 6 INVOKEVIRTUAL // 2 CHECKCAST // 2 _\$_findCachedViewById // 1 findViewById diff --git a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simpleView/simpleView.kt b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simpleView/simpleView.kt index 034e6f65718..a5ea852caf7 100644 --- a/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simpleView/simpleView.kt +++ b/plugins/android-compiler-plugin/testData/codegen/bytecodeShape/simpleView/simpleView.kt @@ -9,7 +9,7 @@ public class MyActivity : Activity() { } // 1 GETSTATIC -// 4 INVOKEVIRTUAL +// 5 INVOKEVIRTUAL // 3 CHECKCAST // 1 _\$_findCachedViewById // 2 findViewById \ No newline at end of file diff --git a/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AbstractAndroidXml2KConversionTest.kt b/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AbstractAndroidXml2KConversionTest.kt index a45a1ab44d4..15c2e0103cb 100644 --- a/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AbstractAndroidXml2KConversionTest.kt +++ b/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AbstractAndroidXml2KConversionTest.kt @@ -33,7 +33,7 @@ public abstract class AbstractAndroidXml2KConversionTest : UsefulTestCase() { val jetCoreEnvironment = getEnvironment(path) val parser = CliAndroidUIXmlProcessor(jetCoreEnvironment.getProject(), path + "AndroidManifest.xml", path + "/res") - val actual = parser.parse() + val actual = parser.parse(false) val layoutFiles = File(path).listFiles { it.isFile() && it.name.startsWith("layout") && it.name.endsWith(".kt") diff --git a/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AndroidBytecodeShapeTestGenerated.java b/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AndroidBytecodeShapeTestGenerated.java index f63a0dac5e8..01b152c1f08 100644 --- a/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AndroidBytecodeShapeTestGenerated.java +++ b/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AndroidBytecodeShapeTestGenerated.java @@ -48,6 +48,18 @@ public class AndroidBytecodeShapeTestGenerated extends AbstractAndroidBytecodeSh doTest(fileName); } + @TestMetadata("clearCache") + public void testClearCache() throws Exception { + String fileName = JetTestUtils.navigationMetadata("plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCache/"); + doTest(fileName); + } + + @TestMetadata("clearCacheBaseClass") + public void testClearCacheBaseClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("plugins/android-compiler-plugin/testData/codegen/bytecodeShape/clearCacheBaseClass/"); + doTest(fileName); + } + @TestMetadata("extensionFunctions") public void testExtensionFunctions() throws Exception { String fileName = JetTestUtils.navigationMetadata("plugins/android-compiler-plugin/testData/codegen/bytecodeShape/extensionFunctions/"); diff --git a/plugins/android-idea-plugin/tests/org/jetbrains/kotlin/android/AndroidFindUsagesTestGenerated.java b/plugins/android-idea-plugin/tests/org/jetbrains/kotlin/android/AndroidFindUsagesTestGenerated.java index 36cee42393d..eff778e09ef 100644 --- a/plugins/android-idea-plugin/tests/org/jetbrains/kotlin/android/AndroidFindUsagesTestGenerated.java +++ b/plugins/android-idea-plugin/tests/org/jetbrains/kotlin/android/AndroidFindUsagesTestGenerated.java @@ -78,12 +78,6 @@ public class AndroidFindUsagesTestGenerated extends AbstractAndroidFindUsagesTes doTest(fileName); } - @TestMetadata("wrongIdFormat") - public void testWrongIdFormat() throws Exception { - String fileName = JetTestUtils.navigationMetadata("plugins/android-idea-plugin/testData/android/findUsages/wrongIdFormat/"); - doTest(fileName); - } - @TestMetadata("simpleFragment") public void testSimpleFragment() throws Exception { String fileName = JetTestUtils.navigationMetadata("plugins/android-idea-plugin/testData/android/findUsages/simpleFragment/"); @@ -95,4 +89,10 @@ public class AndroidFindUsagesTestGenerated extends AbstractAndroidFindUsagesTes String fileName = JetTestUtils.navigationMetadata("plugins/android-idea-plugin/testData/android/findUsages/simpleView/"); doTest(fileName); } + + @TestMetadata("wrongIdFormat") + public void testWrongIdFormat() throws Exception { + String fileName = JetTestUtils.navigationMetadata("plugins/android-idea-plugin/testData/android/findUsages/wrongIdFormat/"); + doTest(fileName); + } }