Skip to content

Commit 3053135

Browse files
committed
Ensure disjunctive normal form types are handled
1 parent 6385006 commit 3053135

File tree

3 files changed

+189
-4
lines changed

3 files changed

+189
-4
lines changed

src/Tokenizers/PHP.php

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -676,12 +676,60 @@ protected function tokenize($string)
676676
}
677677
}
678678

679-
if (isset($nextNonEmptyToken) === true
680-
&& $tokens[$nextNonEmptyToken] === '('
679+
if ($preserveKeyword === true
681680
&& $token[0] === T_READONLY
681+
&& isset($nextNonEmptyToken) === true
682+
&& $tokens[$nextNonEmptyToken] === '('
682683
) {
683-
$preserveKeyword = false;
684-
}
684+
$foundProperty = false;
685+
$foundDNFCloseParen = false;
686+
$foundDNFPipe = false;
687+
688+
for ($i = ($nextNonEmptyToken + 1); $i < $numTokens; $i++) {
689+
if ($foundDNFCloseParen === false && $tokens[$i] === ')') {
690+
$foundDNFCloseParen = true;
691+
continue;
692+
}
693+
694+
if ($foundDNFCloseParen === true && $foundDNFPipe === false && $tokens[$i] === '|') {
695+
$foundDNFPipe = true;
696+
continue;
697+
}
698+
699+
$stopTokens = [
700+
'{',
701+
'}',
702+
'=',
703+
';',
704+
'|',
705+
':',
706+
',',
707+
'(',
708+
')',
709+
];
710+
if (in_array($tokens[$i], $stopTokens, true) === true) {
711+
// We have finished our search.
712+
break;
713+
}
714+
715+
if ($foundDNFPipe !== true) {
716+
continue;
717+
}
718+
719+
if (is_array($tokens[$i]) === false) {
720+
continue;
721+
}
722+
723+
if ($tokens[$i][0] === T_VARIABLE) {
724+
$foundProperty = true;
725+
break;
726+
}
727+
}//end for
728+
729+
if ($foundProperty === false) {
730+
$preserveKeyword = false;
731+
}
732+
}//end if
685733

