Skip to content

Commit

Permalink
Allow using the Type attribute to specify the return type of a functi…
Browse files Browse the repository at this point in the history
…on or method
  • Loading branch information
carlos-granados committed Feb 14, 2024
1 parent e2925ae commit 291a011
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 14 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/vendor/
composer.lock
.phpunit.cache
.phpunit.cache
.idea
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"require": {
"php": ">=8.0",
"nikic/php-parser": "^4 || ^5",
"php-static-analysis/attributes": "^0.1.1 || dev-main"
"php-static-analysis/attributes": "^0.1.2 || dev-main"
},
"require-dev": {
"php-static-analysis/phpstan-extension": "dev-main",
Expand Down
45 changes: 34 additions & 11 deletions src/AttributeNodeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ class AttributeNodeVisitor extends NodeVisitorAbstract
Param::class,
Returns::class,
Template::class,
Type::class,
],
Stmt\Function_::class => [
Param::class,
Returns::class,
Template::class,
Type::class,
],
Stmt\Interface_::class => [
Template::class,
Expand All @@ -72,11 +74,24 @@ class AttributeNodeVisitor extends NodeVisitorAbstract
];

private const ANNOTATION_PER_ATTRIBUTE = [
IsReadOnly::class => 'readonly',
Param::class => 'param',
Returns::class => 'return',
Template::class => 'template',
Type::class => 'var',
IsReadOnly::class => [
'all' => 'readonly',
],
Param::class => [
'all' => 'param',
],
Returns::class => [
'all' => 'return',
],
Template::class => [
'all' => 'template',
],
Type::class => [
Stmt\ClassConst::class => 'var',
Stmt\ClassMethod::class => 'return',
Stmt\Function_::class => 'return',
Stmt\Property::class => 'var',
],
];

private const ARGUMENTS_PER_ATTRIBUTE = [
Expand Down Expand Up @@ -124,24 +139,24 @@ public function enterNode(Node $node)
$tagCreated = false;
switch (self::ARGUMENTS_PER_ATTRIBUTE[$attributeName]) {
case self::ARGS_NONE:
$tagsToAdd[] = $this->createTag($attributeName);
$tagsToAdd[] = $this->createTag($nodeType, $attributeName);
$tagCreated = true;
break;
case self::ARGS_ONE:
if (isset($args[0])) {
$tagsToAdd[] = $this->createTag($attributeName, $args[0]);
$tagsToAdd[] = $this->createTag($nodeType, $attributeName, $args[0]);
$tagCreated = true;
}
break;
case self::ARGS_TWO_WITH_TYPE:
if (isset($args[0])) {
$tagsToAdd[] = $this->createTag($attributeName, $args[0], $args[1] ?? null);
$tagsToAdd[] = $this->createTag($nodeType, $attributeName, $args[0], $args[1] ?? null);
$tagCreated = true;
}
break;
case self::ARGS_MANY_WITH_NAME:
foreach ($args as $arg) {
$tagsToAdd[] = $this->createTag($attributeName, $arg, useName: true);
$tagsToAdd[] = $this->createTag($nodeType, $attributeName, $arg, useName: true);
$tagCreated = true;
}
break;
Expand All @@ -168,7 +183,7 @@ public function enterNode(Node $node)
if ($var instanceof Node\Expr\Variable) {
$name = $var->name;
if (is_string($name)) {
$tagsToAdd[] = $this->createTag($attributeName, $args[0], useName: true, nameToUse: $name);
$tagsToAdd[] = $this->createTag($nodeType, $attributeName, $args[0], useName: true, nameToUse: $name);
$tagCreated = true;
}
}
Expand All @@ -189,13 +204,21 @@ public function enterNode(Node $node)
}

private function createTag(
string $nodeType,
string $attributeName,
Arg $argument = null,
Arg $of = null,
bool $useName = false,
string $nameToUse = null
): string {
$tag = '@' . self::ANNOTATION_PER_ATTRIBUTE[$attributeName];
if (isset(self::ANNOTATION_PER_ATTRIBUTE[$attributeName][$nodeType])) {
$tagName = self::ANNOTATION_PER_ATTRIBUTE[$attributeName][$nodeType];
} elseif (isset(self::ANNOTATION_PER_ATTRIBUTE[$attributeName]['all'])) {
$tagName = self::ANNOTATION_PER_ATTRIBUTE[$attributeName]['all'];
} else {
return '';
}
$tag = '@' . $tagName;
if ($argument) {
$value = $argument->value;
$type = '';
Expand Down
11 changes: 10 additions & 1 deletion tests/AttributeNodeVisitorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ public function testAddsVarPHPDoc(): void
$this->assertEquals("/**\n * @var string\n */", $docText);
}

public function testAddsReturnPHPDocWithTypeAttribute(): void
{
$node = new Node\Stmt\ClassMethod('Test');
$this->addTypeAttributeToNode($node);
$this->nodeVisitor->enterNode($node);
$docText = $this->getDocText($node);
$this->assertEquals("/**\n * @return string\n */", $docText);
}

public function testAddsTemplatePHPDoc(): void
{
$node = new Node\Stmt\Class_('Test');
Expand Down Expand Up @@ -184,7 +193,7 @@ private function addReturnsAttributeToNode(Node\Stmt\ClassMethod $node): void
$node->attrGroups = [new AttributeGroup([$attribute])];
}

private function addTypeAttributeToNode(Node\Stmt\Property $node): void
private function addTypeAttributeToNode(Node\Stmt\Property|Node\Stmt\ClassMethod $node): void
{
$args = [
new Node\Arg(new Node\Scalar\String_('string'))
Expand Down

0 comments on commit 291a011

Please sign in to comment.