Skip to content

Commit

Permalink
Detect promoted properties (#1049)
Browse files Browse the repository at this point in the history
  • Loading branch information
DerManoMann authored Jan 1, 2022
1 parent 2bc19e4 commit 47bc50f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
46 changes: 45 additions & 1 deletion src/Analysers/TokenScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,18 @@ protected function scanTokens(array $tokens): array
$token = $this->nextToken($tokens);

if (($unitLevel + 1) == count($stack) && $currentName) {
$units[$currentName]['methods'][] = $token[1];
if (!$isInterface) {
// more nesting
$units[$currentName]['properties'] = array_merge(
$units[$currentName]['properties'],
$this->parsePromotedProperties($tokens)
);
$this->skipTo($tokens, '{', true);
} else {
// no function body
$this->skipTo($tokens, ';');
}
$units[$currentName]['methods'][] = $token[1];
}
break;

Expand Down Expand Up @@ -295,4 +299,44 @@ protected function parseFQNStatement(array &$tokens, &$token): array

return $statements;
}

protected function parsePromotedProperties(array &$tokens): array
{
$properties = [];

$this->skipTo($tokens, '(');
$round = 1;
$promoted = false;
while (false !== ($token = $this->nextToken($tokens))) {
if (is_string($token)) {
switch ($token) {
case '(':
++$round;
break;
case ')':
--$round;
if (0 == $round) {
return $properties;
}
}
}
if (is_array($token)) {
switch ($token[0]) {
case T_PUBLIC:
case T_PROTECTED:
case T_PRIVATE:
$promoted = true;
break;
case T_VARIABLE:
if ($promoted) {
$properties[] = ltrim($token[1], '$');
$promoted = false;
}
break;
}
}
}

return $properties;
}
}
7 changes: 5 additions & 2 deletions tests/Analysers/TokenScannerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,14 @@ public function scanCases()
'PHP/Php8NamedProperty.php',
[
'OpenApi\\Tests\\Fixtures\\PHP\\Php8NamedProperty' => [
'uses' => ['Label' => 'OpenApi\\Tests\\Fixtures\\PHP\\Label'],
'uses' => [
'Label' => 'OpenApi\\Tests\\Fixtures\\PHP\\Label',
'Property' => 'OpenApi\\Attributes\\Property',
],
'interfaces' => [],
'traits' => [],
'methods' => ['__construct'],
'properties' => [],
'properties' => ['labels', 'id'],
],
],
],
Expand Down
5 changes: 4 additions & 1 deletion tests/Fixtures/PHP/Php8NamedProperty.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace OpenApi\Tests\Fixtures\PHP;

use OpenApi\Attributes\Property;
use OpenApi\Tests\Fixtures\PHP\Label;

/**
Expand All @@ -20,7 +21,9 @@ public function __construct(
* @var Label[]|null $labels
* @OA\Property()
*/
public ?array $labels
public ?array $labels,
#[Property()]
public int $id,
)
{
}
Expand Down

0 comments on commit 47bc50f

Please sign in to comment.