Search in sources :

Example 71 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project android by JetBrains.

the class RecipeMergeUtils method mergeResourceFile.

/**
   * Merges the given resource file contents into the given resource file
   */
@SuppressWarnings("StatementWithEmptyBody")
public static String mergeResourceFile(@NotNull RenderingContext context, @NotNull String targetXml, @NotNull String sourceXml, @NotNull String fileName, @Nullable ResourceFolderType folderType) {
    XmlFile targetPsiFile = (XmlFile) PsiFileFactory.getInstance(context.getProject()).createFileFromText("targetFile", XMLLanguage.INSTANCE, StringUtil.convertLineSeparators(targetXml));
    XmlFile sourcePsiFile = (XmlFile) PsiFileFactory.getInstance(context.getProject()).createFileFromText("sourceFile", XMLLanguage.INSTANCE, StringUtil.convertLineSeparators(sourceXml));
    XmlTag root = targetPsiFile.getDocument().getRootTag();
    assert root != null : "Cannot find XML root in target: " + targetXml;
    XmlAttribute[] attributes = sourcePsiFile.getRootTag().getAttributes();
    for (XmlAttribute attr : attributes) {
        if (attr.getNamespacePrefix().equals(XMLNS_PREFIX)) {
            root.setAttribute(attr.getName(), attr.getValue());
        }
    }
    List<XmlTagChild> prependElements = Lists.newArrayList();
    XmlText indent = null;
    if (folderType == ResourceFolderType.VALUES) {
        // Try to merge items of the same name
        Map<String, XmlTag> old = Maps.newHashMap();
        for (XmlTag newSibling : root.getSubTags()) {
            old.put(getResourceId(newSibling), newSibling);
        }
        for (PsiElement child : sourcePsiFile.getRootTag().getChildren()) {
            if (child instanceof XmlComment) {
                if (indent != null) {
                    prependElements.add(indent);
                }
                prependElements.add((XmlTagChild) child);
            } else if (child instanceof XmlText) {
                indent = (XmlText) child;
            } else if (child instanceof XmlTag) {
                XmlTag subTag = (XmlTag) child;
                String mergeStrategy = subTag.getAttributeValue(MERGE_ATTR_STRATEGY);
                subTag.setAttribute(MERGE_ATTR_STRATEGY, null);
                // remove the space left by the deleted attribute
                CodeStyleManager.getInstance(context.getProject()).reformat(subTag);
                String name = getResourceId(subTag);
                XmlTag replace = name != null ? old.get(name) : null;
                if (replace != null) {
                    // default!
                    if (MERGE_ATTR_STRATEGY_REPLACE.equals(mergeStrategy)) {
                        child = replace.replace(child);
                        // When we're replacing, the line is probably already indented. Skip the initial indent
                        if (child.getPrevSibling() instanceof XmlText && prependElements.get(0) instanceof XmlText) {
                            prependElements.remove(0);
                            // If we're adding something we'll need a newline/indent after it
                            if (!prependElements.isEmpty()) {
                                prependElements.add(indent);
                            }
                        }
                        for (XmlTagChild element : prependElements) {
                            root.addBefore(element, child);
                        }
                    } else if (MERGE_ATTR_STRATEGY_PRESERVE.equals(mergeStrategy)) {
                    // Preserve the existing value.
                    } else if (replace.getText().trim().equals(child.getText().trim())) {
                    // There are no differences, do not issue a warning.
                    } else {
                        // No explicit directive given, preserve the original value by default.
                        context.getWarnings().add(String.format("Ignoring conflict for the value: %1$s wanted: \"%2$s\" but it already is: \"%3$s\" in the file: %4$s", name, child.getText(), replace.getText(), fileName));
                    }
                } else {
                    if (indent != null) {
                        prependElements.add(indent);
                    }
                    subTag = root.addSubTag(subTag, false);
                    for (XmlTagChild element : prependElements) {
                        root.addBefore(element, subTag);
                    }
                }
                prependElements.clear();
            }
        }
    } else {
        // at the end.
        for (PsiElement child : sourcePsiFile.getRootTag().getChildren()) {
            if (child instanceof XmlTag) {
                root.addSubTag((XmlTag) child, false);
            }
        }
    }
    return targetPsiFile.getText();
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) PsiElement(com.intellij.psi.PsiElement)

