android: navigation from java to resource should work even if related R class field cannot be resolved

This commit is contained in:
Eugene Kudelevsky
2012-02-13 14:04:08 +04:00
parent 50e72b7591
commit 191a7ee0cb
6 changed files with 88 additions and 26 deletions
@@ -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<PsiElement> 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++) {
@@ -270,28 +270,40 @@ public class AndroidResourceUtil {
@NotNull
public static List<PsiElement> 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<PsiElement> findResourcesByFieldName(@NotNull LocalResourceManager manager,
@NotNull String resClassName,
@NotNull String fieldName) {
List<PsiElement> targets = new ArrayList<PsiElement>();
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;
@@ -3,7 +3,10 @@
<resources>
<item type="id" name="myId" />
<item type="id" name="myId1" />
<item type="id" name="notInRJava" />
<item type="string" name="str2" />
<item type="string"/>
<item type="id"/>
<dimen name="notInRJava"/>
</resources>
@@ -0,0 +1,7 @@
package p1.p2;
class Java {
public void g() {
int a = R.id.notIn<caret>RJava;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
class Java {
public void g() {
int a = R.dimen.notIn<caret>RJava;
}
}
@@ -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);
}