1: <?php declare(strict_types=1);
2:
3: namespace PhpParser\Node\Expr;
4:
5: use PhpParser\Node\Arg;
6: use PhpParser\Node\Expr;
7: use PhpParser\Node\VariadicPlaceholder;
8:
9: abstract class CallLike extends Expr {
10: /**
11: * Return raw arguments, which may be actual Args, or VariadicPlaceholders for first-class
12: * callables.
13: *
14: * @return array<Arg|VariadicPlaceholder>
15: */
16: abstract public function getRawArgs(): array;
17:
18: /**
19: * Returns whether this call expression is actually a first class callable.
20: */
21: public function isFirstClassCallable(): bool {
22: $rawArgs = $this->getRawArgs();
23: return count($rawArgs) === 1 && current($rawArgs) instanceof VariadicPlaceholder;
24: }
25:
26: /**
27: * Assert that this is not a first-class callable and return only ordinary Args.
28: *
29: * @return Arg[]
30: */
31: public function getArgs(): array {
32: assert(!$this->isFirstClassCallable());
33: return $this->getRawArgs();
34: }
35:
36: /**
37: * Retrieves a specific argument from the raw arguments.
38: *
39: * Returns the named argument that matches the given `$name`, or the
40: * positional (unnamed) argument that exists at the given `$position`,
41: * otherwise, returns `null` for first-class callables or if no match is found.
42: */
43: public function getArg(string $name, int $position): ?Arg {
44: if ($this->isFirstClassCallable()) {
45: return null;
46: }
47: foreach ($this->getRawArgs() as $i => $arg) {
48: if ($arg->unpack) {
49: continue;
50: }
51: if (
52: ($arg->name !== null && $arg->name->toString() === $name)
53: || ($arg->name === null && $i === $position)
54: ) {
55: return $arg;
56: }
57: }
58: return null;
59: }
60: }
61: