Fix Android resource reference folding
Properly fold qualified expressions and handle nested references #KT-18429 Fixed
This commit is contained in:
+32
-20
@@ -100,23 +100,27 @@ class ResourceFoldingBuilder : FoldingBuilderEx() {
|
|||||||
FoldingDescriptor(psi.node, psi.textRange, null, dependencies)
|
FoldingDescriptor(psi.node, psi.textRange, null, dependencies)
|
||||||
}
|
}
|
||||||
|
|
||||||
val element = getOutermostQualified() ?: this
|
val element = uastParent as? UQualifiedReferenceExpression ?: this
|
||||||
|
val getResourceValueCall = (element.uastParent as? UCallExpression)?.takeIf { it.isFoldableGetResourceValueCall() }
|
||||||
(element.uastParent as? UCallExpression)?.run {
|
if (getResourceValueCall != null) {
|
||||||
if (isFoldableGetResourceValueCall()) {
|
val qualifiedCall = getResourceValueCall.uastParent as? UQualifiedReferenceExpression
|
||||||
return getOutermostQualified()?.createFoldingDescriptor() ?: createFoldingDescriptor()
|
if (qualifiedCall?.selector == getResourceValueCall) {
|
||||||
|
return qualifiedCall.createFoldingDescriptor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return getResourceValueCall.createFoldingDescriptor()
|
||||||
}
|
}
|
||||||
|
|
||||||
return element.createFoldingDescriptor()
|
return element.createFoldingDescriptor()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun UCallExpression.isFoldableGetResourceValueCall() =
|
private fun UCallExpression.isFoldableGetResourceValueCall(): Boolean {
|
||||||
methodName == "getString" ||
|
return methodName == "getString" ||
|
||||||
methodName == "getText" ||
|
methodName == "getText" ||
|
||||||
methodName == "getInteger" ||
|
methodName == "getInteger" ||
|
||||||
methodName?.startsWith("getDimension") ?: false ||
|
methodName?.startsWith("getDimension") ?: false ||
|
||||||
methodName?.startsWith("getQuantityString") ?: false
|
methodName?.startsWith("getQuantityString") ?: false
|
||||||
|
}
|
||||||
|
|
||||||
private fun PsiElement.getAndroidResourceType(): ResourceType? {
|
private fun PsiElement.getAndroidResourceType(): ResourceType? {
|
||||||
val elementType = parent as? PsiClass ?: return null
|
val elementType = parent as? PsiClass ?: return null
|
||||||
@@ -132,17 +136,11 @@ class ResourceFoldingBuilder : FoldingBuilderEx() {
|
|||||||
private fun UReferenceExpression.getAndroidResourceValue(resources: LocalResourceRepository, call: UCallExpression? = null): String? {
|
private fun UReferenceExpression.getAndroidResourceValue(resources: LocalResourceRepository, call: UCallExpression? = null): String? {
|
||||||
val resourceType = resolve()?.getAndroidResourceType() ?: return null
|
val resourceType = resolve()?.getAndroidResourceType() ?: return null
|
||||||
val referenceConfig = FolderConfiguration().apply { localeQualifier = LocaleQualifier("xx") }
|
val referenceConfig = FolderConfiguration().apply { localeQualifier = LocaleQualifier("xx") }
|
||||||
val key = resolvedName
|
val key = resolvedName ?: return null
|
||||||
val resourceValue = resources.getConfiguredValue(resourceType, key, referenceConfig)?.value ?: return null
|
val resourceValue = resources.getResourceValue(resourceType, key, referenceConfig) ?: return null
|
||||||
val text = if (call != null) formatArguments(call, resourceValue) else resourceValue
|
val text = if (call != null) formatArguments(call, resourceValue) else resourceValue
|
||||||
|
|
||||||
if (resourceType == ResourceType.PLURALS && text.startsWith(STRING_PREFIX)) {
|
if (resourceType == ResourceType.STRING || resourceType == ResourceType.PLURALS) {
|
||||||
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) {
|
|
||||||
return '"' + StringUtil.shortenTextWithEllipsis(text, FOLD_MAX_LENGTH - 2, 0) + '"'
|
return '"' + StringUtil.shortenTextWithEllipsis(text, FOLD_MAX_LENGTH - 2, 0) + '"'
|
||||||
}
|
}
|
||||||
else if (text.length <= 1) {
|
else if (text.length <= 1) {
|
||||||
@@ -155,6 +153,20 @@ class ResourceFoldingBuilder : FoldingBuilderEx() {
|
|||||||
return StringUtil.shortenTextWithEllipsis(text, FOLD_MAX_LENGTH, 0)
|
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
|
// Converted from com.android.tools.idea.folding.InlinedResource#insertArguments
|
||||||
private fun formatArguments(callExpression: UCallExpression, formatString: String): String {
|
private fun formatArguments(callExpression: UCallExpression, formatString: String): String {
|
||||||
if (!formatString.contains('%')) {
|
if (!formatString.contains('%')) {
|
||||||
|
|||||||
Vendored
+2
@@ -30,5 +30,7 @@ public final class R {
|
|||||||
public static final int mydimen1=0x7f07005b;
|
public static final int mydimen1=0x7f07005b;
|
||||||
public static final int mydimen2=0x7f07005c;
|
public static final int mydimen2=0x7f07005c;
|
||||||
public static final int mydimen3=0x7f07005d;
|
public static final int mydimen3=0x7f07005d;
|
||||||
|
public static final int dimenRef=0x7f07005e;
|
||||||
|
public static final int dimenAndroidRef=0x7f07005f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+5
@@ -15,5 +15,10 @@ class MyActivity : Activity() <fold text='{...}' expand='true'>{
|
|||||||
val strings = intArrayOf(<fold text='"1111"' expand='false'>R.string.string1</fold>, <fold text='"2222"' expand='false'>R.string.string2</fold>, <fold text='"3333"' expand='false'>R.string.string3</fold>)
|
val strings = intArrayOf(<fold text='"1111"' expand='false'>R.string.string1</fold>, <fold text='"2222"' expand='false'>R.string.string2</fold>, <fold text='"3333"' expand='false'>R.string.string3</fold>)
|
||||||
val dimensions = intArrayOf(<fold text='1dip' expand='false'>R.dimen.mydimen1</fold>, <fold text='2dip' expand='false'>R.dimen.mydimen2</fold>)
|
val dimensions = intArrayOf(<fold text='1dip' expand='false'>R.dimen.mydimen1</fold>, <fold text='2dip' expand='false'>R.dimen.mydimen2</fold>)
|
||||||
val maxButtons = <fold text='max_action_buttons: 2' expand='false'>resources.getInteger(R.integer.max_action_buttons)</fold>
|
val maxButtons = <fold text='max_action_buttons: 2' expand='false'>resources.getInteger(R.integer.max_action_buttons)</fold>
|
||||||
|
val dimensionWithReference = <fold text='1dip' expand='false'>resources.getDimension(R.dimen.dimenRef)</fold>
|
||||||
|
val dimensionWithAndroidReference = <fold text='@android:dimen/app_icon_size' expand='false'>resources.getDimension(R.dimen.dimenAndroidRef)</fold>
|
||||||
|
with(resources) <fold text='{...}' expand='true'>{
|
||||||
|
val dimension = <fold text='56dip' expand='false'>resources.getDimension(R.dimen.action_bar_default_height)</fold>.toInt()
|
||||||
|
}</fold>
|
||||||
}</fold>
|
}</fold>
|
||||||
}</fold>
|
}</fold>
|
||||||
|
|||||||
+1
-1
@@ -4,6 +4,6 @@ import android.content.Context
|
|||||||
|
|
||||||
fun Context.testPlurals(quantity: Int) <fold text='{...}' expand='true'>{
|
fun Context.testPlurals(quantity: Int) <fold text='{...}' expand='true'>{
|
||||||
val plural1 = <fold text='"Reference One"' expand='false'>resources.getQuantityString(R.plurals.first, quantity)</fold>
|
val plural1 = <fold text='"Reference One"' expand='false'>resources.getQuantityString(R.plurals.first, quantity)</fold>
|
||||||
val plural2 = <fold text='Quantity One' expand='false'>this.getResources().getQuantityString(R.plurals.second, quantity)</fold>
|
val plural2 = <fold text='"Quantity One"' expand='false'>this.getResources().getQuantityString(R.plurals.second, quantity)</fold>
|
||||||
}</fold>
|
}</fold>
|
||||||
|
|
||||||
|
|||||||
+2
@@ -36,4 +36,6 @@
|
|||||||
<dimen name="mydimen3">3dip</dimen>
|
<dimen name="mydimen3">3dip</dimen>
|
||||||
<dimen name="mydimen1">1dip</dimen>
|
<dimen name="mydimen1">1dip</dimen>
|
||||||
<dimen name="mydimen2">2dip</dimen>
|
<dimen name="mydimen2">2dip</dimen>
|
||||||
|
<dimen name="dimenRef">@dimen/mydimen1</dimen>
|
||||||
|
<dimen name="dimenAndroidRef">@android:dimen/app_icon_size</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user