Search in sources :

Example 46 with DomElement

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;
}
Also used : DomElement(com.intellij.util.xml.DomElement) LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) DomManager(com.intellij.util.xml.DomManager) XmlTag(com.intellij.psi.xml.XmlTag)

Example 47 with DomElement

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);
            }
        }
    }
}
Also used : ResourceElement(org.jetbrains.android.dom.resources.ResourceElement) DomElement(com.intellij.util.xml.DomElement) XmlTagValue(com.intellij.psi.xml.XmlTagValue) PsiReferenceExpression(com.intellij.psi.PsiReferenceExpression) ResourceReferenceType(com.android.tools.idea.AndroidPsiUtils.ResourceReferenceType) ResourceType(com.android.resources.ResourceType) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) XmlTag(com.intellij.psi.xml.XmlTag)

Example 48 with DomElement

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);
}
Also used : Project(com.intellij.openapi.project.Project) DomElement(com.intellij.util.xml.DomElement) LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) XmlFile(com.intellij.psi.xml.XmlFile) DomManager(com.intellij.util.xml.DomManager) XmlResourceElement(org.jetbrains.android.dom.xml.XmlResourceElement) PsiFile(com.intellij.psi.PsiFile) Nullable(org.jetbrains.annotations.Nullable)

Example 49 with DomElement

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);
        }
    }
}
Also used : ResourceElement(org.jetbrains.android.dom.resources.ResourceElement) ResourceType(com.android.resources.ResourceType) ResourceManager(org.jetbrains.android.resourceManagers.ResourceManager) LocalResourceManager(org.jetbrains.android.resourceManagers.LocalResourceManager) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) Predicate(com.google.common.base.Predicate) Project(com.intellij.openapi.project.Project) DomElement(com.intellij.util.xml.DomElement) XmlElement(com.intellij.psi.xml.XmlElement) Style(org.jetbrains.android.dom.resources.Style) XmlTag(com.intellij.psi.xml.XmlTag) LazyValueResourceElementWrapper(org.jetbrains.android.dom.wrappers.LazyValueResourceElementWrapper) ValueResourceElementWrapper(org.jetbrains.android.dom.wrappers.ValueResourceElementWrapper)

Example 50 with DomElement

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);
    }
}
Also used : DomElement(com.intellij.util.xml.DomElement) XmlTag(com.intellij.psi.xml.XmlTag)

Aggregations

DomElement (com.intellij.util.xml.DomElement)97 XmlTag (com.intellij.psi.xml.XmlTag)34 PsiElement (com.intellij.psi.PsiElement)19 Nullable (org.jetbrains.annotations.Nullable)19 NotNull (org.jetbrains.annotations.NotNull)15 Project (com.intellij.openapi.project.Project)11 PsiFile (com.intellij.psi.PsiFile)11 XmlFile (com.intellij.psi.xml.XmlFile)11 XmlAttribute (com.intellij.psi.xml.XmlAttribute)10 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)9 ArrayList (java.util.ArrayList)8 LayoutViewElement (org.jetbrains.android.dom.layout.LayoutViewElement)7 ResourceElement (org.jetbrains.android.dom.resources.ResourceElement)6 DomManager (com.intellij.util.xml.DomManager)5 Style (org.jetbrains.android.dom.resources.Style)5 AntDomTarget (com.intellij.lang.ant.dom.AntDomTarget)4 XmlElement (com.intellij.psi.xml.XmlElement)4 DomElementProblemDescriptor (com.intellij.util.xml.highlighting.DomElementProblemDescriptor)4 LookupElement (com.intellij.codeInsight.lookup.LookupElement)3 TextRange (com.intellij.openapi.util.TextRange)3