Search in sources :

Example 1 with Function

use of org.intellij.lang.xpath.context.functions.Function 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)

Example 2 with Function

use of org.intellij.lang.xpath.context.functions.Function in project intellij-community by JetBrains.

the class XPathFunctionCallImpl method getType.

@NotNull
public XPathType getType() {
    final XPathFunction f = resolve();
    if (f == null)
        return XPathType.UNKNOWN;
    final Function function = f.getDeclaration();
    return function != null ? function.getReturnType() : XPathType.UNKNOWN;
}
Also used : Function(org.intellij.lang.xpath.context.functions.Function) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with Function

use of org.intellij.lang.xpath.context.functions.Function in project intellij-community by JetBrains.

the class Xslt2ContextProvider method resolveCustomFunction.

@Nullable
private static Function resolveCustomFunction(final XmlFile file, final QName name, int argCount) {
    final Map<Pair<QName, Integer>, Function> functions = getCustomFunctions(file);
    final Function exactMatch = functions.get(Pair.create(name, argCount));
    if (exactMatch != null) {
        return exactMatch;
    }
    Function candidate = null;
    for (Pair<QName, Integer> pair : functions.keySet()) {
        if (pair.getFirst().equals(name)) {
            candidate = functions.get(pair);
        }
    }
    return candidate;
}
Also used : XsltFunction(org.intellij.lang.xpath.xslt.psi.XsltFunction) Function(org.intellij.lang.xpath.context.functions.Function) QName(javax.xml.namespace.QName) Pair(com.intellij.openapi.util.Pair) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with Function

use of org.intellij.lang.xpath.context.functions.Function in project intellij-community by JetBrains.

the class XPathParameterInfoHandler method updateUI.

public void updateUI(XPathFunction function, @NotNull ParameterInfoUIContext context) {
    final Function declaration = function.getDeclaration();
    if (declaration != null) {
        if (declaration.getParameters().length > 0) {
            final String signature = declaration.buildSignature();
            final int length = declaration.getName().length();
            final String hint = signature.substring(length + 1, signature.length() - 1);
            final int currentParameterIndex = context.getCurrentParameterIndex();
            if (currentParameterIndex < 0 || currentParameterIndex >= declaration.getParameters().length) {
                context.setupUIComponentPresentation(hint, -1, -1, false, false, false, context.getDefaultParameterColor());
            } else {
                final String[] ps = hint.split(",");
                final TextRange[] ts = new TextRange[ps.length];
                int start = 0;
                for (int i = 0; i < ps.length; i++) {
                    String p = ps[i];
                    ts[i] = TextRange.from(start, p.length());
                    start += p.length() + 1;
                }
                final TextRange range = ts[currentParameterIndex];
                context.setupUIComponentPresentation(hint, range.getStartOffset(), range.getEndOffset(), false, false, false, context.getDefaultParameterColor());
            }
        } else {
            context.setupUIComponentPresentation(noParamsMessage(), -1, -1, false, false, false, context.getDefaultParameterColor());
        }
    }
}
Also used : Function(org.intellij.lang.xpath.context.functions.Function) XPathFunction(org.intellij.lang.xpath.psi.XPathFunction) TextRange(com.intellij.openapi.util.TextRange)

Example 5 with Function

use of org.intellij.lang.xpath.context.functions.Function in project intellij-community by JetBrains.

the class CompletionLists method getFunctionCompletions.

public static Collection<Lookup> getFunctionCompletions(XPathElement element) {
    final XPathFile xpathFile = (XPathFile) element.getContainingFile();
    final ContextProvider contextProvider = ContextProvider.getContextProvider(xpathFile);
    final NamespaceContext nsContext = contextProvider.getNamespaceContext();
    String uri;
    PrefixedName qn = null;
    if (element instanceof QNameElement) {
        qn = ((QNameElement) element).getQName();
        if (qn != null) {
            QName qName = contextProvider.getQName(qn, element);
            if (qn.getPrefix() != null) {
                if (qName != null) {
                    uri = qName.getNamespaceURI();
                } else {
                    return Collections.emptySet();
                }
            } else {
                uri = null;
            }
        } else {
            uri = null;
        }
    } else {
        uri = null;
    }
    final Map<Pair<QName, Integer>, ? extends Function> functions = contextProvider.getFunctionContext().getFunctions();
    final List<Lookup> lookups = new ArrayList<>(functions.size());
    for (Map.Entry<Pair<QName, Integer>, ? extends Function> entry : functions.entrySet()) {
        final Function functionDecl = entry.getValue();
        final QName f = entry.getKey().first;
        final String p;
        if (nsContext != null) {
            String namespaceURI = f.getNamespaceURI();
            if (uri != null && !namespaceURI.equals(uri)) {
                continue;
            }
            final String prefixForURI = nsContext.getPrefixForURI(namespaceURI, PsiTreeUtil.getContextOfType(element, XmlElement.class, true));
            if (prefixForURI == null && namespaceURI.length() > 0) {
                continue;
            }
            p = qn == null || qn.getPrefix() == null ? makePrefix(prefixForURI) : "";
        } else {
            p = "";
        }
        lookups.add(FunctionLookup.newFunctionLookup(p + f.getLocalPart(), functionDecl));
    }
    return lookups;
}
Also used : QName(javax.xml.namespace.QName) ContextProvider(org.intellij.lang.xpath.context.ContextProvider) Function(org.intellij.lang.xpath.context.functions.Function) XPathFile(org.intellij.lang.xpath.XPathFile) NamespaceContext(org.intellij.lang.xpath.context.NamespaceContext) XmlElement(com.intellij.psi.xml.XmlElement) Pair(com.intellij.openapi.util.Pair)

Aggregations

Function (org.intellij.lang.xpath.context.functions.Function)5 Pair (com.intellij.openapi.util.Pair)3 QName (javax.xml.namespace.QName)3 ASTNode (com.intellij.lang.ASTNode)1 Annotation (com.intellij.lang.annotation.Annotation)1 TextRange (com.intellij.openapi.util.TextRange)1 PsiReference (com.intellij.psi.PsiReference)1 XmlElement (com.intellij.psi.xml.XmlElement)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 XPathFile (org.intellij.lang.xpath.XPathFile)1 ContextProvider (org.intellij.lang.xpath.context.ContextProvider)1 NamespaceContext (org.intellij.lang.xpath.context.NamespaceContext)1 Parameter (org.intellij.lang.xpath.context.functions.Parameter)1 XPathFunction (org.intellij.lang.xpath.psi.XPathFunction)1 PrefixedNameImpl (org.intellij.lang.xpath.psi.impl.PrefixedNameImpl)1 XsltFunction (org.intellij.lang.xpath.xslt.psi.XsltFunction)1 NotNull (org.jetbrains.annotations.NotNull)1 Nullable (org.jetbrains.annotations.Nullable)1