MCPcopy Create free account
hub / github.com/PRQL/prql / func_call

Function func_call

prqlc/prqlc-parser/src/parser/expr.rs:414–483  ·  view source on GitHub ↗
(expr: E)

Source from the content-addressed store, hash-verified

412}
413
414fn func_call<'a, I, E>(expr: E) -> impl Parser<'a, I, Expr, ParserError<'a>> + Clone + 'a
415where
416 I: Input<'a, Token = lr::Token, Span = Span> + BorrowInput<'a>,
417 E: Parser<'a, I, Expr, ParserError<'a>> + Clone + 'a,
418{
419 let func_name = expr.clone();
420
421 let named_arg = ident_part()
422 .map(Some)
423 .then_ignore(ctrl(':'))
424 .then(expr.clone());
425
426 // TODO: I think this possibly should be restructured. Currently in the case
427 // of `derive x = 5`, the `x` is an alias of a single positional argument.
428 // That then means we incorrectly allow something like `derive x = 5 y = 6`,
429 // since there are two positional arguments each with an alias. This then
430 // leads to quite confusing error messages.
431 //
432 // Instead, we could only allow a single alias per function call as the
433 // first positional argument? (I worry that not simple though...).
434 // Alternatively we could change the language to enforce tuples, so `derive
435 // {x = 5}` were required. But we still need to account for the `join`
436 // example below, which doesn't work so well in a tuple; so I'm not sure
437 // this helps much.
438 //
439 // As a reminder, we need to account for `derive x = 5` and `join a=artists
440 // (id==album_id)`.
441 let positional_arg = maybe_aliased(expr.clone()).map(|e| (None, e));
442
443 func_name
444 .then(named_arg.or(positional_arg).repeated().collect::<Vec<_>>())
445 .validate(
446 |(name, args): (Expr, Vec<(Option<String>, Expr)>), extra, emit| {
447 let span = extra.span();
448 if args.is_empty() {
449 return name.kind;
450 }
451
452 let mut named_args = HashMap::new();
453 let mut positional = Vec::new();
454
455 for (name, arg) in args {
456 if let Some(name) = name {
457 match named_args.entry(name) {
458 Entry::Occupied(entry) => {
459 emit.emit(Rich::custom(
460 span,
461 format!("argument '{}' is used multiple times", entry.key()),
462 ));
463 }
464 Entry::Vacant(entry) => {
465 entry.insert(arg);
466 }
467 }
468 } else {
469 positional.push(arg);
470 }
471 }

Callers 4

expr_callFunction · 0.85
exprFunction · 0.85
caseFunction · 0.85
lambda_funcFunction · 0.85

Calls 9

ctrlFunction · 0.85
maybe_aliasedFunction · 0.85
mapMethod · 0.80
is_emptyMethod · 0.80
pushMethod · 0.80
ident_partFunction · 0.70
FuncCallClass · 0.50
spanMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected