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();
}
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;
}
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;
}
} };
}
});
}
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;
}
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;
}
Aggregations