Example 72 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project android by JetBrains.

the class AndroidFindStyleApplicationsProcessor method isPossibleApplicationOfStyle.

private boolean isPossibleApplicationOfStyle(XmlTag candidate) {
    final DomElement domCandidate = DomManager.getDomManager(myProject).getDomElement(candidate);
    if (!(domCandidate instanceof LayoutViewElement)) {
        return false;
    }
    final LayoutViewElement candidateView = (LayoutViewElement) domCandidate;
    final Map<Pair<String, String>, String> attrsInCandidateMap = new HashMap<Pair<String, String>, String>();
    final List<XmlAttribute> attrsInCandidate = AndroidExtractStyleAction.getExtractableAttributes(candidate);
    if (attrsInCandidate.size() < myAttrMap.size()) {
        return false;
    }
    for (XmlAttribute attribute : attrsInCandidate) {
        final String attrValue = attribute.getValue();
        if (attrValue != null) {
            attrsInCandidateMap.put(Pair.create(attribute.getNamespace(), attribute.getLocalName()), attrValue);
        }
    }
    for (Map.Entry<AndroidAttributeInfo, String> entry : myAttrMap.entrySet()) {
        final String ns = entry.getKey().getNamespace();
        final String name = entry.getKey().getName();
        final String value = entry.getValue();
        final String valueInCandidate = attrsInCandidateMap.get(Pair.create(ns, name));
        if (valueInCandidate == null || !valueInCandidate.equals(value)) {
            return false;
        }
    }
    if (candidateView.getStyle().getStringValue() != null) {
        if (myParentStyleNameAttrValue == null) {
            return false;
        }
        final PsiElement styleNameAttrValueForTag = getStyleNameAttrValueForTag(candidateView);
        if (styleNameAttrValueForTag == null || !myParentStyleNameAttrValue.equals(styleNameAttrValueForTag)) {
            return false;
        }
    } else if (myParentStyleNameAttrValue != null) {
        return false;
    }
    return true;
}
Also used : DomElement(com.intellij.util.xml.DomElement) LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) XmlAttribute(com.intellij.psi.xml.XmlAttribute) HashMap(com.intellij.util.containers.HashMap) HashMap(com.intellij.util.containers.HashMap) PsiElement(com.intellij.psi.PsiElement) Pair(com.intellij.openapi.util.Pair)

Example 73 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.

the class IconsReferencesContributor method registerReferenceProviders.

