diff --git a/plugins/android/src/org/jetbrains/android/AndroidGotoDeclarationHandler.java b/plugins/android/src/org/jetbrains/android/AndroidGotoDeclarationHandler.java index 8a3dd17f6c9c..aa5db7e53521 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidGotoDeclarationHandler.java +++ b/plugins/android/src/org/jetbrains/android/AndroidGotoDeclarationHandler.java @@ -26,6 +26,9 @@ import org.jetbrains.android.dom.wrappers.FileResourceElementWrapper; import org.jetbrains.android.dom.wrappers.ValueResourceElementWrapper; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.util.AndroidResourceUtil; +import org.jetbrains.android.util.AndroidUtils; + +import java.util.List; /** * @author Eugene.Kudelevsky @@ -47,19 +50,41 @@ public class AndroidGotoDeclarationHandler implements GotoDeclarationHandler { return null; } - final PsiElement resolvedElement = refExp.resolve(); - if (resolvedElement == null || !(resolvedElement instanceof PsiField)) { + final String resFieldName = refExp.getReferenceName(); + if (resFieldName == null || resFieldName.length() == 0) { return null; } - final PsiField resolvedField = (PsiField)resolvedElement; - final PsiFile containingFile = resolvedField.getContainingFile(); + PsiExpression qExp = refExp.getQualifierExpression(); + if (!(qExp instanceof PsiReferenceExpression)) { + return null; + } + final PsiReferenceExpression resClassReference = (PsiReferenceExpression)qExp; - if (containingFile == null || !AndroidResourceUtil.isRJavaField(containingFile, resolvedField)) { + final String resClassName = resClassReference.getReferenceName(); + if (resClassName == null || resClassName.length() == 0) { return null; } - final PsiElement[] resources = AndroidResourceUtil.findResources(resolvedField); + qExp = resClassReference.getQualifierExpression(); + if (!(qExp instanceof PsiReferenceExpression)) { + return null; + } + + final PsiElement resolvedElement = ((PsiReferenceExpression)qExp).resolve(); + if (!(resolvedElement instanceof PsiClass) || + !AndroidUtils.R_CLASS_NAME.equals(((PsiClass)resolvedElement).getName())) { + return null; + } + + final PsiFile containingFile = resolvedElement.getContainingFile(); + if (containingFile == null || !AndroidUtils.isRClassFile(facet, containingFile)) { + return null; + } + + final List resourceList = + AndroidResourceUtil.findResourcesByFieldName(facet.getLocalResourceManager(), resClassName, resFieldName); + final PsiElement[] resources = resourceList.toArray(new PsiElement[resourceList.size()]); final PsiElement[] wrappedResources = new PsiElement[resources.length]; for (int i = 0; i < resources.length; i++) { diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java index cea10c4c3d9c..f2a71e6b7738 100644 --- a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java +++ b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java @@ -270,28 +270,40 @@ public class AndroidResourceUtil { @NotNull public static List findResourcesByField(@NotNull LocalResourceManager manager, @NotNull PsiField field) { - String type = getResourceClassName(field); + final String type = getResourceClassName(field); + if (type == null) { + return Collections.emptyList(); + } + + final String fieldName = field.getName(); + if (fieldName == null) { + return Collections.emptyList(); + } + return findResourcesByFieldName(manager, type, fieldName); + } + + @NotNull + public static List findResourcesByFieldName(@NotNull LocalResourceManager manager, + @NotNull String resClassName, + @NotNull String fieldName) { List targets = new ArrayList(); - if (type != null) { - String name = field.getName(); - if (type.equals("id")) { - manager.collectIdDeclarations(name, targets); + if (resClassName.equals("id")) { + manager.collectIdDeclarations(fieldName, targets); + } + for (PsiFile file : manager.findResourceFiles(resClassName, fieldName, false)) { + targets.add(file); + } + for (ResourceElement element : manager.findValueResources(resClassName, fieldName, false)) { + targets.add(element.getName().getXmlAttributeValue()); + } + if (resClassName.equals("attr")) { + for (Attr attr : manager.findAttrs(fieldName)) { + targets.add(attr.getName().getXmlAttributeValue()); } - for (PsiFile file : manager.findResourceFiles(type, name, false)) { - targets.add(file); - } - for (ResourceElement element : manager.findValueResources(type, name, false)) { - targets.add(element.getName().getXmlAttributeValue()); - } - if (type.equals("attr")) { - for (Attr attr : manager.findAttrs(name)) { - targets.add(attr.getName().getXmlAttributeValue()); - } - } - else if (type.equals("styleable")) { - for (DeclareStyleable styleable : manager.findStyleables(name)) { - targets.add(styleable.getName().getXmlAttributeValue()); - } + } + else if (resClassName.equals("styleable")) { + for (DeclareStyleable styleable : manager.findStyleables(fieldName)) { + targets.add(styleable.getName().getXmlAttributeValue()); } } return targets; diff --git a/plugins/android/testData/resNavigation/res/values/ids.xml b/plugins/android/testData/resNavigation/res/values/ids.xml index ac1f1adc1377..04e5e83bf9c4 100644 --- a/plugins/android/testData/resNavigation/res/values/ids.xml +++ b/plugins/android/testData/resNavigation/res/values/ids.xml @@ -3,7 +3,10 @@ + + + diff --git a/plugins/android/testData/resNavigation/src/p1/p2/JavaFileNavigation6.java b/plugins/android/testData/resNavigation/src/p1/p2/JavaFileNavigation6.java new file mode 100644 index 000000000000..aacfdfa28362 --- /dev/null +++ b/plugins/android/testData/resNavigation/src/p1/p2/JavaFileNavigation6.java @@ -0,0 +1,7 @@ +package p1.p2; + +class Java { + public void g() { + int a = R.id.notInRJava; + } +} \ No newline at end of file diff --git a/plugins/android/testData/resNavigation/src/p1/p2/JavaFileNavigation7.java b/plugins/android/testData/resNavigation/src/p1/p2/JavaFileNavigation7.java new file mode 100644 index 000000000000..31384d4e3e40 --- /dev/null +++ b/plugins/android/testData/resNavigation/src/p1/p2/JavaFileNavigation7.java @@ -0,0 +1,7 @@ +package p1.p2; + +class Java { + public void g() { + int a = R.dimen.notInRJava; + } +} \ No newline at end of file diff --git a/plugins/android/testSrc/org/jetbrains/android/AndroidResourcesLineMarkerTest.java b/plugins/android/testSrc/org/jetbrains/android/AndroidResourcesLineMarkerTest.java index 278cb8e1ed20..d88bc50189c4 100644 --- a/plugins/android/testSrc/org/jetbrains/android/AndroidResourcesLineMarkerTest.java +++ b/plugins/android/testSrc/org/jetbrains/android/AndroidResourcesLineMarkerTest.java @@ -122,6 +122,14 @@ public class AndroidResourcesLineMarkerTest extends AndroidTestCase { doJavaFileNavigationTest(1, true); } + public void testJavaFileNavigation6() throws Exception { + doJavaFileNavigationTest(1, true); + } + + public void testJavaFileNavigation7() throws Exception { + doJavaFileNavigationTest(1, true); + } + /*public void testRJavaFileNavigation1() throws Exception { doRJavaFileNavigationTest(1); }