Skip to content

Commit

Permalink
Return types properly with disjunctive normal form
Browse files Browse the repository at this point in the history
  • Loading branch information
fredden committed Mar 18, 2024
1 parent f627b49 commit f6a6111
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
19 changes: 19 additions & 0 deletions PHPCSUtils/Utils/FunctionDeclarations.php
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,12 @@ public static function getParameters(File $phpcsFile, $stackPtr)
* still be a valid assumption.
*/
|| $tokens[$i]['code'] === \T_STATIC
/*
* Disjunctive Normal Form uses a single pipe operator.
* This is not always tokenized as a union type.
* That bug is likely to be solved as part of https://github.com/PHPCSStandards/PHP_CodeSniffer/issues/387
*/
|| $tokens[$i]['code'] === \T_BITWISE_OR
) {
if ($typeHintToken === false) {
$typeHintToken = $i;
Expand Down Expand Up @@ -495,6 +501,19 @@ public static function getParameters(File $phpcsFile, $stackPtr)
$readonlyToken = $i;
break;

case \T_OPEN_PARENTHESIS:
// Disjunctive Normal Form
if ($typeHintToken === false) {
$typeHintToken = $i;
}

$dnfCloser = $tokens[$i]['parenthesis_closer'];
for ($j = $i; $j <= $dnfCloser; $j++) {
$typeHint .= $tokens[$j]['content'];
}
$typeHintEndToken = $i = $dnfCloser;
break;

case \T_CLOSE_PARENTHESIS:
case \T_COMMA:
// If it's null, then there must be no parameters for this
Expand Down
9 changes: 9 additions & 0 deletions Tests/BackCompat/BCFile/GetMethodParametersTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,15 @@ function() use(
/* testInvalidUse */
function() use {}; // Intentional parse error.

/* testDisjunctiveNormalForm */
function disjunctiveNormalForm(
A|(B&C) $one,
(A&B)|C $two,
A|(B&C)|(D&E&F)|G|null $three,
A&B $four,
(A&B) $five
) {}

/* testArrowFunctionLiveCoding */
// Intentional parse error. This has to be the last test in the file.
$fn = fn
89 changes: 89 additions & 0 deletions Tests/Utils/FunctionDeclarations/GetParametersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,95 @@ public function testNoParams($commentString, $targetTokenType = [\T_FUNCTION, \T
$this->assertSame([], $result);
}

/**
* Verify Disjunctive Normal Form parameter types work as expected.
*
* @return void
*/
public function testDisjunctiveNormalForm()
{
// Offsets are relative to the T_FUNCTION token.
$expected = [
[
'token' => 14,
'name' => '$one',
'content' => 'A|(B&C) $one',
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => 'A|(B&C)',
'type_hint_token' => 6,
'type_hint_end_token' => 12,
'nullable_type' => false,
'comma_token' => 15,
],
[
'token' => 26,
'name' => '$two',
'content' => '(A&B)|C $two',
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => '(A&B)|C',
'type_hint_token' => 18,
'type_hint_end_token' => 24,
'nullable_type' => false,
'comma_token' => 27,
],
[
'token' => 50,
'name' => '$three',
'content' => 'A|(B&C)|(D&E&F)|G|null $three',
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => 'A|(B&C)|(D&E&F)|G|null',
'type_hint_token' => 30,
'type_hint_end_token' => 48,
'nullable_type' => false,
'comma_token' => 51,
],
[
'token' => 58,
'name' => '$four',
'content' => 'A&B $four',
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => 'A&B',
'type_hint_token' => 54,
'type_hint_end_token' => 56,
'nullable_type' => false,
'comma_token' => 59,
],
[
'token' => 68,
'name' => '$five',
'content' => '(A&B) $five',
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => '(A&B)',
'type_hint_token' => 62,
'type_hint_end_token' => 66,
'nullable_type' => false,
'comma_token' => false,
],
];

$this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected);
}

/**
* Test helper.
*
Expand Down

0 comments on commit f6a6111

Please sign in to comment.