use of com.intellij.psi.xml.XmlAttributeValue in project android by JetBrains.
the class PackageClassConverter method createReferences.
@NotNull
@Override
public PsiReference[] createReferences(GenericDomValue<PsiClass> value, final PsiElement element, ConvertContext context) {
assert element instanceof XmlAttributeValue;
final XmlAttributeValue attrValue = (XmlAttributeValue) element;
final String strValue = attrValue.getValue();
final boolean startsWithPoint = strValue.startsWith(".");
final int start = attrValue.getValueTextRange().getStartOffset() - attrValue.getTextRange().getStartOffset();
final DomElement domElement = context.getInvocationElement();
final String manifestPackage = getManifestPackage(context);
final ExtendClass extendClassAnnotation = domElement.getAnnotation(ExtendClass.class);
final String[] extendClassesNames = extendClassAnnotation != null ? new String[] { extendClassAnnotation.value() } : myExtendClassesNames;
final boolean inModuleOnly = domElement.getAnnotation(CompleteNonModuleClass.class) == null;
AndroidFacet facet = AndroidFacet.getInstance(context);
// If the source XML file is contained within the test folders, we'll also allow to resolve test classes
final boolean isTestFile = facet != null && isTestFile(facet, element.getContainingFile().getVirtualFile());
if (strValue.isEmpty()) {
return PsiReference.EMPTY_ARRAY;
}
final List<PsiReference> result = new ArrayList<>();
final Module module = context.getModule();
/**
* Using inner class here as opposed to anonymous one as with anonymous class it wouldn't be possible to access {@code myPartStart} later
*/
class CustomConsumer implements Consumer<Integer> {
int myPartStart = 0;
private boolean myIsPackage = true;
@Override
public void consume(Integer index) {
if (index > myPartStart) {
final TextRange range = new TextRange(start + myPartStart, start + index);
final MyReference reference = new MyReference(element, range, manifestPackage, startsWithPoint, start, myIsPackage, module, extendClassesNames, inModuleOnly, isTestFile);
result.add(reference);
}
myPartStart = index + 1;
}
}
final CustomConsumer consumer = new CustomConsumer();
AndroidTextUtils.forEachOccurrence(strValue, '.', consumer);
consumer.myIsPackage = false;
AndroidTextUtils.forEachOccurrence(strValue, '$', consumer.myPartStart, consumer);
consumer.consume(strValue.length());
return result.toArray(new PsiReference[result.size()]);
}
use of com.intellij.psi.xml.XmlAttributeValue in project android by JetBrains.
the class AndroidXmlSpellcheckingStrategy method isAttributeValueContext.
private static boolean isAttributeValueContext(@NotNull PsiElement element) {
if (!(element instanceof XmlAttributeValue)) {
return false;
}
PsiElement parent = element.getParent();
parent = parent != null ? parent.getParent() : null;
if (!(parent instanceof XmlTag)) {
return false;
}
DomElement domElement = DomManager.getDomManager(element.getProject()).getDomElement((XmlTag) parent);
if (domElement instanceof AndroidDomElement) {
return inEnglish(element);
}
return false;
}
use of com.intellij.psi.xml.XmlAttributeValue in project android by JetBrains.
the class AndroidTestBase method appendElementDescription.
/** Appends a description of the given element, suitable as unit test golden file output */
public static void appendElementDescription(@NotNull StringBuilder sb, @NotNull PsiElement element) {
if (element instanceof LazyValueResourceElementWrapper) {
LazyValueResourceElementWrapper wrapper = (LazyValueResourceElementWrapper) element;
XmlAttributeValue value = wrapper.computeElement();
if (value != null) {
element = value;
}
}
PsiFile file = element.getContainingFile();
int offset = element.getTextOffset();
TextRange segment = element.getTextRange();
appendSourceDescription(sb, file, offset, segment);
}
use of com.intellij.psi.xml.XmlAttributeValue in project android by JetBrains.
the class MigrateDrawableToMipmapFix method apply.
@Override
public void apply(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull AndroidQuickfixContexts.Context context) {
Project project = startElement.getProject();
AndroidFacet facet = AndroidFacet.getInstance(startElement);
if (facet == null) {
return;
}
final List<PsiFile> bitmaps = Lists.newArrayList();
final Set<PsiElement> references = Sets.newHashSet();
GlobalSearchScope useScope = GlobalSearchScope.projectScope(project);
ProjectResourceRepository projectResources = facet.getProjectResources(true);
List<ResourceItem> resourceItems = projectResources.getResourceItem(myUrl.type, myUrl.name);
if (resourceItems != null) {
for (ResourceItem item : resourceItems) {
PsiFile file = LocalResourceRepository.getItemPsiFile(project, item);
if (file == null) {
continue;
}
bitmaps.add(file);
Iterable<PsiReference> allReferences = SearchUtils.findAllReferences(file, useScope);
for (PsiReference next : allReferences) {
PsiElement element = next.getElement();
if (element != null) {
references.add(element);
}
}
}
}
PsiField[] resourceFields = AndroidResourceUtil.findResourceFields(facet, ResourceType.DRAWABLE.getName(), myUrl.name, true);
if (resourceFields.length == 1) {
Iterable<PsiReference> allReferences = SearchUtils.findAllReferences(resourceFields[0], useScope);
for (PsiReference next : allReferences) {
PsiElement element = next.getElement();
if (element != null) {
references.add(element);
}
}
}
Set<PsiFile> applicableFiles = Sets.newHashSet();
applicableFiles.addAll(bitmaps);
for (PsiElement element : references) {
PsiFile containingFile = element.getContainingFile();
if (containingFile != null) {
applicableFiles.add(containingFile);
}
}
WriteCommandAction<Void> action = new WriteCommandAction<Void>(project, "Migrate Drawable to Bitmap", applicableFiles.toArray(new PsiFile[applicableFiles.size()])) {
@Override
protected void run(@NotNull Result<Void> result) throws Throwable {
// Move each drawable bitmap from drawable-my-qualifiers to bitmap-my-qualifiers
for (PsiFile bitmap : bitmaps) {
VirtualFile file = bitmap.getVirtualFile();
if (file == null) {
continue;
}
VirtualFile parent = file.getParent();
if (parent == null) {
// shouldn't happen for bitmaps found in the resource repository
continue;
}
if (file.getFileType() == StdFileTypes.XML && parent.getName().startsWith(FD_RES_VALUES)) {
// Resource alias rather than an actual drawable XML file: update the type reference instead
XmlFile xmlFile = (XmlFile) bitmap;
XmlTag root = xmlFile.getRootTag();
if (root != null) {
for (XmlTag item : root.getSubTags()) {
String name = item.getAttributeValue(ATTR_NAME);
if (myUrl.name.equals(name)) {
if (ResourceType.DRAWABLE.getName().equals(item.getName())) {
item.setName(ResourceType.MIPMAP.getName());
} else if (ResourceType.DRAWABLE.getName().equals(item.getAttributeValue(ATTR_TYPE))) {
item.setAttribute(ATTR_TYPE, ResourceType.MIPMAP.getName());
}
}
}
}
// Don't move the file
continue;
}
VirtualFile res = parent.getParent();
if (res == null) {
// shouldn't happen for bitmaps found in the resource repository
continue;
}
FolderConfiguration configuration = FolderConfiguration.getConfigForFolder(parent.getName());
if (configuration == null) {
continue;
}
String targetFolderName = configuration.getFolderName(ResourceFolderType.MIPMAP);
VirtualFile targetFolder = res.findChild(targetFolderName);
if (targetFolder == null) {
targetFolder = res.createChildDirectory(this, targetFolderName);
}
file.move(this, targetFolder);
}
// Update references
for (PsiElement reference : references) {
if (reference instanceof XmlAttributeValue) {
// Convert @drawable/foo references to @mipmap/foo
XmlAttributeValue value = (XmlAttributeValue) reference;
XmlAttribute attribute = (XmlAttribute) value.getParent();
attribute.setValue(ResourceUrl.create(ResourceType.MIPMAP, myUrl.name, false, false).toString());
} else if (reference instanceof PsiReferenceExpression) {
// Convert R.drawable.foo references to R.mipmap.foo
PsiReferenceExpression inner = (PsiReferenceExpression) reference;
PsiExpression qualifier = inner.getQualifierExpression();
if (qualifier instanceof PsiReferenceExpression) {
PsiReferenceExpression outer = (PsiReferenceExpression) qualifier;
if (outer.getReferenceNameElement() instanceof PsiIdentifier) {
PsiIdentifier identifier = (PsiIdentifier) outer.getReferenceNameElement();
if (ResourceType.DRAWABLE.getName().equals(identifier.getText())) {
Project project = reference.getProject();
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
PsiIdentifier newIdentifier = elementFactory.createIdentifier(ResourceType.MIPMAP.getName());
identifier.replace(newIdentifier);
}
}
}
}
}
}
};
action.execute();
}
use of com.intellij.psi.xml.XmlAttributeValue in project android by JetBrains.
the class AndroidComponentSafeDeleteProcessor method findUsages.
@Override
public NonCodeUsageSearchInfo findUsages(@NotNull PsiElement element, @NotNull PsiElement[] allElementsToDelete, @NotNull List<UsageInfo> result) {
final ArrayList<UsageInfo> usages = new ArrayList<UsageInfo>();
final NonCodeUsageSearchInfo info = getBaseHandler().findUsages(element, allElementsToDelete, usages);
if (info == null) {
return info;
}
assert element instanceof PsiClass;
final PsiClass componentClass = (PsiClass) element;
final AndroidAttributeValue<PsiClass> declaration = AndroidDomUtil.findComponentDeclarationInManifest(componentClass);
if (declaration == null) {
return info;
}
final XmlAttributeValue declarationAttributeValue = declaration.getXmlAttributeValue();
for (UsageInfo usage : usages) {
if (declarationAttributeValue != usage.getElement()) {
result.add(usage);
}
}
return info;
}
Aggregations