aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-05-24 13:38:57 -0700
committerTor Norbye <tnorbye@google.com>2012-05-29 16:16:21 -0700
commit2b9f07885147caab17c5fc3acb916b10a3c6273d (patch)
tree4bb50ccab007e9fa928650425ab9e3a16442ff3e
parent88933007892863ed2e3779aafcd4618732561d61 (diff)
downloadsdk-2b9f07885147caab17c5fc3acb916b10a3c6273d.zip
sdk-2b9f07885147caab17c5fc3acb916b10a3c6273d.tar.gz
sdk-2b9f07885147caab17c5fc3acb916b10a3c6273d.tar.bz2
Make Go To Declaration work for theme references
Also fix a couple of NPEs. Change-Id: Iab4544d3538d370dd76d96e3a97d49555b7c6359
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/Hyperlinks.java71
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/HyperlinksTest.java8
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/navigation1-expected-navigate15.txt7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/navigation1.xml1
5 files changed, 63 insertions, 27 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/Hyperlinks.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/Hyperlinks.java
index 6e035af..c63ed18 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/Hyperlinks.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/Hyperlinks.java
@@ -16,14 +16,15 @@
package com.android.ide.eclipse.adt.internal.editors;
-import static com.android.util.XmlUtils.ANDROID_URI;
import static com.android.ide.common.layout.LayoutConstants.ATTR_CLASS;
import static com.android.ide.common.layout.LayoutConstants.ATTR_NAME;
import static com.android.ide.common.layout.LayoutConstants.ATTR_ON_CLICK;
import static com.android.ide.common.layout.LayoutConstants.NEW_ID_PREFIX;
import static com.android.ide.common.layout.LayoutConstants.VIEW;
import static com.android.ide.common.resources.ResourceResolver.PREFIX_ANDROID_RESOURCE_REF;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_ANDROID_THEME_REF;
import static com.android.ide.common.resources.ResourceResolver.PREFIX_RESOURCE_REF;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_THEME_REF;
import static com.android.ide.eclipse.adt.AdtConstants.ANDROID_PKG;
import static com.android.ide.eclipse.adt.AdtConstants.EXT_XML;
import static com.android.ide.eclipse.adt.AdtConstants.FN_RESOURCE_BASE;
@@ -38,6 +39,10 @@ import static com.android.sdklib.xml.AndroidManifest.ATTRIBUTE_NAME;
import static com.android.sdklib.xml.AndroidManifest.ATTRIBUTE_PACKAGE;
import static com.android.sdklib.xml.AndroidManifest.NODE_ACTIVITY;
import static com.android.sdklib.xml.AndroidManifest.NODE_SERVICE;
+import static com.android.tools.lint.detector.api.LintConstants.ANDROID_STYLE_RESOURCE_PREFIX;
+import static com.android.tools.lint.detector.api.LintConstants.NEW_ID_RESOURCE_PREFIX;
+import static com.android.tools.lint.detector.api.LintConstants.STYLE_RESOURCE_PREFIX;
+import static com.android.util.XmlUtils.ANDROID_URI;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
@@ -210,14 +215,14 @@ public class Hyperlinks {
}
String value = attribute.getValue();
- if (value.startsWith("@+")) { //$NON-NLS-1$
+ if (value.startsWith(NEW_ID_RESOURCE_PREFIX)) {
// It's a value -declaration-, nowhere else to jump
// (though we could consider jumping to the R-file; would that
// be helpful?)
return false;
}
- Pair<ResourceType,String> resource = ResourceHelper.parseResource(value);
+ Pair<ResourceType,String> resource = parseResource(value);
if (resource != null) {
ResourceType type = resource.getFirst();
if (type != null) {
@@ -1026,23 +1031,28 @@ public class Hyperlinks {
if (type == ResourceType.ID) {
// Ids are recorded in <item> tags instead of <id> tags
targetTag = "item"; //$NON-NLS-1$
- } else if (type == ResourceType.ATTR) {
+ }
+
+ Pair<File, Integer> result = findTag(name, file, parser, document, targetTag);
+ if (result == null && type == ResourceType.ATTR) {
// Attributes seem to be defined in <public> tags
targetTag = "public"; //$NON-NLS-1$
+ result = findTag(name, file, parser, document, targetTag);
}
- Element root = document.getDocumentElement();
- if (root.getTagName().equals(ROOT_ELEMENT)) {
- NodeList children = root.getChildNodes();
- for (int i = 0, n = children.getLength(); i < n; i++) {
- Node child = children.item(i);
- if (child.getNodeType() == Node.ELEMENT_NODE) {
- Element element = (Element) child;
- if (element.getTagName().equals(targetTag)) {
- String elementName = element.getAttribute(NAME_ATTR);
- if (elementName.equals(name)) {
+ return result;
+ }
- return Pair.of(file, parser.getOffset(element));
- }
+ private static Pair<File, Integer> findTag(String name, File file, OffsetTrackingParser parser,
+ Document document, String targetTag) {
+ NodeList children = document.getElementsByTagName(targetTag);
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ Element element = (Element) child;
+ if (element.getTagName().equals(targetTag)) {
+ String elementName = element.getAttribute(NAME_ATTR);
+ if (elementName.equals(name)) {
+ return Pair.of(file, parser.getOffset(element));
}
}
}
@@ -1067,15 +1077,17 @@ public class Hyperlinks {
}
}
- Pair<ResourceType,String> resource = ResourceHelper.parseResource(url);
+ Pair<ResourceType,String> resource = parseResource(url);
if (resource == null) {
- String androidStyle = "@android:style/"; //$NON-NLS-1$
+ String androidStyle = ANDROID_STYLE_RESOURCE_PREFIX;
if (url.startsWith(PREFIX_ANDROID_RESOURCE_REF)) {
url = androidStyle + url.substring(PREFIX_ANDROID_RESOURCE_REF.length());
+ } else if (url.startsWith(PREFIX_ANDROID_THEME_REF)) {
+ url = androidStyle + url.substring(PREFIX_ANDROID_THEME_REF.length());
} else if (url.startsWith(ANDROID_PKG + ':')) {
url = androidStyle + url.substring(ANDROID_PKG.length() + 1);
} else {
- url = "@style/" + url; //$NON-NLS-1$
+ url = STYLE_RESOURCE_PREFIX + url;
}
}
return getResourceLinks(range, url);
@@ -1087,6 +1099,16 @@ public class Hyperlinks {
return getResourceLinks(range, url, project, configuration);
}
+ /** Parse a resource reference or a theme reference and return the individual parts */
+ private static Pair<ResourceType,String> parseResource(String url) {
+ if (url.startsWith(PREFIX_THEME_REF)) {
+ url = PREFIX_RESOURCE_REF + url.substring(PREFIX_THEME_REF.length());
+ return ResourceHelper.parseResource(url);
+ }
+
+ return ResourceHelper.parseResource(url);
+ }
+
/**
* Computes hyperlinks to resource definitions for resource urls (e.g.
* {@code @android:string/ok} or {@code @layout/foo}. May create multiple links.
@@ -1101,14 +1123,15 @@ public class Hyperlinks {
@NonNull IProject project, @Nullable FolderConfiguration configuration) {
List<IHyperlink> links = new ArrayList<IHyperlink>();
- Pair<ResourceType,String> resource = ResourceHelper.parseResource(url);
+ Pair<ResourceType,String> resource = parseResource(url);
if (resource == null || resource.getFirst() == null) {
return null;
}
ResourceType type = resource.getFirst();
String name = resource.getSecond();
- boolean isFramework = url.startsWith("@android"); //$NON-NLS-1$
+ boolean isFramework = url.startsWith(PREFIX_ANDROID_RESOURCE_REF)
+ || url.startsWith(PREFIX_ANDROID_THEME_REF);
if (project == null) {
// Local reference *within* a framework
isFramework = true;
@@ -1217,10 +1240,10 @@ public class Hyperlinks {
return getStyleLinks(context, range, attribute.getValue());
}
if (attribute != null
- && attribute.getValue().startsWith(PREFIX_RESOURCE_REF)) {
+ && (attribute.getValue().startsWith(PREFIX_RESOURCE_REF)
+ || attribute.getValue().startsWith(PREFIX_THEME_REF))) {
// Instantly create links for resources since we can use the existing
// resolved maps for this and offer multiple choices for the user
-
String url = attribute.getValue();
return getResourceLinks(range, url);
}
@@ -1253,7 +1276,7 @@ public class Hyperlinks {
int offset = caretOffset;
while (offset > lineStart) {
char c = document.getChar(offset);
- if (c == '@') {
+ if (c == '@' || c == '?') {
urlStart = offset;
break;
} else if (!isValidResourceUrlChar(c)) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java
index 3524970..9261aff 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java
@@ -736,7 +736,8 @@ public class OutlinePage extends ContentOutlinePage
// Temporary diagnostics code when developing GridLayout
if (GridLayoutRule.sDebugGridLayout) {
String namespace;
- if (e.getParentNode().getNodeName().equals(GRID_LAYOUT)) {
+ if (e.getParentNode() != null
+ && e.getParentNode().getNodeName().equals(GRID_LAYOUT)) {
namespace = ANDROID_URI;
} else {
IProject project = mGraphicalEditorPart.getProject();
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/HyperlinksTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/HyperlinksTest.java
index 0d42357..a54376d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/HyperlinksTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/HyperlinksTest.java
@@ -19,8 +19,6 @@ import static com.android.sdklib.SdkConstants.FD_SOURCES;
import com.android.ide.common.resources.ResourceFile;
import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
-import com.android.ide.eclipse.adt.internal.editors.Hyperlinks;
import com.android.ide.eclipse.adt.internal.editors.Hyperlinks.ResourceLink;
import com.android.ide.eclipse.adt.internal.editors.Hyperlinks.XmlResolver;
import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.AdtProjectTest;
@@ -180,6 +178,12 @@ public class HyperlinksTest extends AdtProjectTest {
"class=\"com.and^roid.eclipse.tests.TestFragment\"");
}
+ public void testNavigate15() throws Exception {
+ // Check navigating to a theme resource
+ checkXmlNavigation("navigation1.xml", "res/layout/navigation1.xml",
+ "?android:attr/alert^DialogStyle");
+ }
+
// Left to test:
// onClick handling
// class attributes
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/navigation1-expected-navigate15.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/navigation1-expected-navigate15.txt
new file mode 100644
index 0000000..e36c5f3
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/navigation1-expected-navigate15.txt
@@ -0,0 +1,7 @@
+Go To Declaration in navigation1.xml for ?android:attr/alert^DialogStyle:
+Open Declaration in values/attrs.xml : [?android:attr/alertDialogStyle]
+ data/res/values/attrs.xml
+
+
+After open, the selected text is:
+ <attr name="alertDialogStyle" format="reference" />^
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/navigation1.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/navigation1.xml
index 9c175fc..e7ac4bc 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/navigation1.xml
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/navigation1.xml
@@ -13,4 +13,5 @@
<EditText
android:text="@android:string/ok"
</EditText>
+ <EditText android:text="?android:attr/alertDialogStyle" />
</LinearLayout>