Search in sources :

Example 76 with ASTNode

use of com.intellij.lang.ASTNode 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;
    }
}
Also used : XPathExpression(org.intellij.lang.xpath.psi.XPathExpression) XmlAttribute(com.intellij.psi.xml.XmlAttribute) ASTNode(com.intellij.lang.ASTNode) XPathVariableReference(org.intellij.lang.xpath.psi.XPathVariableReference) IncorrectOperationException(com.intellij.util.IncorrectOperationException) PsiElement(com.intellij.psi.PsiElement) XmlTag(com.intellij.psi.xml.XmlTag)

Example 77 with ASTNode

use of com.intellij.lang.ASTNode 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;
    }
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) XmlFile(com.intellij.psi.xml.XmlFile) XsltVariable(org.intellij.lang.xpath.xslt.psi.XsltVariable) ASTNode(com.intellij.lang.ASTNode) IncorrectOperationException(com.intellij.util.IncorrectOperationException) PsiElement(com.intellij.psi.PsiElement) XmlTag(com.intellij.psi.xml.XmlTag)

Example 78 with ASTNode

use of com.intellij.lang.ASTNode 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();
        }
    }
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange) XmlAttributeValueImpl(com.intellij.psi.impl.source.xml.XmlAttributeValueImpl)

Example 79 with ASTNode

use of com.intellij.lang.ASTNode 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);
    }
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) ASTNode(com.intellij.lang.ASTNode) PsiElement(com.intellij.psi.PsiElement)

Example 80 with ASTNode

use of com.intellij.lang.ASTNode in project intellij-community by JetBrains.

the class XPathAnnotator method checkFunctionCall.

private static void checkFunctionCall(AnnotationHolder holder, XPathFunctionCall call, @NotNull ContextProvider contextProvider) {
    final ASTNode node = call.getNode().findChildByType(XPathTokenTypes.FUNCTION_NAME);
    if (node == null) {
        return;
    }
    final QName name = contextProvider.getQName(call);
    final XPathFunction function = call.resolve();
    final Function functionDecl = function != null ? function.getDeclaration() : null;
    if (functionDecl == null) {
        final PrefixedNameImpl qName = (PrefixedNameImpl) call.getQName();
        // need special check for extension functions
        if (call.getQName().getPrefix() != null && contextProvider.getFunctionContext().allowsExtensions()) {
            final PsiReference[] references = call.getReferences();
            if (references.length > 1 && references[1].resolve() == null) {
                final Annotation ann = holder.createErrorAnnotation(qName.getPrefixNode(), "Extension namespace prefix '" + qName.getPrefix() + "' has not been declared");
                ann.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
            } else if (name != null) {
                final String extNS = name.getNamespaceURI();
                if (!StringUtil.isEmpty(extNS)) {
                    final Set<Pair<QName, Integer>> pairs = contextProvider.getFunctionContext().getFunctions().keySet();
                    for (Pair<QName, Integer> pair : pairs) {
                        // extension namespace is known
                        final String uri = pair.first.getNamespaceURI();
                        if (uri != null && uri.equals(extNS)) {
                            holder.createWarningAnnotation(node, "Unknown function '" + name + "'");
                        }
                    }
                }
            }
        } else {
            if (name != null) {
                holder.createWarningAnnotation(node, "Unknown function '" + name + "'");
            } else if (qName.getPrefixNode() != null) {
                final Annotation ann = holder.createErrorAnnotation(qName.getPrefixNode(), "Extension namespace prefix '" + qName.getPrefix() + "' has not been declared");
                ann.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
            }
        }
    } else {
        final XPathExpression[] arguments = call.getArgumentList();
        for (int i = 0; i < arguments.length; i++) {
            checkArgument(holder, arguments[i], i, functionDecl.getParameters());
        }
        if (arguments.length < functionDecl.getMinArity()) {
            if (functionDecl.getMinArity() == 1) {
                holder.createErrorAnnotation(node, "Missing argument for function '" + name + "'");
            } else {
                final Parameter last = functionDecl.getParameters()[functionDecl.getParameters().length - 1];
                final String atLeast = last.kind == Parameter.Kind.OPTIONAL || last.kind == Parameter.Kind.VARARG ? "at least " : "";
                holder.createErrorAnnotation(node, "Function '" + name + "' requires " + atLeast + functionDecl.getMinArity() + " arguments");
            }
        }
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) QName(javax.xml.namespace.QName) PsiReference(com.intellij.psi.PsiReference) Annotation(com.intellij.lang.annotation.Annotation) Function(org.intellij.lang.xpath.context.functions.Function) PrefixedNameImpl(org.intellij.lang.xpath.psi.impl.PrefixedNameImpl) ASTNode(com.intellij.lang.ASTNode) Parameter(org.intellij.lang.xpath.context.functions.Parameter) Pair(com.intellij.openapi.util.Pair)

Aggregations

ASTNode (com.intellij.lang.ASTNode)748 PsiElement (com.intellij.psi.PsiElement)142 NotNull (org.jetbrains.annotations.NotNull)132 IElementType (com.intellij.psi.tree.IElementType)127 Nullable (org.jetbrains.annotations.Nullable)99 TextRange (com.intellij.openapi.util.TextRange)91 ArrayList (java.util.ArrayList)53 IncorrectOperationException (com.intellij.util.IncorrectOperationException)35 PsiFile (com.intellij.psi.PsiFile)31 Annotation (com.intellij.lang.annotation.Annotation)22 CharTable (com.intellij.util.CharTable)22 Document (com.intellij.openapi.editor.Document)18 FoldingDescriptor (com.intellij.lang.folding.FoldingDescriptor)17 XmlTag (com.intellij.psi.xml.XmlTag)17 Project (com.intellij.openapi.project.Project)16 AbstractBlock (com.intellij.psi.formatter.common.AbstractBlock)16 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)16 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)15 CompositeElement (com.intellij.psi.impl.source.tree.CompositeElement)15 PsiReference (com.intellij.psi.PsiReference)14