use of org.intellij.lang.xpath.xslt.psi.XsltVariable 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 org.intellij.lang.xpath.xslt.psi.XsltVariable in project intellij-community by JetBrains.
the class XsltExtractTemplateAction method extractFrom.
private boolean extractFrom(@NotNull final PsiElement start, final PsiElement end, String newName) {
final XmlTag outerTemplate = XsltCodeInsightUtil.getTemplateTag(start, false);
if (outerTemplate == null) {
return false;
}
final XmlTag parentScope = PsiTreeUtil.getParentOfType(start, XmlTag.class, true);
if (parentScope == null) {
return false;
}
final StringBuilder sb = new StringBuilder("\n");
final Set<String> vars = new LinkedHashSet<>();
final int startOffset = start.getTextRange().getStartOffset();
final int endOffset = end.getTextRange().getEndOffset();
PsiElement e = start;
while (e != null) {
if (e instanceof XmlTag) {
final XmlTag tag = (XmlTag) e;
if (XsltSupport.isVariable(tag)) {
final XsltVariable variable = XsltElementFactory.getInstance().wrapElement(tag, XsltVariable.class);
final LocalSearchScope searchScope = new LocalSearchScope(parentScope);
final Query<PsiReference> query = ReferencesSearch.search(variable, searchScope);
for (PsiReference reference : query) {
final XmlElement context = PsiTreeUtil.getContextOfType(reference.getElement(), XmlElement.class, true);
if (context == null || context.getTextRange().getStartOffset() > endOffset) {
return false;
}
}
}
}
sb.append(e.getText());
final List<XPathVariableReference> references = RefactoringUtil.collectVariableReferences(e);
for (XPathVariableReference reference : references) {
final XPathVariable variable = reference.resolve();
if (variable instanceof XsltVariable) {
final XmlTag var = ((XsltVariable) variable).getTag();
if (var.getTextRange().getStartOffset() < startOffset) {
// don't pass through global parameters and variables
if (XsltCodeInsightUtil.getTemplateTag(variable, false) != null) {
vars.add(variable.getName());
}
}
} else if (variable == null) {
// TODO just copy unresolved refs or fail?
vars.add(reference.getReferencedName());
}
}
if (e == end) {
break;
}
e = e.getNextSibling();
}
sb.append("\n");
final String s = newName == null ? Messages.showInputDialog(start.getProject(), "Template Name: ", getRefactoringName(), Messages.getQuestionIcon()) : newName;
if (s != null) {
new WriteCommandAction(start.getProject()) {
protected void run(@NotNull Result result) throws Throwable {
final PsiFile containingFile = start.getContainingFile();
XmlTag templateTag = parentScope.createChildTag("template", XsltSupport.XSLT_NS, sb.toString(), false);
templateTag.setAttribute("name", s);
final PsiElement dummy = XmlElementFactory.getInstance(start.getProject()).createDisplayText(" ");
final PsiElement outerParent = outerTemplate.getParent();
final PsiElement element = outerParent.addAfter(dummy, outerTemplate);
templateTag = (XmlTag) outerParent.addAfter(templateTag, element);
final TextRange adjust = templateTag.getTextRange();
final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(start.getProject());
final Document doc = psiDocumentManager.getDocument(containingFile);
assert doc != null;
psiDocumentManager.doPostponedOperationsAndUnblockDocument(doc);
CodeStyleManager.getInstance(start.getManager().getProject()).adjustLineIndent(containingFile, adjust);
final PsiElement parent = start.getParent();
XmlTag callTag = parentScope.createChildTag("call-template", XsltSupport.XSLT_NS, null, false);
callTag.setAttribute("name", s);
if (start instanceof XmlToken && ((XmlToken) start).getTokenType() == XmlTokenType.XML_DATA_CHARACTERS) {
assert start == end;
callTag = (XmlTag) start.replace(callTag);
} else {
callTag = (XmlTag) parent.addBefore(callTag, start);
parent.deleteChildRange(start, end);
}
for (String var : vars) {
final XmlTag param = templateTag.createChildTag("param", XsltSupport.XSLT_NS, null, false);
param.setAttribute("name", var);
RefactoringUtil.addParameter(templateTag, param);
final XmlTag arg = RefactoringUtil.addWithParam(callTag);
arg.setAttribute("name", var);
arg.setAttribute("select", "$" + var);
}
}
}.execute().logException(Logger.getInstance(getClass().getName()));
}
return true;
}
Aggregations