@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
    final PsiJavaElementPattern.Capture<PsiLiteralExpression> presentationAnno = literalExpression().annotationParam("com.intellij.ide.presentation.Presentation", "icon");
    registrar.registerReferenceProvider(presentationAnno, new PsiReferenceProvider() {

        @NotNull
        @Override
        public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull ProcessingContext context) {
            if (!PsiUtil.isPluginProject(element.getProject()))
                return PsiReference.EMPTY_ARRAY;
            return new PsiReference[] { new PsiReferenceBase<PsiElement>(element, true) {

                @Override
                public PsiElement resolve() {
                    String value = (String) ((PsiLiteralExpression) element).getValue();
                    if (value != null) {
                        List<String> path = StringUtil.split(value, ".");
                        if (path.size() > 1 && path.get(0).endsWith("Icons")) {
                            Project project = element.getProject();
                            PsiClass cur = findIconClass(project, path.get(0));
                            if (cur == null) {
                                return null;
                            }
                            for (int i = 1; i < path.size() - 1; i++) {
                                cur = cur.findInnerClassByName(path.get(i), false);
                                if (cur == null) {
                                    return null;
                                }
                            }
                            return cur.findFieldByName(path.get(path.size() - 1), false);
                        }
                    }
                    return null;
                }

                @Override
                public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
                    PsiElement field = resolve();
                    if (field instanceof PsiField) {
                        String fqn = ((PsiField) field).getContainingClass().getQualifiedName();
                        if (fqn.startsWith("com.intellij.icons.")) {
                            return replace(newElementName, fqn, "com.intellij.icons.", element);
                        }
                        if (fqn.startsWith("icons.")) {
                            return replace(newElementName, fqn, "icons.", element);
                        }
                    }
                    return super.handleElementRename(newElementName);
                }

                @Override
                public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
                    if (element instanceof PsiField) {
                        String fqn = ((PsiField) element).getContainingClass().getQualifiedName();
                        String newElementName = ((PsiField) element).getName();
                        if (fqn.startsWith("com.intellij.icons.")) {
                            return replace(newElementName, fqn, "com.intellij.icons.", getElement());
                        }
                        if (fqn.startsWith("icons.")) {
                            return replace(newElementName, fqn, "icons.", getElement());
                        }
                    }
                    return super.bindToElement(element);
                }

                private PsiElement replace(String newElementName, String fqn, String pckg, PsiElement container) {
                    String newValue = "\"" + fqn.substring(pckg.length()) + "." + newElementName + "\"";
                    return getElement().replace(JavaPsiFacade.getElementFactory(container.getProject()).createExpressionFromText(newValue, container.getParent()));
                }

                @NotNull
                @Override
                public Object[] getVariants() {
                    return EMPTY_ARRAY;
                }
            } };
        }
    });
    final PsiMethodPattern method = psiMethod().withName("findIcon", "getIcon").definedInClass(IconLoader.class.getName());
    final PsiJavaElementPattern.Capture<PsiLiteralExpression> findGetIconPattern = literalExpression().and(psiExpression().methodCallParameter(0, method));
    registrar.registerReferenceProvider(findGetIconPattern, new PsiReferenceProvider() {

        @NotNull
        @Override
        public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull ProcessingContext context) {
            if (!PsiUtil.isIdeaProject(element.getProject()))
                return PsiReference.EMPTY_ARRAY;
            return new FileReferenceSet(element) {

                @Override
                protected Collection<PsiFileSystemItem> getExtraContexts() {
                    final Module icons = ModuleManager.getInstance(element.getProject()).findModuleByName("icons");
                    if (icons != null) {
                        final ArrayList<PsiFileSystemItem> result = new ArrayList<>();
                        final VirtualFile[] roots = ModuleRootManager.getInstance(icons).getSourceRoots();
                        final PsiManager psiManager = element.getManager();
                        for (VirtualFile root : roots) {
                            final PsiDirectory directory = psiManager.findDirectory(root);
                            if (directory != null) {
                                result.add(directory);
                            }
                        }
                        return result;
                    }
                    return super.getExtraContexts();
                }
            }.getAllReferences();
        }
    });
    registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().withLocalName("icon"), new PsiReferenceProvider() {

        @NotNull
        @Override
        public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull ProcessingContext context) {
            if (!PsiUtil.isPluginProject(element.getProject()) || !DescriptorUtil.isPluginXml(element.getContainingFile())) {
                return PsiReference.EMPTY_ARRAY;
            }
            return new PsiReference[] { new PsiReferenceBase<PsiElement>(element, true) {

                @Override
                public PsiElement resolve() {
                    String value = ((XmlAttributeValue) element).getValue();
                    if (value.startsWith("/")) {
                        FileReference lastRef = new FileReferenceSet(element).getLastReference();
                        return lastRef != null ? lastRef.resolve() : null;
                    }
                    List<String> path = StringUtil.split(value, ".");
                    if (path.size() > 1 && path.get(0).endsWith("Icons")) {
                        Project project = element.getProject();
                        PsiClass cur = findIconClass(project, path.get(0));
                        if (cur == null)
                            return null;
                        for (int i = 1; i < path.size() - 1; i++) {
                            cur = cur.findInnerClassByName(path.get(i), false);
                            if (cur == null)
                                return null;
                        }
                        return cur.findFieldByName(path.get(path.size() - 1), false);
                    }
                    return null;
                }

                @Override
                public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
                    PsiElement element = resolve();
                    if (element instanceof PsiFile) {
                        FileReference lastRef = new FileReferenceSet(element).getLastReference();
                        return lastRef.handleElementRename(newElementName);
                    }
                    if (element instanceof PsiField) {
                        String fqn = ((PsiField) element).getContainingClass().getQualifiedName();
                        if (fqn.startsWith("com.intellij.icons.")) {
                            return replace(fqn, newElementName, "com.intellij.icons.");
                        }
                        if (fqn.startsWith("icons.")) {
                            return replace(fqn, newElementName, "icons.");
                        }
                    }
                    return super.handleElementRename(newElementName);
                }

                @Override
                public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
                    if (element instanceof PsiFile) {
                        FileReference lastRef = new FileReferenceSet(element).getLastReference();
                        return lastRef.bindToElement(element);
                    }
                    if (element instanceof PsiField) {
                        String fqn = ((PsiField) element).getContainingClass().getQualifiedName();
                        String newName = ((PsiField) element).getName();
                        if (fqn.startsWith("com.intellij.icons.")) {
                            return replace(fqn, newName, "com.intellij.icons.");
                        }
                        if (fqn.startsWith("icons.")) {
                            return replace(fqn, newName, "icons.");
                        }
                    }
                    return super.bindToElement(element);
                }

                private PsiElement replace(String fqn, String newName, String pckg) {
                    XmlAttribute parent = (XmlAttribute) getElement().getParent();
                    parent.setValue(fqn.substring(pckg.length()) + "." + newName);
                    return parent.getValueElement();
                }

                @NotNull
                @Override
                public Object[] getVariants() {
                    return EMPTY_ARRAY;
                }
            } };
        }
    });
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) ProcessingContext(com.intellij.util.ProcessingContext) XmlAttribute(com.intellij.psi.xml.XmlAttribute) ArrayList(java.util.ArrayList) NotNull(org.jetbrains.annotations.NotNull) ArrayList(java.util.ArrayList) List(java.util.List) FileReferenceSet(com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet) PsiMethodPattern(com.intellij.patterns.PsiMethodPattern) Project(com.intellij.openapi.project.Project) PsiJavaElementPattern(com.intellij.patterns.PsiJavaElementPattern) IncorrectOperationException(com.intellij.util.IncorrectOperationException) Module(com.intellij.openapi.module.Module) FileReference(com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference) PsiFileReference(com.intellij.psi.impl.source.resolve.reference.impl.providers.PsiFileReference) IconLoader(com.intellij.openapi.util.IconLoader)

