use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.
the class XsltIntroduceVariableAction method extractImpl.
protected boolean extractImpl(XPathExpression expression, Set<XPathExpression> matchingExpressions, List<XmlTag> otherMatches, IntroduceVariableOptions dlg) {
final XmlAttribute attribute = PsiTreeUtil.getContextOfType(expression, XmlAttribute.class, true);
assert attribute != null;
try {
final String name = dlg.getName();
final XmlTag insertionPoint = XsltCodeInsightUtil.findVariableInsertionPoint(attribute.getParent(), XsltCodeInsightUtil.getUsageBlock(expression), name, dlg.isReplaceAll() ? otherMatches.toArray(new XmlTag[otherMatches.size()]) : XmlTag.EMPTY);
final XmlTag parentTag = insertionPoint.getParentTag();
assert parentTag != null : "Could not locate position to create variable at";
final XmlTag xmlTag = parentTag.createChildTag("variable", XsltSupport.XSLT_NS, null, false);
xmlTag.setAttribute("name", name);
xmlTag.setAttribute("select", expression.getText());
// TODO: revisit the formatting
final PsiElement element = parentTag.addBefore(xmlTag, insertionPoint);
final ASTNode node1 = parentTag.getNode();
assert node1 != null;
final ASTNode node2 = element.getNode();
assert node2 != null;
CodeStyleManager.getInstance(xmlTag.getManager().getProject()).reformatNewlyAddedElement(node1, node2);
final XPathVariableReference var = XPathChangeUtil.createVariableReference(expression, name);
expression.replace(var);
if (dlg.isReplaceAll()) {
for (XPathExpression expr : matchingExpressions) {
expr.replace(XPathChangeUtil.createVariableReference(expr, name));
}
return false;
} else {
return true;
}
} catch (IncorrectOperationException e) {
Logger.getInstance(getClass().getName()).error(e);
return false;
}
}
use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.
the class XsltExtractFunctionAction method extractImpl.
protected boolean extractImpl(XPathExpression expression, Set<XPathExpression> matchingExpressions, List<XmlTag> otherMatches, RefactoringOptions dlg) {
final XmlAttribute attribute = PsiTreeUtil.getContextOfType(expression, XmlAttribute.class, true);
assert attribute != null;
try {
final String name = dlg.getName();
final XmlTag rootTag = ((XmlFile) attribute.getParent().getContainingFile()).getRootTag();
final XmlTag[] templates = rootTag.findSubTags("template", XsltSupport.XSLT_NS);
final XmlTag insertionPoint = templates.length > 0 ? templates[0] : rootTag.getSubTags()[0];
final XmlTag parentTag = insertionPoint.getParentTag();
assert parentTag != null : "Could not locate position to create function at";
final XmlTag xmlTag = parentTag.createChildTag("function", XsltSupport.XSLT_NS, null, false);
xmlTag.setAttribute("name", name);
final XPathType type = ExpectedTypeUtil.mapType(expression, expression.getType());
xmlTag.setAttribute("as", prefixedName(type, insertionPoint));
final StringBuilder argList = new StringBuilder();
final List<XPathVariableReference> references = RefactoringUtil.collectVariableReferences(expression);
for (XPathVariableReference reference : references) {
final XPathVariable variable = reference.resolve();
if (variable instanceof XsltVariable) {
// don't pass through global parameters and variables
if (XsltCodeInsightUtil.getTemplateTag(variable, false) != null) {
final XmlTag param = parentTag.createChildTag("param", XsltSupport.XSLT_NS, null, false);
param.setAttribute("name", variable.getName());
if (!variable.getType().isAbstract()) {
param.setAttribute("as", prefixedName(ExpectedTypeUtil.mapType(expression, variable.getType()), parentTag));
}
RefactoringUtil.addParameter(xmlTag, param);
if (argList.length() > 0) {
argList.append(", ");
}
argList.append("$").append(variable.getName());
}
}
}
final XmlTag seqTag = parentTag.createChildTag("sequence", XsltSupport.XSLT_NS, null, false);
seqTag.setAttribute("select", expression.getText());
xmlTag.add(seqTag);
// TODO: revisit the formatting
final PsiElement element = parentTag.addBefore(xmlTag, insertionPoint);
final ASTNode node1 = parentTag.getNode();
assert node1 != null;
final ASTNode node2 = element.getNode();
assert node2 != null;
CodeStyleManager.getInstance(xmlTag.getManager().getProject()).reformatNewlyAddedElement(node1, node2);
final XPathExpression var = XPathChangeUtil.createExpression(expression, name + "(" + argList + ")");
expression.replace(var);
return true;
} catch (IncorrectOperationException e) {
Logger.getInstance(getClass().getName()).error(e);
return false;
}
}
use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.
the class XPathLanguageInjector method getLanguagesToInject.
public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
final XmlAttribute attribute = (XmlAttribute) context;
if (!XsltSupport.isXPathAttribute(attribute))
return;
XmlAttributeValueImpl value = (XmlAttributeValueImpl) attribute.getValueElement();
if (value == null)
return;
ASTNode type = value.findChildByType(XmlElementType.XML_ENTITY_REF);
// workaround for inability to inject into text with entity refs (e.g. IDEA-72972) TODO: fix it
if (type != null)
return;
final XsltChecker.LanguageLevel languageLevel = XsltSupport.getXsltLanguageLevel(attribute.getContainingFile());
final TextRange[] ranges = getInjectionRanges(attribute, languageLevel);
for (TextRange range : ranges) {
// workaround for http://www.jetbrains.net/jira/browse/IDEA-10096
TextRange rangeInsideHost;
String prefix;
if (range instanceof AVTRange) {
if (((AVTRange) range).myComplete) {
rangeInsideHost = range.shiftRight(2).grown(-2);
prefix = "";
} else {
// we need to keep the "'}' expected" parse error
rangeInsideHost = range.shiftRight(2).grown(-1);
prefix = "{";
}
} else {
rangeInsideHost = range;
prefix = "";
}
if (value.getTextRange().contains(rangeInsideHost.shiftRight(value.getTextRange().getStartOffset()))) {
registrar.startInjecting(languageLevel.getXPathVersion().getLanguage()).addPlace(prefix, "", value, rangeInsideHost).doneInjecting();
}
}
}
use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.
the class XsltImplicitUsagesProvider method isImplicitUsage.
public boolean isImplicitUsage(PsiElement element) {
if (!(element instanceof XmlAttribute)) {
return false;
}
final XmlAttribute attr = (XmlAttribute) element;
if (!attr.isNamespaceDeclaration()) {
return false;
}
final PsiFile file = attr.getContainingFile();
if (!(file instanceof XmlFile)) {
return false;
}
// ContextProvider.hasXPathInjections() is an optimization that avoids to run the references search on totally XPath-free XML files
if (!ContextProvider.hasXPathInjections((XmlFile) file) && !XsltSupport.isXsltFile(file)) {
return false;
}
// This need to catch both prefix references from injected XPathFiles and prefixes from mode declarations/references:
// <xsl:template match="*" mode="prefix:name" />
// BTW: Almost the same logic applies to other XML dialects (RELAX-NG).
// Pull this class into the platform?
final String prefix = attr.getLocalName();
final SchemaPrefix target = new SchemaPrefix(attr, TextRange.from("xmlns:".length(), prefix.length()), prefix);
final Query<PsiReference> q = ReferencesSearch.search(target, new LocalSearchScope(attr.getParent()));
return !q.forEach(psiReference -> {
if (psiReference.getElement() == attr) {
return true;
}
return false;
});
}
use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.
the class ReplaceWithXslAttribute method isAvailable.
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (!XsltSupport.isXsltFile(file))
return false;
final int offset = editor.getCaretModel().getOffset();
final PsiElement element = file.findElementAt(offset);
final XmlAttribute attr = PsiTreeUtil.getParentOfType(element, XmlAttribute.class, false);
if (attr == null || attr.getValueElement() == null) {
return false;
}
if (XsltSupport.isXsltTag(attr.getParent())) {
return false;
}
final ASTNode node = attr.getNode();
if (node == null)
return false;
final ASTNode nameNode = XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild(node);
if (nameNode == null) {
return false;
} else {
return nameNode.getTextRange().contains(offset);
}
}
Aggregations