mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
optimize working with android resources
This commit is contained in:
@@ -26,6 +26,7 @@ import com.intellij.psi.xml.*;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomManager;
|
||||
import org.jetbrains.android.dom.resources.ResourceElement;
|
||||
import org.jetbrains.android.dom.wrappers.LazyValueResourceElementWrapper;
|
||||
import org.jetbrains.android.dom.wrappers.ResourceElementWrapper;
|
||||
import org.jetbrains.android.dom.wrappers.ValueResourceElementWrapper;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
@@ -45,21 +46,26 @@ import java.util.List;
|
||||
public class AndroidFindUsagesHandlerFactory extends FindUsagesHandlerFactory {
|
||||
@Override
|
||||
public boolean canFindUsages(@NotNull PsiElement element) {
|
||||
if (element instanceof XmlAttributeValue) {
|
||||
XmlAttributeValue value = (XmlAttributeValue)element;
|
||||
PsiElement element1 = LazyValueResourceElementWrapper.computeLazyElement(element);
|
||||
if (element1 == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (element1 instanceof XmlAttributeValue) {
|
||||
XmlAttributeValue value = (XmlAttributeValue)element1;
|
||||
if (AndroidResourceUtil.findIdFields(value).length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
element = correctResourceElement(element);
|
||||
if (element instanceof PsiField) {
|
||||
return AndroidResourceUtil.isResourceField((PsiField)element);
|
||||
element1 = correctResourceElement(element1);
|
||||
if (element1 instanceof PsiField) {
|
||||
return AndroidResourceUtil.isResourceField((PsiField)element1);
|
||||
}
|
||||
else if (element instanceof PsiFile) {
|
||||
return AndroidResourceUtil.findResourceFieldsForFileResource((PsiFile)element, true).length > 0;
|
||||
else if (element1 instanceof PsiFile) {
|
||||
return AndroidResourceUtil.findResourceFieldsForFileResource((PsiFile)element1, true).length > 0;
|
||||
}
|
||||
else if (element instanceof XmlTag) {
|
||||
return AndroidResourceUtil.findResourceFieldsForValueResource((XmlTag)element, true).length > 0;
|
||||
else if (element1 instanceof XmlTag) {
|
||||
return AndroidResourceUtil.findResourceFieldsForValueResource((XmlTag)element1, true).length > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -101,7 +107,11 @@ public class AndroidFindUsagesHandlerFactory extends FindUsagesHandlerFactory {
|
||||
|
||||
@Override
|
||||
public FindUsagesHandler createFindUsagesHandler(@NotNull PsiElement element, boolean forHighlightUsages) {
|
||||
PsiElement e = element;
|
||||
PsiElement e = LazyValueResourceElementWrapper.computeLazyElement(element);
|
||||
if (e == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AndroidFacet facet = AndroidFacet.getInstance(e);
|
||||
assert facet != null;
|
||||
if (e instanceof XmlAttributeValue) {
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomManager;
|
||||
import org.jetbrains.android.dom.resources.ResourceElement;
|
||||
import org.jetbrains.android.dom.wrappers.LazyValueResourceElementWrapper;
|
||||
import org.jetbrains.android.dom.wrappers.ValueResourceElementWrapper;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.resourceManagers.LocalResourceManager;
|
||||
@@ -67,23 +68,28 @@ public class AndroidRenameResourceProcessor extends RenamePsiElementProcessor {
|
||||
public boolean canProcessElement(@NotNull final PsiElement element) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
public Boolean compute() {
|
||||
if (element instanceof PsiFile) {
|
||||
return AndroidFacet.getInstance(element) != null && AndroidResourceUtil.isInResourceSubdirectory((PsiFile)element, null);
|
||||
final PsiElement element1 = LazyValueResourceElementWrapper.computeLazyElement(element);
|
||||
if (element1 == null) {
|
||||
return false;
|
||||
}
|
||||
else if (element instanceof PsiField) {
|
||||
PsiField field = (PsiField)element;
|
||||
|
||||
if (element1 instanceof PsiFile) {
|
||||
return AndroidFacet.getInstance(element1) != null && AndroidResourceUtil.isInResourceSubdirectory((PsiFile)element1, null);
|
||||
}
|
||||
else if (element1 instanceof PsiField) {
|
||||
PsiField field = (PsiField)element1;
|
||||
if (AndroidResourceUtil.isResourceField(field)) {
|
||||
return AndroidResourceUtil.findResourcesByField(field).size() > 0;
|
||||
}
|
||||
}
|
||||
else if (element instanceof XmlAttributeValue) {
|
||||
LocalResourceManager manager = LocalResourceManager.getInstance(element);
|
||||
else if (element1 instanceof XmlAttributeValue) {
|
||||
LocalResourceManager manager = LocalResourceManager.getInstance(element1);
|
||||
if (manager != null) {
|
||||
if (AndroidResourceUtil.isIdDeclaration((XmlAttributeValue)element)) {
|
||||
if (AndroidResourceUtil.isIdDeclaration((XmlAttributeValue)element1)) {
|
||||
return true;
|
||||
}
|
||||
// then it is value resource
|
||||
XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
|
||||
XmlTag tag = PsiTreeUtil.getParentOfType(element1, XmlTag.class);
|
||||
return tag != null && manager.getValueResourceType(tag) != null;
|
||||
}
|
||||
}
|
||||
@@ -94,22 +100,29 @@ public class AndroidRenameResourceProcessor extends RenamePsiElementProcessor {
|
||||
|
||||
@Override
|
||||
public void prepareRenaming(PsiElement element, String newName, Map<PsiElement, String> allRenames) {
|
||||
AndroidFacet facet = AndroidFacet.getInstance(element);
|
||||
assert facet != null;
|
||||
if (element instanceof PsiFile) {
|
||||
prepareResourceFileRenaming((PsiFile)element, newName, allRenames, facet);
|
||||
final PsiElement element1 = LazyValueResourceElementWrapper.computeLazyElement(element);
|
||||
if (element1 == null) {
|
||||
return;
|
||||
}
|
||||
else if (element instanceof XmlAttributeValue) {
|
||||
XmlAttributeValue value = (XmlAttributeValue)element;
|
||||
|
||||
// todo: support renaming alternative value resources
|
||||
|
||||
AndroidFacet facet = AndroidFacet.getInstance(element1);
|
||||
assert facet != null;
|
||||
if (element1 instanceof PsiFile) {
|
||||
prepareResourceFileRenaming((PsiFile)element1, newName, allRenames, facet);
|
||||
}
|
||||
else if (element1 instanceof XmlAttributeValue) {
|
||||
XmlAttributeValue value = (XmlAttributeValue)element1;
|
||||
if (AndroidResourceUtil.isIdDeclaration(value)) {
|
||||
prepareIdRenaming(value, newName, allRenames, facet);
|
||||
}
|
||||
else {
|
||||
prepareValueResourceRenaming(element, newName, allRenames, facet);
|
||||
prepareValueResourceRenaming(element1, newName, allRenames, facet);
|
||||
}
|
||||
}
|
||||
else if (element instanceof PsiField) {
|
||||
prepareResourceFieldRenaming((PsiField)element, newName, allRenames);
|
||||
else if (element1 instanceof PsiField) {
|
||||
prepareResourceFieldRenaming((PsiField)element1, newName, allRenames);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package org.jetbrains.android;
|
||||
|
||||
import com.android.resources.ResourceType;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.XmlRecursiveElementVisitor;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.indexing.*;
|
||||
@@ -11,8 +16,9 @@ import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import com.intellij.util.xml.NanoXmlUtil;
|
||||
import org.jetbrains.android.util.AndroidCommonUtils;
|
||||
import org.jetbrains.android.util.ResourceEntry;
|
||||
import org.jetbrains.android.util.ValueResourcesFileParser;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -26,8 +32,12 @@ import java.util.Set;
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class AndroidValueResourcesIndex extends FileBasedIndexExtension<ResourceEntry, Set<ResourceEntry>> {
|
||||
public static final ID<ResourceEntry, Set<ResourceEntry>> INDEX_ID = ID.create("android.value.resources.index");
|
||||
public class AndroidValueResourcesIndex extends FileBasedIndexExtension<ResourceEntry, Set<AndroidValueResourcesIndex.MyResourceInfo>> {
|
||||
public static final ID<ResourceEntry, Set<MyResourceInfo>> INDEX_ID = ID.create("android.value.resources.index");
|
||||
|
||||
@NonNls private static final String RESOURCES_ROOT_TAG = "resources";
|
||||
@NonNls private static final String NAME_ATTRIBUTE_VALUE = "name";
|
||||
@NonNls private static final String TYPE_ATTRIBUTE_VALUE = "type";
|
||||
|
||||
private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
|
||||
@Override
|
||||
@@ -37,28 +47,54 @@ public class AndroidValueResourcesIndex extends FileBasedIndexExtension<Resource
|
||||
}
|
||||
};
|
||||
|
||||
private final DataIndexer<ResourceEntry, Set<ResourceEntry>, FileContent> myIndexer =
|
||||
new DataIndexer<ResourceEntry, Set<ResourceEntry>, FileContent>() {
|
||||
private final DataIndexer<ResourceEntry, Set<MyResourceInfo>, FileContent> myIndexer =
|
||||
new DataIndexer<ResourceEntry, Set<MyResourceInfo>, FileContent>() {
|
||||
@Override
|
||||
@NotNull
|
||||
public Map<ResourceEntry, Set<ResourceEntry>> map(FileContent inputData) {
|
||||
|
||||
if (CharArrayUtil.indexOf(inputData.getContentAsText(), "<resources", 0) < 0) {
|
||||
public Map<ResourceEntry, Set<MyResourceInfo>> map(FileContent inputData) {
|
||||
if (!isSimilarFile(inputData)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
final Map<ResourceEntry, Set<ResourceEntry>> result = new HashMap<ResourceEntry, Set<ResourceEntry>>();
|
||||
final PsiFile file = inputData.getPsiFile();
|
||||
|
||||
NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()), new ValueResourcesFileParser() {
|
||||
@Override
|
||||
protected void stop() {
|
||||
throw new NanoXmlUtil.ParserStoppedException();
|
||||
}
|
||||
if (!(file instanceof XmlFile)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
final Map<ResourceEntry, Set<MyResourceInfo>> result = new HashMap<ResourceEntry, Set<MyResourceInfo>>();
|
||||
|
||||
file.accept(new XmlRecursiveElementVisitor() {
|
||||
@Override
|
||||
protected void process(@NotNull ResourceEntry entry) {
|
||||
result.put(entry, Collections.<ResourceEntry>emptySet());
|
||||
addEntryToMap(entry, createTypeMarkerKey(entry.getType()), result);
|
||||
addEntryToMap(entry, createTypeNameMarkerKey(entry.getType(), entry.getName()), result);
|
||||
public void visitXmlTag(XmlTag tag) {
|
||||
super.visitXmlTag(tag);
|
||||
final String resName = tag.getAttributeValue(NAME_ATTRIBUTE_VALUE);
|
||||
|
||||
if (resName == null) {
|
||||
return;
|
||||
}
|
||||
final String tagName = tag.getName();
|
||||
final String resTypeStr;
|
||||
|
||||
if ("item".equals(tagName)) {
|
||||
resTypeStr = tag.getAttributeValue(TYPE_ATTRIBUTE_VALUE);
|
||||
}
|
||||
else {
|
||||
resTypeStr = AndroidCommonUtils.getResourceTypeByTagName(tagName);
|
||||
}
|
||||
final ResourceType resType = resTypeStr != null ? ResourceType.getEnum(resTypeStr) : null;
|
||||
|
||||
if (resType == null) {
|
||||
return;
|
||||
}
|
||||
final int offset = tag.getTextRange().getStartOffset();
|
||||
|
||||
if (resType == ResourceType.ATTR) {
|
||||
final XmlTag parentTag = tag.getParentTag();
|
||||
final String contextName = parentTag != null ? parentTag.getAttributeValue(NAME_ATTRIBUTE_VALUE) : null;
|
||||
processResourceEntry(new ResourceEntry(resTypeStr, resName, contextName != null ? contextName : ""), result, offset);
|
||||
}
|
||||
else {
|
||||
processResourceEntry(new ResourceEntry(resTypeStr, resName, ""), result, offset);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -66,14 +102,40 @@ public class AndroidValueResourcesIndex extends FileBasedIndexExtension<Resource
|
||||
}
|
||||
};
|
||||
|
||||
private static void addEntryToMap(ResourceEntry entry, ResourceEntry marker, Map<ResourceEntry, Set<ResourceEntry>> result) {
|
||||
Set<ResourceEntry> set = result.get(marker);
|
||||
private static boolean isSimilarFile(FileContent inputData) {
|
||||
if (CharArrayUtil.indexOf(inputData.getContentAsText(), "<" + RESOURCES_ROOT_TAG, 0) < 0) {
|
||||
return false;
|
||||
}
|
||||
final boolean[] ourRootTag = {false};
|
||||
|
||||
NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()), new NanoXmlUtil.IXMLBuilderAdapter() {
|
||||
@Override
|
||||
public void startElement(String name, String nsPrefix, String nsURI, String systemID, int lineNr)
|
||||
throws Exception {
|
||||
ourRootTag[0] = RESOURCES_ROOT_TAG.equals(name) && nsPrefix == null;
|
||||
stop();
|
||||
}
|
||||
});
|
||||
return ourRootTag[0];
|
||||
}
|
||||
|
||||
private static void processResourceEntry(@NotNull ResourceEntry entry,
|
||||
@NotNull Map<ResourceEntry, Set<MyResourceInfo>> result,
|
||||
int offset) {
|
||||
final MyResourceInfo info = new MyResourceInfo(entry, offset);
|
||||
result.put(entry, Collections.singleton(info));
|
||||
addEntryToMap(info, createTypeMarkerKey(entry.getType()), result);
|
||||
addEntryToMap(info, createTypeNameMarkerKey(entry.getType(), entry.getName()), result);
|
||||
}
|
||||
|
||||
private static void addEntryToMap(MyResourceInfo info, ResourceEntry marker, Map<ResourceEntry, Set<MyResourceInfo>> result) {
|
||||
Set<MyResourceInfo> set = result.get(marker);
|
||||
|
||||
if (set == null) {
|
||||
set = new HashSet<ResourceEntry>();
|
||||
set = new HashSet<MyResourceInfo>();
|
||||
result.put(marker, set);
|
||||
}
|
||||
set.add(entry);
|
||||
set.add(info);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -128,33 +190,35 @@ public class AndroidValueResourcesIndex extends FileBasedIndexExtension<Resource
|
||||
}
|
||||
};
|
||||
|
||||
private final DataExternalizer<Set<ResourceEntry>> myValueExternalizer = new DataExternalizer<Set<ResourceEntry>>() {
|
||||
private final DataExternalizer<Set<MyResourceInfo>> myValueExternalizer = new DataExternalizer<Set<MyResourceInfo>>() {
|
||||
@Override
|
||||
public void save(DataOutput out, Set<ResourceEntry> value) throws IOException {
|
||||
public void save(DataOutput out, Set<MyResourceInfo> value) throws IOException {
|
||||
out.writeInt(value.size());
|
||||
|
||||
for (ResourceEntry entry : value) {
|
||||
out.writeUTF(entry.getType());
|
||||
out.writeUTF(entry.getName());
|
||||
out.writeUTF(entry.getContext());
|
||||
for (MyResourceInfo entry : value) {
|
||||
out.writeUTF(entry.getResourceEntry().getType());
|
||||
out.writeUTF(entry.getResourceEntry().getName());
|
||||
out.writeUTF(entry.getResourceEntry().getContext());
|
||||
out.writeInt(entry.getOffset());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<ResourceEntry> read(DataInput in) throws IOException {
|
||||
public Set<MyResourceInfo> read(DataInput in) throws IOException {
|
||||
final int size = in.readInt();
|
||||
|
||||
if (size == 0) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
final Set<ResourceEntry> result = new HashSet<ResourceEntry>(size);
|
||||
final Set<MyResourceInfo> result = new HashSet<MyResourceInfo>(size);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
final String type = in.readUTF();
|
||||
final String name = in.readUTF();
|
||||
final String context = in.readUTF();
|
||||
result.add(new ResourceEntry(type, name, context));
|
||||
final int offset = in.readInt();
|
||||
result.add(new MyResourceInfo(new ResourceEntry(type, name, context), offset));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -162,13 +226,13 @@ public class AndroidValueResourcesIndex extends FileBasedIndexExtension<Resource
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ID<ResourceEntry, Set<ResourceEntry>> getName() {
|
||||
public ID<ResourceEntry, Set<MyResourceInfo>> getName() {
|
||||
return INDEX_ID;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DataIndexer<ResourceEntry, Set<ResourceEntry>, FileContent> getIndexer() {
|
||||
public DataIndexer<ResourceEntry, Set<MyResourceInfo>, FileContent> getIndexer() {
|
||||
return myIndexer;
|
||||
}
|
||||
|
||||
@@ -178,7 +242,7 @@ public class AndroidValueResourcesIndex extends FileBasedIndexExtension<Resource
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataExternalizer<Set<ResourceEntry>> getValueExternalizer() {
|
||||
public DataExternalizer<Set<MyResourceInfo>> getValueExternalizer() {
|
||||
return myValueExternalizer;
|
||||
}
|
||||
|
||||
@@ -194,6 +258,53 @@ public class AndroidValueResourcesIndex extends FileBasedIndexExtension<Resource
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
public static class MyResourceInfo {
|
||||
private final ResourceEntry myResourceEntry;
|
||||
private final int myOffset;
|
||||
|
||||
private MyResourceInfo(@NotNull ResourceEntry resourceEntry, int offset) {
|
||||
myResourceEntry = resourceEntry;
|
||||
myOffset = offset;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ResourceEntry getResourceEntry() {
|
||||
return myResourceEntry;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return myOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MyResourceInfo info = (MyResourceInfo)o;
|
||||
|
||||
if (myOffset != info.myOffset) {
|
||||
return false;
|
||||
}
|
||||
if (!myResourceEntry.equals(info.myResourceEntry)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myResourceEntry.hashCode();
|
||||
result = 31 * result + myOffset;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
-15
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.android.dom.converters;
|
||||
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.ResolveCache;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
@@ -26,12 +26,13 @@ import com.intellij.util.xml.*;
|
||||
import com.intellij.util.xml.impl.ConvertContextImpl;
|
||||
import com.intellij.util.xml.impl.DomCompletionContributor;
|
||||
import org.jetbrains.android.dom.AndroidDomUtil;
|
||||
import org.jetbrains.android.dom.resources.ResourceElement;
|
||||
import org.jetbrains.android.dom.resources.ResourceValue;
|
||||
import org.jetbrains.android.dom.wrappers.FileResourceElementWrapper;
|
||||
import org.jetbrains.android.dom.wrappers.ValueResourceElementWrapper;
|
||||
import org.jetbrains.android.dom.wrappers.LazyValueResourceElementWrapper;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.resourceManagers.ResourceManager;
|
||||
import org.jetbrains.android.resourceManagers.ValueResourceInfo;
|
||||
import org.jetbrains.android.resourceManagers.ValueResourceInfoImpl;
|
||||
import org.jetbrains.android.util.AndroidCommonUtils;
|
||||
import org.jetbrains.android.util.AndroidResourceUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -122,7 +123,7 @@ public class AndroidResourceReference extends PsiReferenceBase.Poly<XmlElement>
|
||||
collectTargets(myFacet, myResourceValue, elements, files);
|
||||
|
||||
final List<ResolveResult> result = new ArrayList<ResolveResult>();
|
||||
|
||||
|
||||
for (PsiFile target : files) {
|
||||
if (target != null) {
|
||||
final PsiFile e = new FileResourceElementWrapper(target);
|
||||
@@ -131,15 +132,15 @@ public class AndroidResourceReference extends PsiReferenceBase.Poly<XmlElement>
|
||||
}
|
||||
|
||||
for (PsiElement target : elements) {
|
||||
final PsiElement e = target instanceof NavigationItem && target instanceof XmlAttributeValue
|
||||
/*final PsiElement e = target instanceof NavigationItem && target instanceof XmlAttributeValue
|
||||
? new ValueResourceElementWrapper((XmlAttributeValue)target)
|
||||
: target;
|
||||
result.add(new PsiElementResolveResult(e));
|
||||
: target;*/
|
||||
result.add(new PsiElementResolveResult(target));
|
||||
}
|
||||
return result.toArray(new ResolveResult[result.size()]);
|
||||
}
|
||||
|
||||
private static void collectTargets(AndroidFacet facet, ResourceValue resValue, List<PsiElement> elements, List<PsiFile> files) {
|
||||
private void collectTargets(AndroidFacet facet, ResourceValue resValue, List<PsiElement> elements, List<PsiFile> files) {
|
||||
String resType = resValue.getResourceType();
|
||||
if (resType == null) {
|
||||
return;
|
||||
@@ -148,15 +149,13 @@ public class AndroidResourceReference extends PsiReferenceBase.Poly<XmlElement>
|
||||
if (manager != null) {
|
||||
String resName = resValue.getResourceName();
|
||||
if (resName != null) {
|
||||
List<ResourceElement> valueResources = manager.findValueResources(resType, resName, false);
|
||||
for (ResourceElement resource : valueResources) {
|
||||
elements.add(resource.getName().getXmlAttributeValue());
|
||||
List<ValueResourceInfoImpl> valueResources = manager.findValueResourceInfos(resType, resName, false);
|
||||
|
||||
for (final ValueResourceInfo resource : valueResources) {
|
||||
elements.add(new LazyValueResourceElementWrapper(resource, myElement));
|
||||
}
|
||||
if (resType.equals("id")) {
|
||||
List<PsiElement> idAttrs = manager.findIdDeclarations(resName);
|
||||
if (idAttrs != null) {
|
||||
elements.addAll(idAttrs);
|
||||
}
|
||||
elements.addAll(manager.findIdDeclarations(resName));
|
||||
}
|
||||
if (elements.size() == 0) {
|
||||
files.addAll(manager.findResourceFiles(resType, resName, false));
|
||||
@@ -164,4 +163,32 @@ public class AndroidResourceReference extends PsiReferenceBase.Poly<XmlElement>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
final ResolveResult[] results = multiResolve(false);
|
||||
final PsiFile psiFile = element.getContainingFile();
|
||||
final VirtualFile vFile = psiFile != null ? psiFile.getVirtualFile() : null;
|
||||
|
||||
for (ResolveResult result : results) {
|
||||
final PsiElement target = result.getElement();
|
||||
|
||||
if (element.getManager().areElementsEquivalent(target, element)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target instanceof LazyValueResourceElementWrapper && vFile != null) {
|
||||
final ValueResourceInfo info = ((LazyValueResourceElementWrapper)target).getResourceInfo();
|
||||
|
||||
if (info.getContainingFile().equals(vFile)) {
|
||||
final XmlAttributeValue realTarget = info.computeXmlElement();
|
||||
|
||||
if (element.getManager().areElementsEquivalent(realTarget, element)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package org.jetbrains.android.dom.wrappers;
|
||||
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiTarget;
|
||||
import com.intellij.psi.impl.RenameableFakePsiElement;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.android.resourceManagers.ValueResourceInfo;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class LazyValueResourceElementWrapper extends RenameableFakePsiElement implements PsiTarget {
|
||||
private final ValueResourceInfo myResourceInfo;
|
||||
private final PsiElement myParent;
|
||||
|
||||
public LazyValueResourceElementWrapper(@NotNull ValueResourceInfo resourceInfo, @NotNull PsiElement parent) {
|
||||
super(parent);
|
||||
myParent = parent;
|
||||
myResourceInfo = resourceInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return myResourceInfo.getName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
|
||||
final XmlAttributeValue element = computeElement();
|
||||
if (element == null) {
|
||||
throw new IncorrectOperationException(
|
||||
"Cannot find resource '" + myResourceInfo.getName() + "' in file " + myResourceInfo.getContainingFile().getPath());
|
||||
}
|
||||
return new ValueResourceElementWrapper(element).setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemPresentation getPresentation() {
|
||||
return new ItemPresentation() {
|
||||
@Nullable
|
||||
public String getPresentableText() {
|
||||
final String name = myResourceInfo.getName();
|
||||
final VirtualFile resDir = myResourceInfo.getContainingFile().getParent();
|
||||
if (resDir == null) {
|
||||
return name;
|
||||
}
|
||||
return name + " (" + resDir.getName() + ')';
|
||||
}
|
||||
|
||||
public String getLocationString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Icon getIcon(boolean open) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public XmlAttributeValue computeElement() {
|
||||
return myResourceInfo.computeXmlElement();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getNavigationElement() {
|
||||
final XmlAttributeValue element = myResourceInfo.computeXmlElement();
|
||||
return element != null ? element : myParent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ValueResourceInfo getResourceInfo() {
|
||||
return myResourceInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return "Android Value Resource";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement computeLazyElement(PsiElement element) {
|
||||
if (element instanceof LazyValueResourceElementWrapper) {
|
||||
element = ((LazyValueResourceElementWrapper)element).computeElement();
|
||||
}
|
||||
return element;
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -141,21 +141,21 @@ public class LocalResourceManager extends ResourceManager {
|
||||
for (ResourceType resourceType : AndroidResourceUtil.ALL_VALUE_RESOURCE_TYPES) {
|
||||
final ResourceEntry typeMarkerEntry = AndroidValueResourcesIndex.createTypeMarkerKey(resourceType.getName());
|
||||
|
||||
for (Set<ResourceEntry> entrySet : index.getValues(AndroidValueResourcesIndex.INDEX_ID, typeMarkerEntry, scope)) {
|
||||
for (ResourceEntry entry : entrySet) {
|
||||
final Collection<VirtualFile> files = index.getContainingFiles(AndroidValueResourcesIndex.INDEX_ID, entry, scope);
|
||||
|
||||
for (VirtualFile file : files) {
|
||||
index.processValues(AndroidValueResourcesIndex.INDEX_ID, typeMarkerEntry, null, new FileBasedIndex.ValueProcessor<Set<AndroidValueResourcesIndex.MyResourceInfo>>() {
|
||||
@Override
|
||||
public boolean process(VirtualFile file, Set<AndroidValueResourcesIndex.MyResourceInfo> infos) {
|
||||
for (AndroidValueResourcesIndex.MyResourceInfo info : infos) {
|
||||
Set<String> resourcesInFile = file2Types.get(file);
|
||||
|
||||
if (resourcesInFile == null) {
|
||||
resourcesInFile = new HashSet<String>();
|
||||
file2Types.put(file, resourcesInFile);
|
||||
}
|
||||
resourcesInFile.add(entry.getType());
|
||||
resourcesInFile.add(info.getResourceEntry().getType());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}, scope);
|
||||
}
|
||||
final Set<String> result = new HashSet<String>();
|
||||
|
||||
|
||||
@@ -23,11 +23,10 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
@@ -280,27 +279,28 @@ public abstract class ResourceManager {
|
||||
if (type == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final FileBasedIndex index = FileBasedIndex.getInstance();
|
||||
final ResourceEntry typeMarkerEntry = AndroidValueResourcesIndex.createTypeMarkerKey(resourceType);
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(myModule.getProject());
|
||||
|
||||
final Map<VirtualFile, Set<ResourceEntry>> file2resourceSet = new HashMap<VirtualFile, Set<ResourceEntry>>();
|
||||
for (Set<ResourceEntry> entrySet : index.getValues(AndroidValueResourcesIndex.INDEX_ID, typeMarkerEntry, scope)) {
|
||||
for (ResourceEntry entry : entrySet) {
|
||||
final Collection<VirtualFile> files = index.getContainingFiles(AndroidValueResourcesIndex.INDEX_ID, entry, scope);
|
||||
|
||||
for (VirtualFile file : files) {
|
||||
index.processValues(AndroidValueResourcesIndex.INDEX_ID, typeMarkerEntry, null, new FileBasedIndex.ValueProcessor<Set<AndroidValueResourcesIndex.MyResourceInfo>>() {
|
||||
@Override
|
||||
public boolean process(VirtualFile file, Set<AndroidValueResourcesIndex.MyResourceInfo> infos) {
|
||||
for (AndroidValueResourcesIndex.MyResourceInfo info : infos) {
|
||||
Set<ResourceEntry> resourcesInFile = file2resourceSet.get(file);
|
||||
|
||||
if (resourcesInFile == null) {
|
||||
resourcesInFile = new HashSet<ResourceEntry>();
|
||||
file2resourceSet.put(file, resourcesInFile);
|
||||
}
|
||||
resourcesInFile.add(entry);
|
||||
resourcesInFile.add(info.getResourceEntry());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}, scope);
|
||||
|
||||
final List<ResourceEntry> result = new ArrayList<ResourceEntry>();
|
||||
|
||||
for (VirtualFile file : getAllValueResourceFiles()) {
|
||||
@@ -333,43 +333,40 @@ public abstract class ResourceManager {
|
||||
|
||||
// searches only declarations such as "@+id/..."
|
||||
@NotNull
|
||||
public List<IdResourceInfo> findIdDeclarationInfos(@NotNull final String id) {
|
||||
public List<PsiElement> findIdDeclarations(@NotNull final String id) {
|
||||
if (!isResourcePublic(ResourceType.ID.getName(), id)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final List<IdResourceInfo> result = new ArrayList<IdResourceInfo>();
|
||||
final List<PsiElement> declarations = new ArrayList<PsiElement>();
|
||||
final Collection<VirtualFile> files =
|
||||
FileBasedIndex.getInstance().getContainingFiles(AndroidIdIndex.INDEX_ID, id, GlobalSearchScope.allScope(myModule.getProject()));
|
||||
final Set<VirtualFile> fileSet = new HashSet<VirtualFile>(files);
|
||||
final PsiManager psiManager = PsiManager.getInstance(myModule.getProject());
|
||||
|
||||
for (VirtualFile subdir : getResourceSubdirsToSearchIds()) {
|
||||
for (VirtualFile file : subdir.getChildren()) {
|
||||
if (fileSet.contains(file)) {
|
||||
result.add(new IdResourceInfo(id, file, myModule.getProject()));
|
||||
final PsiFile psiFile = psiManager.findFile(file);
|
||||
|
||||
if (psiFile instanceof XmlFile) {
|
||||
psiFile.accept(new XmlRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitXmlAttributeValue(XmlAttributeValue attributeValue) {
|
||||
if (AndroidResourceUtil.isIdDeclaration(attributeValue)) {
|
||||
final String idInAttr = AndroidResourceUtil.getResourceNameByReferenceText(attributeValue.getValue());
|
||||
|
||||
if (id.equals(idInAttr)) {
|
||||
declarations.add(attributeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<PsiElement> findIdDeclarations(@NotNull String id) {
|
||||
final List<IdResourceInfo> infos = findIdDeclarationInfos(id);
|
||||
|
||||
if (infos.size() == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final List<PsiElement> result = new ArrayList<PsiElement>();
|
||||
|
||||
for (IdResourceInfo info : infos) {
|
||||
final PsiElement element = info.computeXmlElement();
|
||||
|
||||
if (element != null) {
|
||||
result.add(element);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return declarations;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -451,37 +448,36 @@ public abstract class ResourceManager {
|
||||
|
||||
@NotNull
|
||||
public List<ValueResourceInfoImpl> findValueResourceInfos(@NotNull String resourceType,
|
||||
@NotNull String resourceName,
|
||||
boolean distinguishDelimetersInName) {
|
||||
@NotNull final String resourceName,
|
||||
final boolean distinguishDelimetersInName) {
|
||||
final ResourceType type = ResourceType.getEnum(resourceType);
|
||||
if (type == null) {
|
||||
if (type == null || !AndroidResourceUtil.VALUE_RESOURCE_TYPES.contains(type)) {
|
||||
// do not search for styleables and atts here because we don't want to resolve references to it
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
new HashMap<VirtualFile, Set<AndroidValueResourcesIndex.MyResourceInfo>>();
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(myModule.getProject());
|
||||
final List<Set<ResourceEntry>> values = FileBasedIndex.getInstance()
|
||||
.getValues(AndroidValueResourcesIndex.INDEX_ID, AndroidValueResourcesIndex.createTypeNameMarkerKey(resourceType, resourceName),
|
||||
scope);
|
||||
|
||||
final Set<VirtualFile> valueResourceFiles = getAllValueResourceFiles();
|
||||
final List<ValueResourceInfoImpl> result = new ArrayList<ValueResourceInfoImpl>();
|
||||
final Set<VirtualFile> valueResourceFiles = getAllValueResourceFiles();
|
||||
|
||||
for (Set<ResourceEntry> entrySet : values) {
|
||||
for (ResourceEntry entry : entrySet) {
|
||||
final String name = entry.getName();
|
||||
FileBasedIndex.getInstance()
|
||||
.processValues(AndroidValueResourcesIndex.INDEX_ID, AndroidValueResourcesIndex.createTypeNameMarkerKey(resourceType, resourceName),
|
||||
null, new FileBasedIndex.ValueProcessor<Set<AndroidValueResourcesIndex.MyResourceInfo>>() {
|
||||
@Override
|
||||
public boolean process(VirtualFile file, Set<AndroidValueResourcesIndex.MyResourceInfo> infos) {
|
||||
for (AndroidValueResourcesIndex.MyResourceInfo info : infos) {
|
||||
final String name = info.getResourceEntry().getName();
|
||||
|
||||
if (AndroidUtils.equal(resourceName, name, distinguishDelimetersInName)) {
|
||||
final Collection<VirtualFile> files =
|
||||
FileBasedIndex.getInstance().getContainingFiles(AndroidValueResourcesIndex.INDEX_ID, entry, scope);
|
||||
|
||||
for (VirtualFile file : files) {
|
||||
if (AndroidUtils.equal(resourceName, name, distinguishDelimetersInName)) {
|
||||
if (valueResourceFiles.contains(file)) {
|
||||
result.add(new ValueResourceInfoImpl(name, type, file, myModule));
|
||||
result.add(new ValueResourceInfoImpl(info.getResourceEntry().getName(), type, file, myModule, info.getOffset()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}, scope);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+36
-18
@@ -2,49 +2,67 @@ package org.jetbrains.android.resourceManagers;
|
||||
|
||||
import com.android.resources.ResourceType;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomManager;
|
||||
import org.jetbrains.android.dom.resources.Item;
|
||||
import org.jetbrains.android.dom.resources.ResourceElement;
|
||||
import org.jetbrains.android.dom.resources.Resources;
|
||||
import org.jetbrains.android.util.AndroidResourceUtil;
|
||||
import org.jetbrains.android.util.AndroidUtils;
|
||||
import org.jetbrains.android.util.AndroidCommonUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class ValueResourceInfoImpl extends ValueResourceInfoBase {
|
||||
private final Module myModule;
|
||||
private final int myOffset;
|
||||
|
||||
ValueResourceInfoImpl(@NotNull String name, @NotNull ResourceType type, @NotNull VirtualFile file, @NotNull Module module) {
|
||||
ValueResourceInfoImpl(@NotNull String name, @NotNull ResourceType type, @NotNull VirtualFile file, @NotNull Module module, int offset) {
|
||||
super(name, type, file);
|
||||
myModule = module;
|
||||
myOffset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlAttributeValue computeXmlElement() {
|
||||
final ResourceElement element = computeDomElement();
|
||||
return element != null ? element.getName().getXmlAttributeValue() : null;
|
||||
final ResourceElement resDomElement = computeDomElement();
|
||||
return resDomElement != null ? resDomElement.getName().getXmlAttributeValue() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ResourceElement computeDomElement() {
|
||||
final Resources resources = AndroidUtils.loadDomElement(myModule, myFile, Resources.class);
|
||||
if (resources == null) {
|
||||
final Project project = myModule.getProject();
|
||||
final PsiFile file = PsiManager.getInstance(project).findFile(myFile);
|
||||
|
||||
if (!(file instanceof XmlFile)) {
|
||||
return null;
|
||||
}
|
||||
final List<ResourceElement> elements = AndroidResourceUtil.getValueResourcesFromElement(myType.getName(), resources);
|
||||
final XmlTag tag = PsiTreeUtil.findElementOfClassAtOffset(file, myOffset, XmlTag.class, true);
|
||||
|
||||
for (ResourceElement element : elements) {
|
||||
final String name = element.getName().getValue();
|
||||
|
||||
if (myName.equals(name)) {
|
||||
return element;
|
||||
}
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
final DomElement domElement = DomManager.getDomManager(project).getDomElement(tag);
|
||||
if (!(domElement instanceof ResourceElement)) {
|
||||
return null;
|
||||
}
|
||||
final String resType = domElement instanceof Item
|
||||
? ((Item)domElement).getType().getStringValue()
|
||||
: AndroidCommonUtils.getResourceTypeByTagName(tag.getName());
|
||||
|
||||
if (!myType.getName().equals(resType)) {
|
||||
return null;
|
||||
}
|
||||
final ResourceElement resDomElement = (ResourceElement)domElement;
|
||||
final String resName = ((ResourceElement)domElement).getName().getStringValue();
|
||||
return myName.equals(resName) ? resDomElement : null;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/str1"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/str2"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/str100"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/str1000"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/str2500"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,11 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@strin<caret>g/str1000"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -12,6 +12,9 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import org.jetbrains.android.inspections.CreateFileResourceQuickFix;
|
||||
import org.jetbrains.android.inspections.CreateValueResourceQuickFix;
|
||||
|
||||
@@ -405,26 +408,67 @@ public class AndroidLayoutDomTest extends AndroidDomTest {
|
||||
toTestCompletion(getTestName(true) + ".xml", getTestName(true) + "_after.xml");
|
||||
}
|
||||
|
||||
/*public void testCustomAttrsPerformance() throws Throwable {
|
||||
public void testCustomAttrsPerformance() throws Throwable {
|
||||
myFixture.copyFileToProject("dom/resources/bigfile.xml", "res/values/bigfile.xml");
|
||||
myFixture.copyFileToProject("dom/resources/bigattrs.xml", "res/values/bigattrs.xml");
|
||||
myFixture.copyFileToProject("dom/resources/bigattrs.xml", "res/values/bigattrs1.xml");
|
||||
myFixture.copyFileToProject("dom/resources/bigattrs.xml", "res/values/bigattrs2.xml");
|
||||
myFixture.copyFileToProject("dom/resources/bigattrs.xml", "res/values/bigattrs3.xml");
|
||||
String path = copyFileToProject("bigfile.xml");
|
||||
VirtualFile f = myFixture.findFileInTempDir(path);
|
||||
VirtualFile f = copyFileToProject("bigfile.xml");
|
||||
myFixture.configureFromExistingVirtualFile(f);
|
||||
IdeaTestUtil.assertTiming("", 800, new Runnable() {
|
||||
|
||||
PlatformTestUtil.startPerformanceTest("android custom attrs highlighting is slow", 800, new ThrowableRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myFixture.doHighlighting();
|
||||
}
|
||||
catch (Exception e) {
|
||||
public void run() throws Throwable {
|
||||
myFixture.doHighlighting();
|
||||
}
|
||||
}).attempts(2).cpuBound().usesAllCPUCores().assertTiming();
|
||||
}
|
||||
|
||||
public void testResourceHighlightingPerformance() throws Throwable {
|
||||
doCopyManyStrings();
|
||||
final VirtualFile f = copyFileToProject(getTestName(true) + ".xml");
|
||||
myFixture.configureFromExistingVirtualFile(f);
|
||||
PlatformTestUtil.startPerformanceTest("android highlighting is slow", 400, new ThrowableRunnable() {
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
myFixture.doHighlighting();
|
||||
}
|
||||
}).attempts(2).cpuBound().usesAllCPUCores().assertTiming();
|
||||
}
|
||||
|
||||
public void testResourceNavigationPerformance() throws Throwable {
|
||||
doCopyManyStrings();
|
||||
final VirtualFile f = copyFileToProject(getTestName(true) + ".xml");
|
||||
myFixture.configureFromExistingVirtualFile(f);
|
||||
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
|
||||
final List<PsiElement> navElements = new ArrayList<PsiElement>();
|
||||
|
||||
// warm
|
||||
myFixture.doHighlighting();
|
||||
|
||||
PlatformTestUtil.startPerformanceTest("android highlighting is slow", 7000, new ThrowableRunnable() {
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
final PsiReference reference = TargetElementUtilBase.findReference(myFixture.getEditor(), myFixture.getCaretOffset());
|
||||
final ResolveResult[] results = ((PsiPolyVariantReference)reference).multiResolve(false);
|
||||
for (ResolveResult result : results) {
|
||||
final PsiElement navElement = result.getElement().getNavigationElement();
|
||||
assertInstanceOf(navElement, XmlAttributeValue.class);
|
||||
navElements.add(navElement);
|
||||
}
|
||||
}
|
||||
});
|
||||
}*/
|
||||
}).attempts(1).cpuBound().usesAllCPUCores().assertTiming();
|
||||
assertEquals(31, navElements.size());
|
||||
}
|
||||
|
||||
private void doCopyManyStrings() {
|
||||
myFixture.copyFileToProject(testFolder + "/many_strings.xml", "res/values/strings.xml");
|
||||
for (int i = 0; i < 30; i++) {
|
||||
myFixture.copyFileToProject(testFolder + "/many_strings.xml", "res/values-" + Integer.toString(i) + "/strings.xml");
|
||||
}
|
||||
}
|
||||
|
||||
public void testViewClassReference() throws Throwable {
|
||||
VirtualFile file = myFixture.copyFileToProject(testFolder + "/vcr.xml", getPathToCopy("vcr.xml"));
|
||||
|
||||
@@ -30,9 +30,9 @@ import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.refactoring.actions.InlineAction;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import org.jetbrains.android.dom.wrappers.LazyValueResourceElementWrapper;
|
||||
import org.jetbrains.android.inspections.CreateValueResourceQuickFix;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -252,7 +252,8 @@ public class AndroidValueResourcesTest extends AndroidDomTest {
|
||||
PsiReference rootReference = psiFile.findReferenceAt(rootOffset);
|
||||
assertNotNull(rootReference);
|
||||
PsiElement element = rootReference.resolve();
|
||||
assertTrue("Must be PsiClass reference", element instanceof XmlAttributeValue);
|
||||
assertInstanceOf(element, LazyValueResourceElementWrapper.class);
|
||||
assertNotNull(((LazyValueResourceElementWrapper)element).computeElement());
|
||||
}
|
||||
|
||||
// see getPathToCopy()
|
||||
|
||||
Reference in New Issue
Block a user