diff options
author | Tor Norbye <tnorbye@google.com> | 2012-05-29 16:17:46 -0700 |
---|---|---|
committer | android code review <noreply-gerritcodereview@google.com> | 2012-05-29 16:17:47 -0700 |
commit | 0d9c4404b933d2205214d7f7bad7e1153e99055f (patch) | |
tree | 4bb50ccab007e9fa928650425ab9e3a16442ff3e | |
parent | 88933007892863ed2e3779aafcd4618732561d61 (diff) | |
parent | 2b9f07885147caab17c5fc3acb916b10a3c6273d (diff) | |
download | sdk-0d9c4404b933d2205214d7f7bad7e1153e99055f.zip sdk-0d9c4404b933d2205214d7f7bad7e1153e99055f.tar.gz sdk-0d9c4404b933d2205214d7f7bad7e1153e99055f.tar.bz2 |
Merge "Make Go To Declaration work for theme references"
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> |