Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.33% covered (success)
93.33%
14 / 15
83.33% covered (success)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
AttributeGenerator
93.33% covered (success)
93.33%
14 / 15
83.33% covered (success)
83.33%
5 / 6
9.02
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addArgument
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 hasArguments
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getArguments
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 render
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
4
 __toString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <dev@noladev.com>
8 * @copyright  Copyright (c) 2009-2027 NOLA Interactive, LLC.
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Code\Generator;
16
17use Pop\Code\Generator\Support\ValueFormatter;
18
19/**
20 * Attribute generator class
21 *
22 * Represents one `#[Name(args)]` usage. Deliberately never calls printIndent() — its correct
23 * indentation depends entirely on where it's used (none for a class-level attribute, matching the
24 * host's own indent for a member-level one), a decision made by the caller (AttributesTrait), not by
25 * this class.
26 *
27 * @category   Pop
28 * @package    Pop\Code
29 * @author     Nick Sagona, III <dev@noladev.com>
30 * @copyright  Copyright (c) 2009-2027 NOLA Interactive, LLC.
31 * @license    https://www.popphp.org/license     New BSD License
32 * @version    6.0.0
33 */
34class AttributeGenerator extends AbstractGenerator
35{
36
37    use Traits\NameTrait;
38
39    /**
40     * Arguments, each shaped ['name' => ?string, 'value' => mixed]
41     * @var array
42     */
43    protected array $arguments = [];
44
45    /**
46     * Constructor
47     *
48     * Instantiate the attribute generator object
49     *
50     * @param  string $name
51     */
52    public function __construct(string $name)
53    {
54        $this->setName($name);
55    }
56
57    /**
58     * Add an argument
59     *
60     * Parameter order is (value, name), not (name, value) like Traits\FunctionTrait::addArgument()
61     * elsewhere in this library — deliberate, since it mirrors ReflectionAttribute::getArguments()'s
62     * own shape (numeric keys positional, string keys named) and makes the common positional case a
63     * single-argument call: addArgument('value') rather than addArgument(null, 'value').
64     *
65     * @param  mixed   $value
66     * @param  ?string $name
67     * @return AttributeGenerator
68     */
69    public function addArgument(mixed $value, ?string $name = null): AttributeGenerator
70    {
71        $this->arguments[] = ['name' => $name, 'value' => $value];
72        return $this;
73    }
74
75    /**
76     * Has arguments
77     *
78     * @return bool
79     */
80    public function hasArguments(): bool
81    {
82        return !empty($this->arguments);
83    }
84
85    /**
86     * Get the arguments
87     *
88     * @return array
89     */
90    public function getArguments(): array
91    {
92        return $this->arguments;
93    }
94
95    /**
96     * Render attribute
97     *
98     * @return string
99     */
100    public function render(): string
101    {
102        $this->output = '#[' . $this->name;
103
104        if (!empty($this->arguments)) {
105            $formatted = [];
106            foreach ($this->arguments as $argument) {
107                $value       = ValueFormatter::format($argument['value'], null, '', true);
108                $formatted[] = ($argument['name'] !== null) ? $argument['name'] . ': ' . $value : $value;
109            }
110            $this->output .= '(' . implode(', ', $formatted) . ')';
111        }
112
113        $this->output .= ']';
114
115        return $this->output;
116    }
117
118    /**
119     * Print attribute
120     *
121     * @return string
122     */
123    public function __toString(): string
124    {
125        return $this->render();
126    }
127
128}