From f5078579303ff7a02de82e74f00a1f5e00f42988 Mon Sep 17 00:00:00 2001 From: Mikhail Mutcianko Date: Mon, 1 Sep 2014 12:19:12 +0400 Subject: [PATCH] fix R class field resolving - resolve by class name and package defined in AndroidManifest.xml --- .../jet/lang/resolve/android/AndroidUtil.kt | 15 +++++++++++++++ .../android/AndroidGotoDeclarationHandler.kt | 7 +++++-- .../jet/plugin/android/AndroidRenameProcessor.kt | 3 ++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidUtil.kt b/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidUtil.kt index 61c304a9311..42a21264a3b 100644 --- a/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidUtil.kt +++ b/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidUtil.kt @@ -22,6 +22,8 @@ import com.intellij.openapi.project.Project import org.jetbrains.jet.lang.psi.JetFile import com.intellij.openapi.components.ServiceManager import java.util.ArrayList +import com.intellij.psi.PsiField +import com.intellij.psi.PsiClass trait AndroidResource @@ -49,6 +51,7 @@ fun isAndroidSyntheticFile(f: PsiFile?): Boolean { public fun isAndroidSyntheticElement(element: PsiElement?): Boolean { return isAndroidSyntheticFile(element?.getContainingFile()) } + public fun searchAndAddAndroidDeclarations(project: Project, originalFiles: Collection): Collection { val parser = ServiceManager.getService(project, javaClass()) val file = parser?.parseToPsi(project) @@ -56,3 +59,15 @@ public fun searchAndAddAndroidDeclarations(project: Project, originalFiles: Coll if (file != null) files.add(file) return files } + +public fun isRClassField(element: PsiElement): Boolean { + return if (element is PsiField) { + val outerClass = element.getParent()?.getParent() + if (outerClass !is PsiClass) return false + val processor = ServiceManager.getService(element.getProject(), javaClass()) + val packageName = processor?.resourceManager?.readManifest()?._package + if ((outerClass as PsiClass).getQualifiedName()?.startsWith(packageName ?: "") ?: false) + true else false + } + else false +} diff --git a/idea/src/org/jetbrains/jet/plugin/android/AndroidGotoDeclarationHandler.kt b/idea/src/org/jetbrains/jet/plugin/android/AndroidGotoDeclarationHandler.kt index acef71394a7..e1a099ae2a0 100644 --- a/idea/src/org/jetbrains/jet/plugin/android/AndroidGotoDeclarationHandler.kt +++ b/idea/src/org/jetbrains/jet/plugin/android/AndroidGotoDeclarationHandler.kt @@ -28,16 +28,19 @@ import org.jetbrains.jet.lang.psi.JetSimpleNameExpression import org.jetbrains.jet.lang.psi.JetProperty import com.intellij.psi.impl.light.LightElement import com.intellij.psi.xml.XmlAttribute +import org.jetbrains.jet.lang.resolve.android.isRClassField +import com.intellij.psi.PsiField public class AndroidGotoDeclarationHandler : GotoDeclarationHandler { override fun getGotoDeclarationTargets(sourceElement: PsiElement?, offset: Int, editor: Editor?): Array? { if (sourceElement is LeafPsiElement && sourceElement.getParent() is JetSimpleNameExpression) { val resolved = JetSimpleNameReference(sourceElement.getParent() as JetSimpleNameExpression).resolve() + if (resolved == null) return null val name = if (resolved is JetProperty) { resolved.getName() } - else if (resolved is LightElement && resolved.getParent().toString() == "AndroidRClass") { - resolved.getName() + else if (isRClassField(resolved)) { + (resolved as PsiField).getName() } else null if (name != null) { diff --git a/idea/src/org/jetbrains/jet/plugin/android/AndroidRenameProcessor.kt b/idea/src/org/jetbrains/jet/plugin/android/AndroidRenameProcessor.kt index 8be95f63a3d..733a1093dea 100644 --- a/idea/src/org/jetbrains/jet/plugin/android/AndroidRenameProcessor.kt +++ b/idea/src/org/jetbrains/jet/plugin/android/AndroidRenameProcessor.kt @@ -29,13 +29,14 @@ import org.jetbrains.android.dom.wrappers.LazyValueResourceElementWrapper import org.jetbrains.android.util.AndroidResourceUtil import com.intellij.psi.xml.XmlAttribute import com.intellij.psi.impl.light.LightElement +import org.jetbrains.jet.lang.resolve.android.isRClassField public class AndroidRenameProcessor : RenamePsiElementProcessor() { override fun canProcessElement(element: PsiElement): Boolean { // either renaming synthetic property, or value in ui xml, or R light class field return (element.namedUnwrappedElement is JetProperty && isAndroidSyntheticElement(element.namedUnwrappedElement)) || element is XmlAttributeValue || - element is LightElement + isRClassField(element) } override fun prepareRenaming(element: PsiElement?, newName: String?, allRenames: MutableMap, scope: SearchScope) {