1<?php declare(strict_types=1);
2
3namespace PhpParser\Builder;
4
5use PhpParser;
6use PhpParser\BuilderHelpers;
7use PhpParser\Node;
8use PhpParser\Node\Name;
9use PhpParser\Node\Stmt;
10
11class Interface_ extends Declaration {
12    protected string $name;
13    /** @var list<Name> */
14    protected array $extends = [];
15    /** @var list<Stmt\ClassConst> */
16    protected array $constants = [];
17    /** @var list<Stmt\ClassMethod> */
18    protected array $methods = [];
19    /** @var list<Node\AttributeGroup> */
20    protected array $attributeGroups = [];
21
22    /**
23     * Creates an interface builder.
24     *
25     * @param string $name Name of the interface
26     */
27    public function __construct(string $name) {
28        $this->name = $name;
29    }
30
31    /**
32     * Extends one or more interfaces.
33     *
34     * @param Name|string ...$interfaces Names of interfaces to extend
35     *
36     * @return $this The builder instance (for fluid interface)
37     */
38    public function extend(...$interfaces) {
39        foreach ($interfaces as $interface) {
40            $this->extends[] = BuilderHelpers::normalizeName($interface);
41        }
42
43        return $this;
44    }
45
46    /**
47     * Adds a statement.
48     *
49     * @param Stmt|PhpParser\Builder $stmt The statement to add
50     *
51     * @return $this The builder instance (for fluid interface)
52     */
53    public function addStmt($stmt) {
54        $stmt = BuilderHelpers::normalizeNode($stmt);
55
56        if ($stmt instanceof Stmt\ClassConst) {
57            $this->constants[] = $stmt;
58        } elseif ($stmt instanceof Stmt\ClassMethod) {
59            // we erase all statements in the body of an interface method
60            $stmt->stmts = null;
61            $this->methods[] = $stmt;
62        } else {
63            throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
64        }
65
66        return $this;
67    }
68
69    /**
70     * Adds an attribute group.
71     *
72     * @param Node\Attribute|Node\AttributeGroup $attribute
73     *
74     * @return $this The builder instance (for fluid interface)
75     */
76    public function addAttribute($attribute) {
77        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
78
79        return $this;
80    }
81
82    /**
83     * Returns the built interface node.
84     *
85     * @return Stmt\Interface_ The built interface node
86     */
87    public function getNode(): PhpParser\Node {
88        return new Stmt\Interface_($this->name, [
89            'extends' => $this->extends,
90            'stmts' => array_merge($this->constants, $this->methods),
91            'attrGroups' => $this->attributeGroups,
92        ], $this->attributes);
93    }
94}
95