Skip to content

Commit

Permalink
add Typed Class Constants support (#366)
Browse files Browse the repository at this point in the history
  • Loading branch information
llaville committed Dec 31, 2023
1 parent b837f76 commit a7b1526
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ They are grouped by categories to solve PHP features (from 4.0 to 8.2)
- Arrays (3)
- Attributes (3)
- Classes (11)
- Constants (4)
- Constants (5)
- ControlStructures (4)
- Enumerations (1)
- Expressions (3)
Expand Down
7 changes: 5 additions & 2 deletions docs/components/sniffs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,11 @@ Here is the list of features supported and their corresponding sniffs :

## [PHP 8.3](https://www.php.net/manual/en/migration83.php)

| Sniff category | Sniff class name | PHP Feature |
|----------------------|----------------------------------------------|-----------------------------------------------------------------------------------------|
| Sniff category | Sniff class name | PHP Feature |
|----------------|-------------------------|---------------------------------------------|
| Constants | TypedClassConstantSniff | [Typed Class Constants][TypedClassConstant] |

[TypedClassConstant]: https://www.php.net/releases/8.3/en.php#typed_class_constants

## Special cases

Expand Down
56 changes: 56 additions & 0 deletions src/Application/Sniffs/Constants/TypedClassConstantSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php declare(strict_types=1);
/**
* This file is part of the PHP_CompatInfo package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Bartlett\CompatInfo\Application\Sniffs\Constants;

use Bartlett\CompatInfo\Application\Sniffs\SniffAbstract;

use PhpParser\Node;

use Generator;

/**
* Typed hinting class constants has been introduced in PHP 8.3
*
* @author Laurent Laville
* @since Release 7.1.0
*
* @see tests/Sniffs/TypedClassConstantSniffTest
*/
final class TypedClassConstantSniff extends SniffAbstract
{
// Rules identifiers for SARIF report
private const CA83 = 'CA8301';

/**
* @inheritDoc
*/
public function enterNode(Node $node)
{
if (!$node instanceof Node\Stmt\ClassConst) {
return null;
}

if ($node->type instanceof Node\Identifier) {
$this->updateNodeElementVersion($node, $this->attributeKeyStore, ['php.min' => '8.3.0alpha1']);
$this->updateNodeElementRule($node, $this->attributeKeyStore, self::CA83);
}
return null;
}

/**
* @inheritDoc
*/
public function getRules(): Generator
{
yield self::CA83 => [
'name' => $this->getShortClass(),
'fullDescription' => "Type hinting class constants has been introduced in PHP 8.3.0",
'helpUri' => '%baseHelpUri%/01_Components/03_Sniffs/Features/#php-83',
];
}
}
83 changes: 83 additions & 0 deletions tests/Sniffs/TypedClassConstantSniffTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php declare(strict_types=1);
/**
* This file is part of the PHP_CompatInfo package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Bartlett\CompatInfo\Tests\Sniffs;

use Exception;

/**
* Typed Class constants
*
* @author Laurent Laville
* @since Class available since Release 7.1.0
*
* @link https://wiki.php.net/rfc/typed_class_constants
* @link https://php.watch/versions/8.3/typed-constants
* @link https://stitcher.io/blog/new-in-php-83#typed-class-constants-rfc
*/
class TypedClassConstantSniffTest extends SniffTestCase
{
/**
* @inheritDoc
*/
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();

self::$fixtures .= 'constants' . DIRECTORY_SEPARATOR;
}

/**
* Data Provider to test Typed Class Constants
*
* @return iterable
*/
public static function typedConstantsProvider(): iterable
{
$provides = [
'typed_const.php' => [
'Test\FOO' => [
'php.min' => '8.3.0alpha1',
],
'Test\GARPLY' => [
'php.min' => '8.3.0alpha1',
],
'Test\WALDO' => [
'php.min' => '8.3.0alpha1',
],
],
];

foreach ($provides as $filename => $versions) {
yield [$filename, $versions];
}
}

/**
* Feature test for typed class constants
*
* @link https://github.com/llaville/php-compatinfo/issues/366
* Typed class constants are detected as PHP 8.3
* @link https://github.com/php/php-src/commit/414f71a90254cc33896bb3ba953f979f743c198c
* @group features
* @dataProvider typedConstantsProvider
* @return void
* @throws Exception
*/
public function testTypedClassConstants(string $dataSource, array $expectedVersions)
{
$metrics = $this->executeAnalysis($dataSource);
$constants = $metrics[self::$analyserId]['constants'];

foreach ($expectedVersions as $name => $versions) {
$this->assertArrayHasKey($name, $constants);
foreach ($versions as $key => $value) {
$this->assertEquals($value, $constants[$name][$key]);
}
}
}
}
10 changes: 10 additions & 0 deletions tests/fixtures/sniffs/constants/typed_const.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

class Test
{
const string FOO = 'test';

protected const string GARPLY = 'test';

final protected const string WALDO = 'test';
}

0 comments on commit a7b1526

Please sign in to comment.