Skip to content

Commit

Permalink
#363 : Allow null, false, and true as stand-alone types
Browse files Browse the repository at this point in the history
  • Loading branch information
llaville committed Nov 14, 2023
1 parent ed2e58c commit 4d26ac6
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
9 changes: 5 additions & 4 deletions docs/01_Components/03_Sniffs/Features.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,11 @@ Here is the list of features supported and their corresponding sniffs :

## [PHP 8.2](https://www.php.net/manual/en/migration82.php)

| Sniff category | Sniff class name | PHP Feature |
|----------------------|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------|
| Classes | ReadonlyClassSniff | [Readonly Classes](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly) |
| FunctionDeclarations | ParamTypeDeclarationSniff | [Disjunctive Normal Form Types](https://www.php.net/manual/en/migration82.new-features.php#migration82.new-features.core.type-system) |
| Sniff category | Sniff class name | PHP Feature |
|----------------------|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------|
| Classes | ReadonlyClassSniff | [Readonly Classes](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly) |
| FunctionDeclarations | ParamTypeDeclarationSniff | [Disjunctive Normal Form Types](https://www.php.net/manual/en/migration82.new-features.php#migration82.new-features.core.type-system) |
| FunctionDeclarations | ReturnTypeDeclarationSniff | [Allow null, false, and true as stand-alone types](https://wiki.php.net/rfc/true-type) |

## Special cases

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
use PhpParser\Node;

use Generator;
use function in_array;
use function strcasecmp;

/**
* Return Type Declarations since PHP 7.0.0 alpha1
Expand All @@ -22,6 +24,8 @@
* @link https://wiki.php.net/rfc/return_types
* @link https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.return-type-declarations
* @link https://www.php.net/releases/8.1/en.php#never_return_type
* @link https://wiki.php.net/rfc/null-false-standalone-types
* @link https://wiki.php.net/rfc/true-type
* @see tests/Sniffs/ReturnTypeDeclarationSniffTest
*/
final class ReturnTypeDeclarationSniff extends SniffAbstract
Expand All @@ -30,6 +34,7 @@ final class ReturnTypeDeclarationSniff extends SniffAbstract
private const CA70 = 'CA7001';
private const CA8105 = 'CA8105';
private const CA8106 = 'CA8106';
private const CA8202 = 'CA8202';

/**
* {@inheritDoc}
Expand Down Expand Up @@ -59,6 +64,11 @@ public function enterNode(Node $node)
// @link https://wiki.php.net/rfc/noreturn_type
$min = '8.1.0alpha1';
$ruleId = self::CA8106;
} elseif ($returnType instanceof Node\Identifier && in_array($returnType->name, ['null', 'false', 'true'])) {
// @link https://wiki.php.net/rfc/null-false-standalone-types
// @link https://wiki.php.net/rfc/true-type
$min = '8.2.0alpha1';
$ruleId = self::CA8202;
} else {
$min = '7.0.0alpha1';
$ruleId = self::CA70;
Expand Down Expand Up @@ -88,6 +98,11 @@ public function getRules(): Generator
'fullDescription' => 'Return Never Type Declaration is available since PHP 8.1.0',
'helpUri' => '%baseHelpUri%/01_Components/03_Sniffs/Features/#php-81',
];
yield self::CA8202 => [
'name' => $this->getShortClass(),
'fullDescription' => 'Null False and True Type Declaration are available since PHP 8.2.0',
'helpUri' => '%baseHelpUri%/01_Components/03_Sniffs/Features/#php-82',
];
}

private function hasReturnType(Node $node): bool
Expand Down
32 changes: 32 additions & 0 deletions tests/Sniffs/ReturnTypeDeclarationSniffTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
* @link https://github.com/llaville/php-compat-info/issues/273
* @link https://www.php.net/releases/8.1/en.php#pure_intersection_types
* @link https://wiki.php.net/rfc/pure-intersection-types
* @link https://wiki.php.net/rfc/null-false-standalone-types
* @link https://wiki.php.net/rfc/true-type
*/
final class ReturnTypeDeclarationSniffTest extends SniffTestCase
{
Expand Down Expand Up @@ -172,4 +174,34 @@ public function testNeverReturnType()
$functions['redirect']['php.min']
);
}

/**
* Feature test for return null, false or true type
*
* @link https://github.com/llaville/php-compatinfo/issues/363
* @link https://wiki.php.net/rfc/null-false-standalone-types
* @link https://wiki.php.net/rfc/true-type
* @group features
* @return void
* @throws Exception
*/
public function testNullOrBooleanReturnType()
{
$dataSource = 'return_null_bool.php';
$metrics = $this->executeAnalysis($dataSource);
$functions = $metrics[self::$analyserId]['methods'];

$this->assertEquals(
'8.2.0alpha1',
$functions['Falsy\alwaysFalse']['php.min']
);
$this->assertEquals(
'8.2.0alpha1',
$functions['Falsy\alwaysTrue']['php.min']
);
$this->assertEquals(
'8.2.0alpha1',
$functions['Falsy\alwaysNull']['php.min']
);
}
}
10 changes: 10 additions & 0 deletions tests/fixtures/sniffs/functions/return_null_bool.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

class Falsy
{
public function alwaysFalse(): false { /* ... */ *}

public function alwaysTrue(): true { /* ... */ *}

public function alwaysNull(): null { /* ... */ *}
}

0 comments on commit 4d26ac6

Please sign in to comment.