Example 74 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.

the class GenerateAntTest method attributesEqual.

private static boolean attributesEqual(XmlTag genTag, XmlTag expTag) {
    final XmlAttribute[] gattributes = genTag.getAttributes();
    final XmlAttribute[] eattributes = expTag.getAttributes();
    if (gattributes.length != eattributes.length)
        return false;
    for (int i = 0; i < eattributes.length; i++) {
        XmlAttribute eattribute = eattributes[i];
        XmlAttribute gattribute = gattributes[i];
        // logical comparison of the attributes (namespace:localname and display value)
        if (!Comparing.strEqual(gattribute.getLocalName(), eattribute.getLocalName()))
            return false;
        if (!Comparing.strEqual(gattribute.getNamespace(), eattribute.getNamespace()))
            return false;
        if (!Comparing.strEqual(gattribute.getDisplayValue(), eattribute.getDisplayValue()))
            return false;
    }
    return true;
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute)

Example 75 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.

the class MethodPropertyReference method getClassReferencesElement.

protected PsiElement getClassReferencesElement() {
    final XmlTag tag = (XmlTag) myElement.getParent().getParent();
    final XmlAttribute name = tag.getAttribute("name", null);
    if (name != null) {
        return name.getValueElement();
    }
    return null;
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) XmlTag(com.intellij.psi.xml.XmlTag)

Aggregations

XmlAttribute (com.intellij.psi.xml.XmlAttribute)220 XmlTag (com.intellij.psi.xml.XmlTag)116 PsiElement (com.intellij.psi.PsiElement)60 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)57 NotNull (org.jetbrains.annotations.NotNull)44 XmlFile (com.intellij.psi.xml.XmlFile)37 Nullable (org.jetbrains.annotations.Nullable)27 Project (com.intellij.openapi.project.Project)25 VirtualFile (com.intellij.openapi.vfs.VirtualFile)20 TextRange (com.intellij.openapi.util.TextRange)18 XmlAttributeDescriptor (com.intellij.xml.XmlAttributeDescriptor)18 ArrayList (java.util.ArrayList)18 PsiFile (com.intellij.psi.PsiFile)17 PsiReference (com.intellij.psi.PsiReference)17 IncorrectOperationException (com.intellij.util.IncorrectOperationException)10 DomElement (com.intellij.util.xml.DomElement)10 Result (com.intellij.openapi.application.Result)9 XmlElementDescriptor (com.intellij.xml.XmlElementDescriptor)9 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)8 XmlElement (com.intellij.psi.xml.XmlElement)6