use of com.intellij.util.xml.DomElement in project android by JetBrains.
the class AndroidExtractAsIncludeAction method isEnabledForPsiRange.
@Override
protected boolean isEnabledForPsiRange(@NotNull PsiElement from, @Nullable PsiElement to) {
final DomManager domManager = DomManager.getDomManager(from.getProject());
PsiElement e = from;
boolean containsViewElement = false;
while (e != null) {
if (e instanceof XmlTag) {
final DomElement domElement = domManager.getDomElement((XmlTag) e);
if (!isSuitableDomElement(domElement)) {
return false;
}
if (domElement instanceof LayoutViewElement) {
containsViewElement = true;
}
}
if (e == to) {
break;
}
e = e.getNextSibling();
}
return containsViewElement;
}
use of com.intellij.util.xml.DomElement in project android by JetBrains.
the class AndroidColorAnnotator method annotate.
@Override
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
if (element instanceof XmlTag) {
XmlTag tag = (XmlTag) element;
String tagName = tag.getName();
if ((ResourceType.COLOR.getName().equals(tagName) || ResourceType.DRAWABLE.getName().equals(tagName) || ResourceType.MIPMAP.getName().equals(tagName))) {
DomElement domElement = DomManager.getDomManager(element.getProject()).getDomElement(tag);
if (domElement instanceof ResourceElement || ApplicationManager.getApplication().isUnitTestMode()) {
String value = tag.getValue().getText().trim();
annotateXml(element, holder, value);
}
} else if (TAG_ITEM.equals(tagName)) {
XmlTagValue value = tag.getValue();
String text = value.getText();
annotateXml(element, holder, text);
}
} else if (element instanceof XmlAttributeValue) {
XmlAttributeValue v = (XmlAttributeValue) element;
String value = v.getValue();
if (value == null || value.isEmpty()) {
return;
}
annotateXml(element, holder, value);
} else if (element instanceof PsiReferenceExpression) {
ResourceReferenceType referenceType = AndroidPsiUtils.getResourceReferenceType(element);
if (referenceType != ResourceReferenceType.NONE) {
// (isResourceReference will return true for both "R.drawable.foo" and the foo literal leaf in the
// same expression, which would result in both elements getting annotated and the icon showing up
// in the gutter twice. Instead we only count the outer one.
ResourceType type = AndroidPsiUtils.getResourceType(element);
if (type == ResourceType.COLOR || type == ResourceType.DRAWABLE || type == ResourceType.MIPMAP) {
String name = AndroidPsiUtils.getResourceName(element);
annotateResourceReference(type, holder, element, name, referenceType == ResourceReferenceType.FRAMEWORK);
}
}
}
}
use of com.intellij.util.xml.DomElement in project android by JetBrains.
the class AndroidDomElementDescriptorProvider method getDomElementAndBaseClassQName.
@Nullable
public static Pair<AndroidDomElement, String> getDomElementAndBaseClassQName(@NotNull XmlTag tag) {
final PsiFile file = tag.getContainingFile();
if (!(file instanceof XmlFile))
return null;
Project project = file.getProject();
if (project.isDefault())
return null;
final DomManager domManager = DomManager.getDomManager(project);
if (domManager.getFileElement((XmlFile) file, AndroidDomElement.class) == null)
return null;
final DomElement domElement = domManager.getDomElement(tag);
if (!(domElement instanceof AndroidDomElement)) {
return null;
}
String className = null;
if (domElement instanceof LayoutViewElement) {
className = AndroidUtils.VIEW_CLASS_NAME;
} else if (domElement instanceof XmlResourceElement) {
className = SdkConstants.CLASS_PREFERENCE;
}
return Pair.create((AndroidDomElement) domElement, className);
}
use of com.intellij.util.xml.DomElement in project android by JetBrains.
the class AndroidResourceRenameResourceProcessor method prepareValueResourceRenaming.
private static void prepareValueResourceRenaming(PsiElement element, String newName, Map<PsiElement, String> allRenames, final AndroidFacet facet) {
ResourceManager manager = facet.getLocalResourceManager();
XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
assert tag != null;
String type = manager.getValueResourceType(tag);
assert type != null;
Project project = tag.getProject();
DomElement domElement = DomManager.getDomManager(project).getDomElement(tag);
assert domElement instanceof ResourceElement;
String name = ((ResourceElement) domElement).getName().getValue();
assert name != null;
List<ResourceElement> resources = manager.findValueResources(type, name);
for (ResourceElement resource : resources) {
XmlElement xmlElement = resource.getName().getXmlAttributeValue();
if (!element.getManager().areElementsEquivalent(element, xmlElement)) {
allRenames.put(xmlElement, newName);
}
}
if (getResourceType(element) == ResourceType.STYLE) {
// For styles, try also to find child styles defined by name (i.e. "ParentName.StyleName") and add them
// to the rename list. This will allow the rename processor to also handle the references to those. For example,
// If you rename "MyTheme" and your manifest theme is "MyTheme.NoActionBar", this will make sure that
// the reference from the manifest is also updated by adding "MyTheme.NoActionBar" to the rename list.
// We iterate the styles in order to cascade any changes to children down the hierarchy.
// List of styles that will be renamed.
HashSet<String> renamedStyles = Sets.newHashSet();
renamedStyles.add(name);
final String stylePrefix = name + ".";
Collection<String> renameCandidates;
ResourceType resourceType = ResourceType.getEnum(type);
if (resourceType == null) {
renameCandidates = Collections.emptyList();
} else {
renameCandidates = Collections2.filter(manager.getResourceNames(resourceType), new Predicate<String>() {
@Override
public boolean apply(String input) {
return input.startsWith(stylePrefix);
}
});
}
for (String resourceName : ORDER_BY_LENGTH.sortedCopy(renameCandidates)) {
// resourceName.lastIndexOf will never return -1 because we've filtered all names that
// do not contain stylePrefix
String parentName = resourceName.substring(0, resourceName.lastIndexOf('.'));
if (!renamedStyles.contains(parentName)) {
// This resource's parent wasn't affected by the rename
continue;
}
for (ResourceElement resource : manager.findValueResources(type, resourceName)) {
if (!(resource instanceof Style) || ((Style) resource).getParentStyle().getXmlAttributeValue() != null) {
// This element is not a style or does have an explicit parent so we do not rename it.
continue;
}
XmlAttributeValue xmlElement = resource.getName().getXmlAttributeValue();
if (xmlElement != null) {
String newStyleName = newName + StringUtil.trimStart(resourceName, name);
allRenames.put(new ValueResourceElementWrapper(xmlElement), newStyleName);
renamedStyles.add(resourceName);
}
}
}
}
PsiField[] resFields = AndroidResourceUtil.findResourceFieldsForValueResource(tag, false);
for (PsiField resField : resFields) {
String escaped = AndroidResourceUtil.getFieldNameByResourceName(newName);
allRenames.put(resField, escaped);
}
// Also rename the dependent fields, e.g. if you rename <declare-styleable name="Foo">,
// we have to rename not just R.styleable.Foo but the also R.styleable.Foo_* attributes
PsiField[] styleableFields = AndroidResourceUtil.findStyleableAttributeFields(tag, false);
if (styleableFields.length > 0) {
String tagName = tag.getName();
boolean isDeclareStyleable = tagName.equals(TAG_DECLARE_STYLEABLE);
boolean isAttr = !isDeclareStyleable && tagName.equals(TAG_ATTR) && tag.getParentTag() != null;
assert isDeclareStyleable || isAttr;
String style = isAttr ? tag.getParentTag().getAttributeValue(ATTR_NAME) : null;
for (PsiField resField : styleableFields) {
String fieldName = resField.getName();
String newAttributeName;
if (isDeclareStyleable && fieldName.startsWith(name)) {
newAttributeName = newName + fieldName.substring(name.length());
} else if (isAttr && style != null) {
newAttributeName = style + '_' + newName;
} else {
newAttributeName = name;
}
String escaped = AndroidResourceUtil.getFieldNameByResourceName(newAttributeName);
allRenames.put(resField, escaped);
}
}
}
use of com.intellij.util.xml.DomElement in project android by JetBrains.
the class StructureUtils method acceptChildrenInOrder.
/**
* {@link DomElement#acceptChildren(DomElementVisitor)} doesn't iterate over children in order
* they appear in the XML file. This is a helper method that iterates over subtags of given
* element in the order of appearance and accepts a visitor for each one of them that correspond
* to a DOM element
*/
public static void acceptChildrenInOrder(@NotNull DomElement element, @NotNull DomElementVisitor visitor) {
final XmlTag tag = element.getXmlTag();
for (XmlTag xmlTag : tag.getSubTags()) {
final DomElement child = element.getManager().getDomElement(xmlTag);
if (child == null) {
return;
}
child.accept(visitor);
}
}
Aggregations