-
-
Notifications
You must be signed in to change notification settings - Fork 440
Expand file tree
/
Copy pathArrayItemNodeAnnotationToAttributeMapper.php
More file actions
91 lines (73 loc) · 2.8 KB
/
ArrayItemNodeAnnotationToAttributeMapper.php
File metadata and controls
91 lines (73 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?php
declare(strict_types=1);
namespace Rector\PhpAttribute\AnnotationToAttributeMapper;
use PhpParser\Node\ArrayItem;
use PhpParser\Node\Expr;
use PhpParser\Node\Scalar\String_;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\BetterPhpDocParser\PhpDoc\StringNode;
use Rector\PhpAttribute\AnnotationToAttributeMapper;
use Rector\PhpAttribute\Contract\AnnotationToAttributeMapperInterface;
use Rector\PhpAttribute\Enum\DocTagNodeState;
use Rector\Validation\RectorAssert;
use Webmozart\Assert\InvalidArgumentException;
/**
* @implements AnnotationToAttributeMapperInterface<ArrayItemNode>
*/
final class ArrayItemNodeAnnotationToAttributeMapper implements AnnotationToAttributeMapperInterface
{
private AnnotationToAttributeMapper $annotationToAttributeMapper;
/**
* Avoid circular reference
*/
public function autowire(AnnotationToAttributeMapper $annotationToAttributeMapper): void
{
$this->annotationToAttributeMapper = $annotationToAttributeMapper;
}
public function isCandidate(mixed $value): bool
{
return $value instanceof ArrayItemNode;
}
/**
* @param ArrayItemNode $arrayItemNode
*/
public function map($arrayItemNode): ArrayItem
{
$valueExpr = $this->annotationToAttributeMapper->map($arrayItemNode->value);
if ($valueExpr === DocTagNodeState::REMOVE_ARRAY) {
return new ArrayItem(new String_($valueExpr));
}
if ($arrayItemNode->key !== null) {
/** @var Expr $keyExpr */
$keyExpr = $this->annotationToAttributeMapper->map($arrayItemNode->key);
} else {
if ($this->hasNoParenthesesAnnotation($arrayItemNode)) {
try {
RectorAssert::className(ltrim((string) $arrayItemNode->value, '@'));
$identifierTypeNode = new IdentifierTypeNode($arrayItemNode->value);
$arrayItemNode->value = new DoctrineAnnotationTagValueNode($identifierTypeNode);
return $this->map($arrayItemNode);
} catch (InvalidArgumentException) {
}
}
$keyExpr = null;
}
// @todo how to skip natural integer keys?
return new ArrayItem($valueExpr, $keyExpr);
}
private function hasNoParenthesesAnnotation(ArrayItemNode $arrayItemNode): bool
{
if ($arrayItemNode->value instanceof StringNode) {
return false;
}
if (! is_string($arrayItemNode->value)) {
return false;
}
if (! str_starts_with($arrayItemNode->value, '@')) {
return false;
}
return ! str_ends_with($arrayItemNode->value, ')');
}
}