1<?php declare(strict_types=1);
2
3namespace PhpParser\Builder;
4
5use PhpParser;
6use PhpParser\BuilderHelpers;
7use PhpParser\Node;
8use PhpParser\Node\Stmt;
9
10class Method extends FunctionLike
11{
12    protected $name;
13    protected $flags = 0;
14
15    /** @var array|null */
16    protected $stmts = [];
17
18    /** @var Node\AttributeGroup[] */
19    protected $attributeGroups = [];
20
21    /**
22     * Creates a method builder.
23     *
24     * @param string $name Name of the method
25     */
26    public function __construct(string $name) {
27        $this->name = $name;
28    }
29
30    /**
31     * Makes the method public.
32     *
33     * @return $this The builder instance (for fluid interface)
34     */
35    public function makePublic() {
36        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC);
37
38        return $this;
39    }
40
41    /**
42     * Makes the method protected.
43     *
44     * @return $this The builder instance (for fluid interface)
45     */
46    public function makeProtected() {
47        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED);
48
49        return $this;
50    }
51
52    /**
53     * Makes the method private.
54     *
55     * @return $this The builder instance (for fluid interface)
56     */
57    public function makePrivate() {
58        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE);
59
60        return $this;
61    }
62
63    /**
64     * Makes the method static.
65     *
66     * @return $this The builder instance (for fluid interface)
67     */
68    public function makeStatic() {
69        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_STATIC);
70
71        return $this;
72    }
73
74    /**
75     * Makes the method abstract.
76     *
77     * @return $this The builder instance (for fluid interface)
78     */
79    public function makeAbstract() {
80        if (!empty($this->stmts)) {
81            throw new \LogicException('Cannot make method with statements abstract');
82        }
83
84        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_ABSTRACT);
85        $this->stmts = null; // abstract methods don't have statements
86
87        return $this;
88    }
89
90    /**
91     * Makes the method final.
92     *
93     * @return $this The builder instance (for fluid interface)
94     */
95    public function makeFinal() {
96        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_FINAL);
97
98        return $this;
99    }
100
101    /**
102     * Adds a statement.
103     *
104     * @param Node|PhpParser\Builder $stmt The statement to add
105     *
106     * @return $this The builder instance (for fluid interface)
107     */
108    public function addStmt($stmt) {
109        if (null === $this->stmts) {
110            throw new \LogicException('Cannot add statements to an abstract method');
111        }
112
113        $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
114
115        return $this;
116    }
117
118    /**
119     * Adds an attribute group.
120     *
121     * @param Node\Attribute|Node\AttributeGroup $attribute
122     *
123     * @return $this The builder instance (for fluid interface)
124     */
125    public function addAttribute($attribute) {
126        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
127
128        return $this;
129    }
130
131    /**
132     * Returns the built method node.
133     *
134     * @return Stmt\ClassMethod The built method node
135     */
136    public function getNode() : Node {
137        return new Stmt\ClassMethod($this->name, [
138            'flags'      => $this->flags,
139            'byRef'      => $this->returnByRef,
140            'params'     => $this->params,
141            'returnType' => $this->returnType,
142            'stmts'      => $this->stmts,
143            'attrGroups' => $this->attributeGroups,
144        ], $this->attributes);
145    }
146}
147