void (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) { holder.newAnnotation(HighlightSeverity.ERROR, XPathBundle.message("annotator.error.extension.namespace.prefix.has.not.been.declared", qName.getPrefix())) .range(qName.getPrefixNode()) .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL).create(); } 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.newAnnotation(HighlightSeverity.WARNING, XPathBundle.message("annotator.warning.unknown.function", name)).range(node).create(); } } } } } else { if (name != null) { holder.newAnnotation(HighlightSeverity.WARNING, XPathBundle.message("annotator.warning.unknown.function", name)).range(node).create(); } else if (qName.getPrefixNode() != null) { holder.newAnnotation(HighlightSeverity.ERROR, XPathBundle.message("annotator.error.extension.namespace.prefix.has.not.been.declared", qName.getPrefix())) .range(qName.getPrefixNode()) .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL).create(); } } } 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.newAnnotation(HighlightSeverity.ERROR, XPathBundle.message("annotator.error.missing.argument.for.function", name)).range(node).create(); } else { final Parameter last = functionDecl.getParameters()[functionDecl.getParameters().length - 1]; holder.newAnnotation(HighlightSeverity.ERROR, XPathBundle.message("annotator.error.function.requires.choice.at.least.arguments", name, last.kind == Parameter.Kind.OPTIONAL || last.kind == Parameter.Kind.VARARG ? 0 : 1, functionDecl.getMinArity())).range(node).create(); } } } }