Skip to content

Commit

Permalink
add static variable initializers support (#366)
Browse files Browse the repository at this point in the history
  • Loading branch information
llaville committed Dec 31, 2023
1 parent 9ece759 commit 1ae8fca
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 5 deletions.
2 changes: 1 addition & 1 deletion docs/components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ They are grouped by categories to solve PHP features (from 4.0 to 8.2)
- Constants (5)
- ControlStructures (4)
- Enumerations (1)
- Expressions (3)
- Expressions (4)
- Fibers (1)
- FunctionCalls (1)
- FunctionDeclarations (7)
Expand Down
10 changes: 6 additions & 4 deletions docs/components/sniffs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,14 @@ 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 |
|----------------|-------------------------|---------------------------------------------|
| Attributes | OverrideAttributeSniff | [Override attribute][OverrideAttribute] |
| Constants | TypedClassConstantSniff | [Typed Class Constants][TypedClassConstant] |
| Sniff category | Sniff class name | PHP Feature |
|----------------|---------------------------|------------------------------------------------------|
| Attributes | OverrideAttributeSniff | [Override attribute][OverrideAttribute] |
| Constants | TypedClassConstantSniff | [Typed Class Constants][TypedClassConstant] |
| Expressions | StaticVarInitializerSniff | [Static Variable initializers][StaticVarInitializer] |

[OverrideAttribute]: https://www.php.net/releases/8.3/en.php#override_attribute
[StaticVarInitializer]: https://www.php.net/manual/en/migration83.new-features.php#migration83.new-features.core.static-variable-initializers
[TypedClassConstant]: https://www.php.net/releases/8.3/en.php#typed_class_constants

## Special cases
Expand Down
59 changes: 59 additions & 0 deletions src/Application/Sniffs/Expressions/StaticVarInitializerSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?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\Expressions;

use Bartlett\CompatInfo\Application\Sniffs\SniffAbstract;

use Generator;
use PhpParser\Node;

/**
* Static variable initializers available since PHP 8.3.0 alpha1
*
* @author Laurent Laville
* @since Class available since Release 7.1.0
*
* @link https://wiki.php.net/rfc/arbitrary_static_variable_initializers
* @see tests/Sniffs/StaticVarInitializerSniffTest
*/
final class StaticVarInitializerSniff extends SniffAbstract
{
// Rules identifiers for SARIF report
private const CA83 = 'CA8303';

/**
* @inheritDoc
*/
public function getRules(): Generator
{
yield self::CA83 => [
'name' => $this->getShortClass(),
'fullDescription' => "Static variable initializers syntax is available since PHP 8.3.0",
'helpUri' => '%baseHelpUri%/01_Components/03_Sniffs/Features/#php-83',
];
}

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

if ($node->default instanceof Node\Expr\CallLike && !$node->default instanceof Node\Expr\New_) {
if (!$parent = $node->getAttribute($this->attributeParentKeyStore)) {
return null;
}
$this->updateNodeElementVersion($parent, $this->attributeKeyStore, ['php.min' => '8.3.0alpha1']);
$this->updateNodeElementRule($parent, $this->attributeKeyStore, self::CA83);
}
return null;
}
}
50 changes: 50 additions & 0 deletions tests/Sniffs/StaticVarInitializerSniffTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?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;

/**
* Unit test case for Static variable initializers
*
* @author Laurent Laville
* @since Class available since Release 7.1.0
*
* @link https://wiki.php.net/rfc/arbitrary_static_variable_initializers
*/
final class StaticVarInitializerSniffTest extends SniffTestCase
{
/**
* @inheritDoc
*/
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();

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

/**
* Feature test to detect static variable initializers
*
* @group features
* @return void
* @throws Exception
*/
public function testStaticVariableInitializer()
{
$dataSource = 'static_var_initializer.php';
$metrics = $this->executeAnalysis($dataSource);
$functions = $metrics[self::$analyserId]['functions'];

$this->assertEquals(
'8.3.0alpha1',
$functions['foo']['php.min']
);
}
}
9 changes: 9 additions & 0 deletions tests/fixtures/sniffs/expressions/static_var_initializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
function bar() {
return 1;
}

function foo() {
static $i = bar();
echo $i++, "\n";
}

0 comments on commit 1ae8fca

Please sign in to comment.