aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2011-12-16 11:05:22 -0800
committerTor Norbye <tnorbye@google.com>2011-12-16 11:07:30 -0800
commit2c256afd8caf3630bdcba35988150e7646114284 (patch)
tree99119156a741d5438e65d1d276075c14dfea90d4
parentd5f733212db0aaa7b80d0f9d7184f8cc6943503d (diff)
downloadsdk-2c256afd8caf3630bdcba35988150e7646114284.zip
sdk-2c256afd8caf3630bdcba35988150e7646114284.tar.gz
sdk-2c256afd8caf3630bdcba35988150e7646114284.tar.bz2
Fix <item> resource handling
This changeset fixes the handling of resource references inside items, such as creating a layout alias like this: <item type="layout" name="foo">@layout/bar</item> This was not working correctly for code completion (no resource completion inside the text node area of the item, and it was not working correctly for the unused resource detector. Change-Id: I844bf9be4802a0d246accd47b83514ebf0ae6d53
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesContentAssist.java36
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/animator1-expected-completion61.txt3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-applyCompletion45.diff4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion70.txt3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion71.txt3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2.xml8
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/UnusedResourceDetector.java48
8 files changed, 100 insertions, 21 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesContentAssist.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesContentAssist.java
index 1661100..844ff15 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesContentAssist.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesContentAssist.java
@@ -17,11 +17,14 @@
package com.android.ide.eclipse.adt.internal.editors.resources;
import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME_PREFIX;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_ANDROID_RESOURCE_REF;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_RESOURCE_REF;
import static com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor.ATTRIBUTE_ICON_FILENAME;
import static com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors.ITEM_TAG;
import static com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors.NAME_ATTR;
import static com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors.STYLE_ELEMENT;
import static com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.DESCRIPTOR_LAYOUT;
+import static com.android.tools.lint.detector.api.LintConstants.ATTR_TYPE;
import com.android.annotations.VisibleForTesting;
import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist;
@@ -33,6 +36,7 @@ import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvi
import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
+import com.android.ide.eclipse.adt.internal.editors.uimodel.UiResourceAttributeNode;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import org.eclipse.jface.text.contentassist.CompletionProposal;
@@ -197,6 +201,38 @@ public class ResourcesContentAssist extends AndroidContentAssist {
}
}
}
+ } else if (parentNode.getNodeName().equals(ITEM_TAG)) {
+ // Completing text content inside an <item> tag: offer @resource completion.
+ if (prefix.startsWith(PREFIX_RESOURCE_REF) || prefix.trim().length() == 0) {
+ String[] choices = UiResourceAttributeNode.computeResourceStringMatches(
+ mEditor, null /*attributeDescriptor*/, prefix);
+ if (choices == null || choices.length == 0) {
+ return;
+ }
+
+ // If the parent item tag specifies a type, filter the results
+ Node typeNode = parentNode.getAttributes().getNamedItem(ATTR_TYPE);
+ if (typeNode != null) {
+ String value = typeNode.getNodeValue();
+ List<String> filtered = new ArrayList<String>();
+ for (String s : choices) {
+ if (s.startsWith(PREFIX_ANDROID_RESOURCE_REF) ||
+ s.startsWith(PREFIX_RESOURCE_REF+ value)) {
+ filtered.add(s);
+ }
+ }
+ if (filtered.size() > 0) {
+ choices = filtered.toArray(new String[filtered.size()]);
+ }
+ }
+
+ int replaceLength = computeTextReplaceLength(currentNode, offset);
+ addMatchingProposals(proposals, choices, offset, currentNode,
+ prefix, (char) 0 /*needTag*/, true /* isAttribute */, false /*isNew*/,
+ false /* skipEndTag*/,
+ replaceLength);
+
+ }
}
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java
index 1b3cb3e..2d63835 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java
@@ -48,6 +48,7 @@ import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
+@SuppressWarnings("javadoc")
public class AndroidContentAssistTest extends AdtProjectTest {
private static final String CARET = "^"; //$NON-NLS-1$
@@ -466,6 +467,16 @@ public class AndroidContentAssistTest extends AdtProjectTest {
checkManifestCompletion("manifest.xml", "<uses-sdk android:minSdkVersion=\"^11\" />");
}
+ public void testCompletion70() throws Exception {
+ checkResourceCompletion("completionvalues2.xml",
+ "<item name=\"main_layout4\" type=\"layout\">^</item>");
+ }
+
+ public void testCompletion71() throws Exception {
+ checkResourceCompletion("completionvalues2.xml",
+ "<item name=\"main_layout5\" type=\"string\">@string/^app_name</item>");
+ }
+
// ---- Test *applying* code completion ----
@@ -753,6 +764,11 @@ public class AndroidContentAssistTest extends AdtProjectTest {
checkApplyResourceCompletion("completionvalues1.xml", "[^false]", "true");
}
+ public void testApplyCompletion45() throws Exception {
+ checkApplyResourceCompletion("completionvalues2.xml",
+ "@string/^app_name", "@string/hello");
+ }
+
// --- Code Completion test infrastructure ----
private void checkLayoutCompletion(String name, String caretLocation) throws Exception {
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/animator1-expected-completion61.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/animator1-expected-completion61.txt
index 9ac8a52..1ba8a62 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/animator1-expected-completion61.txt
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/animator1-expected-completion61.txt
@@ -10,6 +10,9 @@ Code completion in animator1.xml for android:interpolator="^@android:anim/bounce
@android:anim/cycle_interpolator
@android:
@+id/
+@anim/
+@animator/
+@color/
@drawable/
@id/
@layout/
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-applyCompletion45.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-applyCompletion45.diff
new file mode 100644
index 0000000..6498668
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-applyCompletion45.diff
@@ -0,0 +1,4 @@
+Code completion in completionvalues2.xml for @string/^app_name selecting @string/hello:
+< <item name="main_layout5" type="string">@string/^app_name</item>
+---
+> <item name="main_layout5" type="string">@string/hello^</item>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion70.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion70.txt
new file mode 100644
index 0000000..20f8a74
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion70.txt
@@ -0,0 +1,3 @@
+Code completion in completionvalues2.xml for <item name="main_layout4" type="layout">^</item>:
+@android:
+@layout/
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion71.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion71.txt
new file mode 100644
index 0000000..641cddb
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion71.txt
@@ -0,0 +1,3 @@
+Code completion in completionvalues2.xml for <item name="main_layout5" type="string">@string/^app_name</item>:
+@string/app_name
+@string/hello
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2.xml
new file mode 100644
index 0000000..293abc0
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <item name="main_layout" type="layout">@layout/main2</item>
+ <item name="main_layout2" type="layout"> @layout/main_layout </item>
+ <item name="main_layout3" type="layout"> </item>
+ <item name="main_layout4" type="layout"></item>
+ <item name="main_layout5" type="string">@string/app_name</item>
+</resources>
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/UnusedResourceDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/UnusedResourceDetector.java
index 13616b7..86f0118 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/UnusedResourceDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/UnusedResourceDetector.java
@@ -453,34 +453,40 @@ public class UnusedResourceDetector extends ResourceXmlDetector implements Detec
mDeclarationToFile.put(resource, context.file);
Handle handle = context.parser.createLocationHandle(context, item);
mDeclarationToHandle.put(resource, handle);
+
+ checkChildRefs(item);
}
}
} else {
assert TAG_STYLE.equals(element.getTagName())
|| TAG_ARRAY.equals(element.getTagName())
|| TAG_STRING_ARRAY.equals(element.getTagName());
- // Look for ?attr/ and @dimen/foo etc references in the item children
for (Element item : LintUtils.getChildren(element)) {
- NodeList childNodes = item.getChildNodes();
- for (int i = 0, n = childNodes.getLength(); i < n; i++) {
- Node child = childNodes.item(i);
- if (child.getNodeType() == Node.TEXT_NODE) {
- String text = child.getNodeValue();
-
- int index = text.indexOf(ATTR_REF_PREFIX);
- if (index != -1) {
- String name = text.substring(index + ATTR_REF_PREFIX.length()).trim();
- mReferences.add(R_PREFIX + RESOURCE_CLZ_ATTR + '.' + name);
- } else {
- index = text.indexOf('@');
- if (index != -1 && text.indexOf('/', index) != -1
- && !text.startsWith("@android:", index)) { //$NON-NLS-1$
- // Compute R-string, e.g. @string/foo => R.string.foo
- String token = text.substring(index + 1).trim().replace('/', '.');
- String r = R_PREFIX + token;
- mReferences.add(r);
- }
- }
+ checkChildRefs(item);
+ }
+ }
+ }
+
+ private void checkChildRefs(Element item) {
+ // Look for ?attr/ and @dimen/foo etc references in the item children
+ NodeList childNodes = item.getChildNodes();
+ for (int i = 0, n = childNodes.getLength(); i < n; i++) {
+ Node child = childNodes.item(i);
+ if (child.getNodeType() == Node.TEXT_NODE) {
+ String text = child.getNodeValue();
+
+ int index = text.indexOf(ATTR_REF_PREFIX);
+ if (index != -1) {
+ String name = text.substring(index + ATTR_REF_PREFIX.length()).trim();
+ mReferences.add(R_PREFIX + RESOURCE_CLZ_ATTR + '.' + name);
+ } else {
+ index = text.indexOf('@');
+ if (index != -1 && text.indexOf('/', index) != -1
+ && !text.startsWith("@android:", index)) { //$NON-NLS-1$
+ // Compute R-string, e.g. @string/foo => R.string.foo
+ String token = text.substring(index + 1).trim().replace('/', '.');
+ String r = R_PREFIX + token;
+ mReferences.add(r);
}
}
}