Skip to content

Commit

Permalink
Ignore PHP8 attributes (#907)
Browse files Browse the repository at this point in the history
Fix the issue of PHP8 attributes located between docblock and the
referenced property/method/class causing the token parser to drop the
docblock.
  • Loading branch information
DerManoMann committed Mar 2, 2021
1 parent 320ae56 commit 77fee10
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 12 deletions.
25 changes: 25 additions & 0 deletions src/StaticAnalyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ protected function fromTokens(array $tokens, Context $parseContext): Analysis
continue;
}

if ($token[0] === T_ATTRIBUTE) {
// consume
$this->parseAttribute($tokens, $token, $parseContext);
continue;
}

if ($token[0] === T_DOC_COMMENT) {
if ($comment) {
// 2 Doc-comments in succession?
Expand Down Expand Up @@ -420,6 +426,25 @@ private function nextToken(array &$tokens, Context $context)
}
}

private function parseAttribute(array &$tokens, &$token, Context $parseContext): void
{
$nesting = 1;
while ($token !== false) {
$token = $this->nextToken($tokens, $parseContext);
if (!is_array($token) && '[' === $token) {
++$nesting;
continue;
}

if (!is_array($token) && ']' === $token) {
--$nesting;
if (!$nesting) {
break;
}
}
}
}

/**
* Parse namespaced string.
*/
Expand Down
14 changes: 14 additions & 0 deletions tests/Fixtures/StaticAnalyser/Label.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php declare(strict_types=1);

namespace OpenApi\Tests\Fixtures\StaticAnalyser;

#[Attribute]
class Label
{
protected $name;

public function __construct(string $name, array $numbers)
{
$this->name = $name;
}
}
21 changes: 21 additions & 0 deletions tests/Fixtures/StaticAnalyser/Php8AttrMix.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types=1);

namespace OpenApi\Tests\Fixtures\StaticAnalyser;

/**
* @OA\Schema()
*/
class Php8AttrMix
{
#[label('Id', [1])]
/** @OA\Property() */
public string $id = '';

/** @OA\Property() */
#[
label('OtherId', [2, 3]),
label('OtherId', [2, 3]),
]
public string $otherId = '';

}
22 changes: 10 additions & 12 deletions tests/Fixtures/StaticAnalyser/php7.php
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
<?php declare(strict_types=1);

namespace OpenApi\Tests\Fixtures;
namespace OpenApi\Tests\Fixtures\StaticAnalyser;

$o = new class
interface foo
{
}

$o = new class {
public function foo()
{
}
};

$o = new class extends stdClass
{
$o = new class extends \stdClass {
};

$o = new class implements foo
{
$o = new class implements foo {
};

$o = new class()
{
$o = new class() {
public function foo()
{
}
};

$o = new class() extends stdClass
{
$o = new class() extends \stdClass {
};

$o = new class() implements foo
{
$o = new class() implements foo {
};
2 changes: 2 additions & 0 deletions tests/Fixtures/StaticAnalyser/routes.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php declare(strict_types=1);

namespace OpenApi\Tests\Fixtures\StaticAnalyser;

//
// Allow indentation with tab(s).
//
Expand Down
17 changes: 17 additions & 0 deletions tests/StaticAnalyserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace OpenApi\Tests;

use OpenApi\Analyser;
use OpenApi\Annotations\Property;
use OpenApi\Annotations\Schema;
use OpenApi\Context;
use OpenApi\StaticAnalyser;
Expand Down Expand Up @@ -228,4 +229,20 @@ public function testNamespacedConstAccess()
$this->assertCount(1, $schemas);
$this->assertEquals(User::CONSTANT, $schemas[0]->example);
}

/**
* @requires PHP 8
*/
public function testPhp8AttributeMix()
{
$analysis = $this->analysisFromFixtures('StaticAnalyser/Php8AttrMix.php');
$schemas = $analysis->getAnnotationsOfType(Schema::class, true);

$this->assertCount(1, $schemas);
$analysis->process();
$properties = $analysis->getAnnotationsOfType(Property::class, true);
$this->assertCount(2, $properties);
$this->assertEquals('id', $properties[0]->property);
$this->assertEquals('otherId', $properties[1]->property);
}
}

0 comments on commit 77fee10

Please sign in to comment.