diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/folding/ResourceFoldingBuilder.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/folding/ResourceFoldingBuilder.kt index 09d2fef85c2..8d4992a0c04 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/folding/ResourceFoldingBuilder.kt +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/folding/ResourceFoldingBuilder.kt @@ -100,23 +100,27 @@ class ResourceFoldingBuilder : FoldingBuilderEx() { FoldingDescriptor(psi.node, psi.textRange, null, dependencies) } - val element = getOutermostQualified() ?: this - - (element.uastParent as? UCallExpression)?.run { - if (isFoldableGetResourceValueCall()) { - return getOutermostQualified()?.createFoldingDescriptor() ?: createFoldingDescriptor() + val element = uastParent as? UQualifiedReferenceExpression ?: this + val getResourceValueCall = (element.uastParent as? UCallExpression)?.takeIf { it.isFoldableGetResourceValueCall() } + if (getResourceValueCall != null) { + val qualifiedCall = getResourceValueCall.uastParent as? UQualifiedReferenceExpression + if (qualifiedCall?.selector == getResourceValueCall) { + return qualifiedCall.createFoldingDescriptor() } + + return getResourceValueCall.createFoldingDescriptor() } return element.createFoldingDescriptor() } - private fun UCallExpression.isFoldableGetResourceValueCall() = - methodName == "getString" || - methodName == "getText" || - methodName == "getInteger" || - methodName?.startsWith("getDimension") ?: false || - methodName?.startsWith("getQuantityString") ?: false + private fun UCallExpression.isFoldableGetResourceValueCall(): Boolean { + return methodName == "getString" || + methodName == "getText" || + methodName == "getInteger" || + methodName?.startsWith("getDimension") ?: false || + methodName?.startsWith("getQuantityString") ?: false + } private fun PsiElement.getAndroidResourceType(): ResourceType? { val elementType = parent as? PsiClass ?: return null @@ -132,17 +136,11 @@ class ResourceFoldingBuilder : FoldingBuilderEx() { private fun UReferenceExpression.getAndroidResourceValue(resources: LocalResourceRepository, call: UCallExpression? = null): String? { val resourceType = resolve()?.getAndroidResourceType() ?: return null val referenceConfig = FolderConfiguration().apply { localeQualifier = LocaleQualifier("xx") } - val key = resolvedName - val resourceValue = resources.getConfiguredValue(resourceType, key, referenceConfig)?.value ?: return null + val key = resolvedName ?: return null + val resourceValue = resources.getResourceValue(resourceType, key, referenceConfig) ?: return null val text = if (call != null) formatArguments(call, resourceValue) else resourceValue - if (resourceType == ResourceType.PLURALS && text.startsWith(STRING_PREFIX)) { - resources.getConfiguredValue(ResourceType.STRING, text.substring(STRING_PREFIX.length), referenceConfig)?.value?.let { - return '"' + StringUtil.shortenTextWithEllipsis(it, FOLD_MAX_LENGTH - 2, 0) + '"' - } - } - - if (resourceType == ResourceType.STRING) { + if (resourceType == ResourceType.STRING || resourceType == ResourceType.PLURALS) { return '"' + StringUtil.shortenTextWithEllipsis(text, FOLD_MAX_LENGTH - 2, 0) + '"' } else if (text.length <= 1) { @@ -155,6 +153,20 @@ class ResourceFoldingBuilder : FoldingBuilderEx() { return StringUtil.shortenTextWithEllipsis(text, FOLD_MAX_LENGTH, 0) } + private tailrec fun LocalResourceRepository.getResourceValue( + type: ResourceType, + name: String, + referenceConfig: FolderConfiguration): String? { + val value = getConfiguredValue(type, name, referenceConfig)?.value ?: return null + if (!value.startsWith('@')) { + return value + } + + val (referencedTypeName, referencedName) = value.substring(1).split('/').takeIf { it.size == 2 } ?: return value + val referencedType = ResourceType.getEnum(referencedTypeName) ?: return value + return getResourceValue(referencedType, referencedName, referenceConfig) + } + // Converted from com.android.tools.idea.folding.InlinedResource#insertArguments private fun formatArguments(callExpression: UCallExpression, formatString: String): String { if (!formatString.contains('%')) { diff --git a/idea/testData/android/folding/R.java b/idea/testData/android/folding/R.java index 63c3d41c701..cb6cc8ac197 100644 --- a/idea/testData/android/folding/R.java +++ b/idea/testData/android/folding/R.java @@ -30,5 +30,7 @@ public final class R { public static final int mydimen1=0x7f07005b; public static final int mydimen2=0x7f07005c; public static final int mydimen3=0x7f07005d; + public static final int dimenRef=0x7f07005e; + public static final int dimenAndroidRef=0x7f07005f; } } \ No newline at end of file diff --git a/idea/testData/android/folding/dimensions.kt b/idea/testData/android/folding/dimensions.kt index 5c8a3956137..2cd0ce91913 100644 --- a/idea/testData/android/folding/dimensions.kt +++ b/idea/testData/android/folding/dimensions.kt @@ -15,5 +15,10 @@ class MyActivity : Activity() { val strings = intArrayOf(R.string.string1, R.string.string2, R.string.string3) val dimensions = intArrayOf(R.dimen.mydimen1, R.dimen.mydimen2) val maxButtons = resources.getInteger(R.integer.max_action_buttons) + val dimensionWithReference = resources.getDimension(R.dimen.dimenRef) + val dimensionWithAndroidReference = resources.getDimension(R.dimen.dimenAndroidRef) + with(resources) { + val dimension = resources.getDimension(R.dimen.action_bar_default_height).toInt() + } } } diff --git a/idea/testData/android/folding/plurals.kt b/idea/testData/android/folding/plurals.kt index 3f18d84d847..7b5c1e7c295 100644 --- a/idea/testData/android/folding/plurals.kt +++ b/idea/testData/android/folding/plurals.kt @@ -4,6 +4,6 @@ import android.content.Context fun Context.testPlurals(quantity: Int) { val plural1 = resources.getQuantityString(R.plurals.first, quantity) - val plural2 = this.getResources().getQuantityString(R.plurals.second, quantity) + val plural2 = this.getResources().getQuantityString(R.plurals.second, quantity) } diff --git a/idea/testData/android/folding/values.xml b/idea/testData/android/folding/values.xml index bcd5571bb3e..ab360a2f5e2 100644 --- a/idea/testData/android/folding/values.xml +++ b/idea/testData/android/folding/values.xml @@ -36,4 +36,6 @@ 3dip 1dip 2dip + @dimen/mydimen1 + @android:dimen/app_icon_size \ No newline at end of file