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");
}
}
}
}
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;
}
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;
}
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());
}
}
}
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;
}
Aggregations