|
6 | 6 |
|
7 | 7 | use PhpParser\Node; |
8 | 8 | use PhpParser\Node\Attribute; |
| 9 | +use PhpParser\Node\AttributeGroup; |
9 | 10 | use PhpParser\Node\Param; |
10 | 11 | use PhpParser\Node\Stmt\Class_; |
11 | 12 | use PhpParser\Node\Stmt\ClassMethod; |
12 | 13 | use PhpParser\Node\Stmt\Function_; |
13 | 14 | use PhpParser\Node\Stmt\Interface_; |
14 | 15 | use PhpParser\Node\Stmt\Property; |
| 16 | +use PHPStan\Analyser\Scope; |
15 | 17 | use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; |
16 | 18 | use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; |
17 | 19 | use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; |
18 | 20 | use Rector\Comments\NodeDocBlock\DocBlockUpdater; |
19 | 21 | use Rector\Contract\Rector\ConfigurableRectorInterface; |
20 | 22 | use Rector\DowngradePhp80\ValueObject\DowngradeAttributeToAnnotation; |
21 | 23 | use Rector\NodeFactory\DoctrineAnnotationFactory; |
| 24 | +use Rector\NodeTypeResolver\Node\AttributeKey; |
22 | 25 | use Rector\Rector\AbstractRector; |
23 | 26 | use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; |
24 | 27 | use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; |
@@ -107,22 +110,21 @@ public function refactor(Node $node): ?Node |
107 | 110 | $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); |
108 | 111 | $oldTokens = $this->file->getOldTokens(); |
109 | 112 |
|
| 113 | + $node->getAttribute(AttributeKey::SCOPE); |
| 114 | + |
110 | 115 | foreach ($node->attrGroups as $attrGroup) { |
111 | 116 | foreach ($attrGroup->attrs as $key => $attribute) { |
112 | 117 | if ($this->shouldSkipAttribute($attribute)) { |
113 | 118 | if (isset($oldTokens[$attrGroup->getEndTokenPos() + 1]) && ! str_contains( |
114 | 119 | (string) $oldTokens[$attrGroup->getEndTokenPos() + 1], |
115 | 120 | "\n" |
116 | 121 | )) { |
117 | | - if ($node->getStartTokenPos() === strlen($attribute->name->toString()) - 2) { |
118 | | - $indentation = ''; |
119 | | - } else { |
120 | | - $indent = $attrGroup->getEndTokenPos() - $node->getStartTokenPos() + 2; |
121 | | - $indentation = $indent > 0 ? str_repeat(' ', $indent) : ''; |
122 | | - } |
123 | | - |
124 | 122 | // add new line |
125 | | - $oldTokens[$attrGroup->getEndTokenPos() + 1]->text = "\n" . $indentation . $oldTokens[$attrGroup->getEndTokenPos() + 1]->text; |
| 123 | + $oldTokens[$attrGroup->getEndTokenPos() + 1]->text = "\n" . $this->resolveIndentation( |
| 124 | + $node, |
| 125 | + $attrGroup, |
| 126 | + $attribute |
| 127 | + ) . $oldTokens[$attrGroup->getEndTokenPos() + 1]->text; |
126 | 128 | $this->isDowngraded = true; |
127 | 129 | } |
128 | 130 |
|
@@ -179,6 +181,25 @@ public function configure(array $configuration): void |
179 | 181 | $this->attributesToAnnotations = $configuration; |
180 | 182 | } |
181 | 183 |
|
| 184 | + private function resolveIndentation(Node $node, AttributeGroup $attributeGroup, Attribute $attribute): string |
| 185 | + { |
| 186 | + $scope = $node->getAttribute(AttributeKey::SCOPE); |
| 187 | + |
| 188 | + if (! $scope instanceof Scope) { |
| 189 | + return ''; |
| 190 | + } |
| 191 | + |
| 192 | + if ( |
| 193 | + ($node->getStartTokenPos() === strlen($attribute->name->toString()) - 2) |
| 194 | + || ($node instanceof Class_ && $scope->isInFirstLevelStatement()) |
| 195 | + ) { |
| 196 | + return ''; |
| 197 | + } |
| 198 | + |
| 199 | + $indent = $attributeGroup->getEndTokenPos() - $node->getStartTokenPos() + 2; |
| 200 | + return $indent > 0 ? str_repeat(' ', $indent) : ''; |
| 201 | + } |
| 202 | + |
182 | 203 | private function cleanupEmptyAttrGroups( |
183 | 204 | ClassMethod | Property | Class_ | Interface_ | Param | Function_ $node |
184 | 205 | ): void { |
|
0 commit comments