Search in sources :

Example 1 with PrefixedNameImpl

use of org.intellij.lang.xpath.psi.impl.PrefixedNameImpl 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)1 Annotation (com.intellij.lang.annotation.Annotation)1 Pair (com.intellij.openapi.util.Pair)1 PsiReference (com.intellij.psi.PsiReference)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 QName (javax.xml.namespace.QName)1 Function (org.intellij.lang.xpath.context.functions.Function)1 Parameter (org.intellij.lang.xpath.context.functions.Parameter)1 PrefixedNameImpl (org.intellij.lang.xpath.psi.impl.PrefixedNameImpl)1