Skip to content

Commit

Permalink
Ensure disjunctive normal form types are handled
Browse files Browse the repository at this point in the history
  • Loading branch information
fredden committed Jun 8, 2023
1 parent 6385006 commit f324e5c
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 4 deletions.
60 changes: 56 additions & 4 deletions src/Tokenizers/PHP.php
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,10 @@ protected function tokenize($string)
echo PHP_EOL;
}

if (PHP_VERSION_ID < 802000 && $token[0] === T_STRING && strtolower($token[1]) === 'readonly') {
$token[0] = T_READONLY;
}

/*
Tokenize context-sensitive keyword as string when it should be string.
*/
Expand Down Expand Up @@ -676,12 +680,60 @@ protected function tokenize($string)
}
}

if (isset($nextNonEmptyToken) === true
&& $tokens[$nextNonEmptyToken] === '('
if ($preserveKeyword === true
&& $token[0] === T_READONLY
&& isset($nextNonEmptyToken) === true
&& $tokens[$nextNonEmptyToken] === '('
) {
$preserveKeyword = false;
}
$foundProperty = false;
$foundDNFCloseParen = false;
$foundDNFPipe = false;

for ($i = ($nextNonEmptyToken + 1); $i < $numTokens; $i++) {
if ($foundDNFCloseParen === false && $tokens[$i] === ')') {
$foundDNFCloseParen = true;
continue;
}

if ($foundDNFCloseParen === true && $foundDNFPipe === false && $tokens[$i] === '|') {
$foundDNFPipe = true;
continue;
}

$stopTokens = [
'{',
'}',
'=',
';',
'|',
':',
',',
'(',
')',
];
if (in_array($tokens[$i], $stopTokens, true) === true) {
// We have finished our search.
break;
}

if ($foundDNFPipe !== true) {
continue;
}

if (is_array($tokens[$i]) === false) {
continue;
}

if ($tokens[$i][0] === T_VARIABLE) {
$foundProperty = true;
break;
}
}//end for

if ($foundProperty === false) {
$preserveKeyword = false;
}
}//end if

if ($preserveKeyword === false) {
if (PHP_CODESNIFFER_VERBOSITY > 1) {
Expand Down
57 changes: 57 additions & 0 deletions tests/Core/Tokenizer/BackfillReadonlyTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,63 @@ echo ClassName::READONLY;
/* testReadonlyUsedAsFunctionCallWithSpaceBetweenKeywordAndParens */
$var = readonly /* comment */ ();

// These test cases are inspired by
// https://github.com/php/php-src/commit/08b75395838b4b42a41e3c70684fa6c6b113eee0
class Dnf
{
/* testDNFPropertyReadonlyPublicABC */
readonly public A|(B&C) $a;
/* testDNFPropertyReadonlyPublicBCA */
readonly public (B&C)|A $b;

/* testDNFPropertyReadonlyProtectedABC */
readonly protected A|(B&C) $c;
/* testDNFPropertyReadonlyProtectedBCA */
readonly protected (B&C)|A $d;

/* testDNFPropertyReadonlyPrivateABC */
readonly private A|(B&C) $e;
/* testDNFPropertyReadonlyPrivateBCA */
readonly private (B&C)|A $f;

/* testDNFPropertyReadonlyABC */
readonly A|(B&C) $g;
/* testDNFPropertyReadonlyBCA */
readonly (B&C)|A $h;

/* testDNFPropertyPublicReadonlyABC */
public readonly A|(B&C) $i;
/* testDNFPropertyPublicReadonlyBCA */
public readonly (B&C)|A $j;

/* testDNFPropertyProtectedReadonlyABC */
protected readonly A|(B&C) $k;
/* testDNFPropertyProtectedReadonlyBCA */
protected readonly (B&C)|A $l;

/* testDNFPropertyPrivateReadonlyABC */
private readonly A|(B&C) $m;
/* testDNFPropertyPrivateReadonlyBCA */
private readonly (B&C)|A $n;

/* testDNFPropertyPrivateReadonlyB_space_CA */
private readonly (B & C)|A $o;
/* testDNFPropertyPrivateReadonlyBC_space_A */
private readonly (B&C) | A $p;
/* testDNFPropertyPrivateReadonlyB_space_C_space_A */
private readonly (B & C) | A $q;

/* testDNFMethodAB */
public function readonly (A&B $param): void {}

public function __construct(
/* testDNFPropertyPromotionABC */
private readonly A|(B&C) $a1,
/* testDNFPropertyPromotionBCA */
private readonly (B&C)|A $b1,
) {}
}

/* testParseErrorLiveCoding */
// This must be the last test in the file.
readonly
80 changes: 80 additions & 0 deletions tests/Core/Tokenizer/BackfillReadonlyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,82 @@ public function dataReadonly()
'/* testReadonlyPropertyInAnonymousClass */',
'readonly',
],
[
'/* testDNFPropertyReadonlyPublicABC */',
'readonly',
],
[
'/* testDNFPropertyReadonlyPublicBCA */',
'readonly',
],
[
'/* testDNFPropertyReadonlyProtectedABC */',
'readonly',
],
[
'/* testDNFPropertyReadonlyProtectedBCA */',
'readonly',
],
[
'/* testDNFPropertyReadonlyPrivateABC */',
'readonly',
],
[
'/* testDNFPropertyReadonlyPrivateBCA */',
'readonly',
],
[
'/* testDNFPropertyReadonlyABC */',
'readonly',
],
[
'/* testDNFPropertyReadonlyBCA */',
'readonly',
],
[
'/* testDNFPropertyPublicReadonlyABC */',
'readonly',
],
[
'/* testDNFPropertyPublicReadonlyBCA */',
'readonly',
],
[
'/* testDNFPropertyProtectedReadonlyABC */',
'readonly',
],
[
'/* testDNFPropertyProtectedReadonlyBCA */',
'readonly',
],
[
'/* testDNFPropertyPrivateReadonlyABC */',
'readonly',
],
[
'/* testDNFPropertyPrivateReadonlyBCA */',
'readonly',
],
[
'/* testDNFPropertyPrivateReadonlyB_space_CA */',
'readonly',
],
[
'/* testDNFPropertyPrivateReadonlyBC_space_A */',
'readonly',
],
[
'/* testDNFPropertyPrivateReadonlyB_space_C_space_A */',
'readonly',
],
[
'/* testDNFPropertyPromotionABC */',
'readonly',
],
[
'/* testDNFPropertyPromotionBCA */',
'readonly',
],
[
'/* testParseErrorLiveCoding */',
'readonly',
Expand Down Expand Up @@ -228,6 +304,10 @@ public function dataNotReadonly()
'/* testClassConstantFetchWithReadonlyAsConstantName */',
'READONLY',
],
[
'/* testDNFMethodAB */',
'readonly',
],
];

}//end dataNotReadonly()
Expand Down

0 comments on commit f324e5c

Please sign in to comment.