686734
if ($preserveKeyword === false) {
687735
if (PHP_CODESNIFFER_VERBOSITY > 1) {

tests/Core/Tokenizer/BackfillReadonlyTest.inc

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,63 @@ echo ClassName::READONLY;
9595
/* testReadonlyUsedAsFunctionCallWithSpaceBetweenKeywordAndParens */
9696
$var = readonly /* comment */ ();
9797

98+
// These test cases are inspired by
99+
// https://github.com/php/php-src/commit/08b75395838b4b42a41e3c70684fa6c6b113eee0
100+
class Dnf
101+
{
102+
/* testDNFPropertyReadonlyPublicABC */
103+
readonly public A|(B&C) $a;
104+
/* testDNFPropertyReadonlyPublicBCA */
105+
readonly public (B&C)|A $b;
106+
107+
/* testDNFPropertyReadonlyProtectedABC */
108+
readonly protected A|(B&C) $c;
109+
/* testDNFPropertyReadonlyProtectedBCA */
110+
readonly protected (B&C)|A $d;
111+
112+
/* testDNFPropertyReadonlyPrivateABC */
113+
readonly private A|(B&C) $e;
114+
/* testDNFPropertyReadonlyPrivateBCA */
115+
readonly private (B&C)|A $f;
116+
117+
/* testDNFPropertyReadonlyABC */
118+
readonly A|(B&C) $g;
119+
/* testDNFPropertyReadonlyBCA */
120+
readonly (B&C)|A $h;
121+
122+
/* testDNFPropertyPublicReadonlyABC */
123+
public readonly A|(B&C) $i;
124+
/* testDNFPropertyPublicReadonlyBCA */
125+
public readonly (B&C)|A $j;
126+
127+
/* testDNFPropertyProtectedReadonlyABC */
128+
protected readonly A|(B&C) $k;
129+
/* testDNFPropertyProtectedReadonlyBCA */
130+
protected readonly (B&C)|A $l;
131+
132+
/* testDNFPropertyPrivateReadonlyABC */
133+
private readonly A|(B&C) $m;
134+
/* testDNFPropertyPrivateReadonlyBCA */
135+
private readonly (B&C)|A $n;
136+
137+
/* testDNFPropertyPrivateReadonlyB_space_CA */
138+
private readonly (B & C)|A $o;
139+
/* testDNFPropertyPrivateReadonlyBC_space_A */
140+
private readonly (B&C) | A $p;
141+
/* testDNFPropertyPrivateReadonlyB_space_C_space_A */
142+
private readonly (B & C) | A $q;
143+
144+
/* testDNFMethodAB */
145+
public function readonly (A&B $param): void {}
146+
147+
public function __construct(
148+
/* testDNFPropertyPromotionABC */
149+
private readonly A|(B&C) $a1,
150+
/* testDNFPropertyPromotionBCA */
151+
private readonly (B&C)|A $b1,
152+
) {}
153+
}
154+
98155
/* testParseErrorLiveCoding */
99156
// This must be the last test in the file.
100157
readonly

tests/Core/Tokenizer/BackfillReadonlyTest.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,82 @@ public function dataReadonly()
147147
'/* testReadonlyPropertyInAnonymousClass */',
148148
'readonly',
149149
],
150+
[
151+
'/* testDNFPropertyReadonlyPublicABC */',
152+
'readonly',
153+
],
154+
[
155+
'/* testDNFPropertyReadonlyPublicBCA */',
156+
'readonly',
157+
],
158+
[
159+
'/* testDNFPropertyReadonlyProtectedABC */',
160+
'readonly',
161+
],
162+
[
163+
'/* testDNFPropertyReadonlyProtectedBCA */',
164+
'readonly',
165+
],
166+
[
167+
'/* testDNFPropertyReadonlyPrivateABC */',
168+
'readonly',
169+
],
170+
[
171+
'/* testDNFPropertyReadonlyPrivateBCA */',
172+
'readonly',
173+
],
174+
[
175+
'/* testDNFPropertyReadonlyABC */',
176+
'readonly',
177+
],
178+
[
179+
'/* testDNFPropertyReadonlyBCA */',
180+
'readonly',
181+
],
182+
[
183+
'/* testDNFPropertyPublicReadonlyABC */',
184+
'readonly',
185+
],
186+
[
187+
'/* testDNFPropertyPublicReadonlyBCA */',
188+
'readonly',
189+
],
190+
[
191+
'/* testDNFPropertyProtectedReadonlyABC */',
192+
'readonly',
193+
],
194+
[
195+
'/* testDNFPropertyProtectedReadonlyBCA */',
196+
'readonly',
197+
],
198+
[
199+
'/* testDNFPropertyPrivateReadonlyABC */',
200+
'readonly',
201+
],
202+
[
203+
'/* testDNFPropertyPrivateReadonlyBCA */',
204+
'readonly',
205+
],
206+
[
207+
'/* testDNFPropertyPrivateReadonlyB_space_CA */',
208+
'readonly',
209+
],
210+
[
211+
'/* testDNFPropertyPrivateReadonlyBC_space_A */',
212+
'readonly',
213+
],
214+
[
215+
'/* testDNFPropertyPrivateReadonlyB_space_C_space_A */',
216+
'readonly',
217+
],
218+
[
219+
'/* testDNFPropertyPromotionABC */',
220+
'readonly',
221+
],
222+
[
223+
'/* testDNFPropertyPromotionBCA */',
224+
'readonly',
225+
],
150226
[
151227
'/* testParseErrorLiveCoding */',
152228
'readonly',
@@ -228,6 +304,10 @@ public function dataNotReadonly()
228304
'/* testClassConstantFetchWithReadonlyAsConstantName */',
229305
'READONLY',
230306
],
307+
[
308+
'/* testDNFMethodAB */',
309+
'readonly',
310+
],
231311
];
232312

233313
}//end dataNotReadonly()

0 commit comments

Comments
 (0)