Skip to content

Commit

Permalink
update: 调整重写顺序依赖问题
Browse files Browse the repository at this point in the history
  • Loading branch information
NHZEX committed Nov 2, 2023
1 parent e30807b commit b01dbee
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 35 deletions.
81 changes: 48 additions & 33 deletions src/Visitor/AttributeRewriteVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ public function enterNode(Node $node): void
}
// 设置顶级类
$this->topClassReflection = $reflection;
$this->parseClassComments();
break;
case $node instanceof Node\Stmt\Use_:
foreach ($node->uses as $use)
Expand Down Expand Up @@ -161,19 +162,45 @@ public function leaveNode(Node $node): ?Node

return match (true)
{
$node instanceof Node\Stmt\ClassLike => $this->generateClass(/* @var $node Node\Stmt\ClassLike */ $node),
$node instanceof Node\Stmt\ClassLike => $this->rewriteClass(/* @var $node Node\Stmt\ClassLike */ $node),
$node instanceof Node\Stmt\ClassMethod => $this->generateClassMethodAttributes(/* @var $node Node\Stmt\ClassMethod */ $node),
default => null,
};
}

private function generateClass(Node\Stmt\ClassLike $node): ?Node\Stmt\ClassLike
private array $classCommentLines = [];

private function parseClassComments(): void
{
$node = $this->currentClass;

$classCommentDoc = Helper::arrayValueLast($node->getComments());
$classCommentText = $classCommentDoc?->getText();

$this->classCommentLines = $this->parseCommentsProperty($classCommentText);
}

private function rewriteClass(Node\Stmt\ClassLike $node): ?Node\Stmt\ClassLike
{
if ($this->debug)
{
$this->logger->debug("> Class: {$node->name}");
}

$classCommentLines = array_filter(
$this->classCommentLines,
static fn ($line) => !('property' !== $line['kind'] && (str_contains($line['raw'], '@Annotation') || str_contains($line['raw'], '@Target'))),
);
if ($this->handleCode->isModified() || $this->classCommentLines !== $classCommentLines)
{
$classCommentLines = array_column($classCommentLines, 'raw');

$newClassCommentText = "/**\n" . implode("\n", $classCommentLines) . "\n */";
$node->setDocComment(new Doc($newClassCommentText));

$this->handleCode->setModified();
}

$newStmts = [];
foreach ($node->stmts as $stmt)
{
Expand Down Expand Up @@ -263,33 +290,27 @@ protected function migrationConstruct(Node\Stmt\ClassMethod $node): Node\Stmt\Cl
}
}

$classCommentDoc = Helper::arrayValueLast($this->currentClass->getComments());
$classComments = $classCommentDoc?->getText();
// $classCommentDoc = Helper::arrayValueLast($this->currentClass->getComments());
// $classComments = $classCommentDoc?->getText();

if ($isModified)
{
// 重写类属性注解
$classCommentsLines = $this->parseCommentsProperty($classComments);
$newClassComments = $this->refactorCommentsProperty($classCommentsLines, $newParams);
$this->classCommentLines = $this->refactorCommentsProperty($this->classCommentLines, $newParams);

if ($newClassComments !== $classComments)
// 重写方法注解
$methodCommentDoc = Helper::arrayValueLast($node->getComments());
$methodComments = $methodCommentDoc?->getText();
if ($methodComments)
{
$this->currentClass->setDocComment(new Doc($newClassComments));

// 重写方法注解
$methodCommentDoc = Helper::arrayValueLast($node->getComments());
$methodComments = $methodCommentDoc?->getText();
if ($methodComments)
$methodComments = $this->cleanAnnotationFromComments($methodComments, $newParams);
if (self::isEmptyComments(explode("\n", $methodComments)))
{
$methodComments = $this->cleanAnnotationFromComments($methodComments, $newParams);
if (self::isEmptyComments(explode("\n", $methodComments)))
{
$node->setDocComment(new Doc(''));
}
else
{
$node->setDocComment(new Doc($methodComments));
}
$node->setDocComment(new Doc(''));
}
else
{
$node->setDocComment(new Doc($methodComments));
}
}

Expand Down Expand Up @@ -371,7 +392,7 @@ protected function parseCommentsProperty(string $comments): array
* }> $comments
* @param array<Node\Param> $props
*/
protected function refactorCommentsProperty(array $comments, array $props): ?string
protected function refactorCommentsProperty(array $comments, array $props): array
{
$classComments = [];

Expand All @@ -386,20 +407,14 @@ protected function refactorCommentsProperty(array $comments, array $props): ?str
{
if ('property' !== $comment['kind'])
{
if (
str_contains($comment['raw'], '@Annotation')
|| str_contains($comment['raw'], '@Target')
) {
continue;
}
$classComments[] = $comment['raw'];
$classComments[] = $comment;
continue;
}
$meta = $comment['meta'];
$prop = $propsMap[$meta['name']] ?? null;
if (empty($prop))
{
$classComments[] = $comment['raw'];
$classComments[] = $comment;
continue;
}
$commentPropMap[$meta['name']] = $comment;
Expand Down Expand Up @@ -432,7 +447,7 @@ protected function refactorCommentsProperty(array $comments, array $props): ?str
}
}

return "/**\n" . implode("\n", $classComments) . "\n*/";
return $classComments;
}

/**
Expand Down Expand Up @@ -464,6 +479,6 @@ protected function cleanAnnotationFromComments(string $comments, array $props):
}
}

return "/**\n" . implode("\n", $newComments) . "\n*/";
return "/**\n" . implode("\n", $newComments) . "\n */";
}
}
28 changes: 26 additions & 2 deletions tests/AttributeRewriteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static function rewriteCodeDataProvider(): \Generator
*
*
*
*/
*/
#[\Attribute(\Attribute::TARGET_CLASS)]
class TestConsumer extends Base
{
Expand Down Expand Up @@ -128,7 +128,7 @@ public function __construct(
*
*
*
*/
*/
#[\Attribute(\Attribute::TARGET_PROPERTY)]
class TestConstruct extends Base
{
Expand All @@ -151,5 +151,29 @@ public function __construct(
}
PHP,
];

yield 'class_comment' => [
__DIR__ . '/StubAttribute/TestClassComment.php',
<<<PHP
<?php
declare (strict_types=1);
namespace Imiphp\Tests\StubAttribute;
use Imi\Bean\Annotation\Base;
/**
* 回调注解.
*
*
*
* @property string|object \$class 类名,或者传入对象
* @property string \$method 方法名
*/
#[\Attribute(\Attribute::TARGET_PROPERTY)]
class TestClassComment extends Base
{
}
PHP,
];
}
}
22 changes: 22 additions & 0 deletions tests/StubAttribute/TestClassComment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Imiphp\Tests\StubAttribute;

use Imi\Bean\Annotation\Base;

/**
* 回调注解.
*
* @Annotation
*
* @Target({"PROPERTY", "ANNOTATION"})
*
* @property string|object $class 类名,或者传入对象
* @property string $method 方法名
*/
#[\Attribute(\Attribute::TARGET_PROPERTY)]
class TestClassComment extends Base
{
}

0 comments on commit b01dbee

Please sign in to comment.