1: <?php declare(strict_types=1);
2:
3: namespace PhpParser\Node\Stmt;
4:
5: use PhpParser\Modifiers;
6: use PhpParser\Node;
7: use PhpParser\Node\FunctionLike;
8:
9: class ClassMethod extends Node\Stmt implements FunctionLike {
10: /** @var int Flags */
11: public int $flags;
12: /** @var bool Whether to return by reference */
13: public bool $byRef;
14: /** @var Node\Identifier Name */
15: public Node\Identifier $name;
16: /** @var Node\Param[] Parameters */
17: public array $params;
18: /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */
19: public ?Node $returnType;
20: /** @var Node\Stmt[]|null Statements */
21: public ?array $stmts;
22: /** @var Node\AttributeGroup[] PHP attribute groups */
23: public array $attrGroups;
24:
25: /** @var array<string, bool> */
26: private static array $magicNames = [
27: '__construct' => true,
28: '__destruct' => true,
29: '__call' => true,
30: '__callstatic' => true,
31: '__get' => true,
32: '__set' => true,
33: '__isset' => true,
34: '__unset' => true,
35: '__sleep' => true,
36: '__wakeup' => true,
37: '__tostring' => true,
38: '__set_state' => true,
39: '__clone' => true,
40: '__invoke' => true,
41: '__debuginfo' => true,
42: '__serialize' => true,
43: '__unserialize' => true,
44: ];
45:
46: /**
47: * Constructs a class method node.
48: *
49: * @param string|Node\Identifier $name Name
50: * @param array{
51: * flags?: int,
52: * byRef?: bool,
53: * params?: Node\Param[],
54: * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
55: * stmts?: Node\Stmt[]|null,
56: * attrGroups?: Node\AttributeGroup[],
57: * } $subNodes Array of the following optional subnodes:
58: * 'flags => 0 : Flags
59: * 'byRef' => false : Whether to return by reference
60: * 'params' => array() : Parameters
61: * 'returnType' => null : Return type
62: * 'stmts' => array() : Statements
63: * 'attrGroups' => array() : PHP attribute groups
64: * @param array<string, mixed> $attributes Additional attributes
65: */
66: public function __construct($name, array $subNodes = [], array $attributes = []) {
67: $this->attributes = $attributes;
68: $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0;
69: $this->byRef = $subNodes['byRef'] ?? false;
70: $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
71: $this->params = $subNodes['params'] ?? [];
72: $this->returnType = $subNodes['returnType'] ?? null;
73: $this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : [];
74: $this->attrGroups = $subNodes['attrGroups'] ?? [];
75: }
76:
77: public function getSubNodeNames(): array {
78: return ['attrGroups', 'flags', 'byRef', 'name', 'params', 'returnType', 'stmts'];
79: }
80:
81: public function returnsByRef(): bool {
82: return $this->byRef;
83: }
84:
85: public function getParams(): array {
86: return $this->params;
87: }
88:
89: public function getReturnType() {
90: return $this->returnType;
91: }
92:
93: public function getStmts(): ?array {
94: return $this->stmts;
95: }
96:
97: public function getAttrGroups(): array {
98: return $this->attrGroups;
99: }
100:
101: /**
102: * Whether the method is explicitly or implicitly public.
103: */
104: public function isPublic(): bool {
105: return ($this->flags & Modifiers::PUBLIC) !== 0
106: || ($this->flags & Modifiers::VISIBILITY_MASK) === 0;
107: }
108:
109: /**
110: * Whether the method is protected.
111: */
112: public function isProtected(): bool {
113: return (bool) ($this->flags & Modifiers::PROTECTED);
114: }
115:
116: /**
117: * Whether the method is private.
118: */
119: public function isPrivate(): bool {
120: return (bool) ($this->flags & Modifiers::PRIVATE);
121: }
122:
123: /**
124: * Whether the method is abstract.
125: */
126: public function isAbstract(): bool {
127: return (bool) ($this->flags & Modifiers::ABSTRACT);
128: }
129:
130: /**
131: * Whether the method is final.
132: */
133: public function isFinal(): bool {
134: return (bool) ($this->flags & Modifiers::FINAL);
135: }
136:
137: /**
138: * Whether the method is static.
139: */
140: public function isStatic(): bool {
141: return (bool) ($this->flags & Modifiers::STATIC);
142: }
143:
144: /**
145: * Whether the method is magic.
146: */
147: public function isMagic(): bool {
148: return isset(self::$magicNames[$this->name->toLowerString()]);
149: }
150:
151: public function getType(): string {
152: return 'Stmt_ClassMethod';
153: }
154: }
155: