Skip to content

Commit 1c7bd16

Browse files
committed
Merge branch 'feature/2791-tokenizer-issue-static-vs-typed-properties' of https://github.com/jrfnl/PHP_CodeSniffer
2 parents eae1b6e + 603d9c6 commit 1c7bd16

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

src/Standards/PSR12/Tests/Functions/NullableTypeDeclarationUnitTest.inc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,19 @@ class TestTokenizingOfNullableVsInlineThen {
6666
}
6767
}
6868

69+
// Issue #2641.
6970
$foo = new static(
7071
is_null($a) ? foo($a) : $a,
7172
is_null($b) ? $b : $c
7273
);
74+
75+
// Issue #2791.
76+
class testInstanceOf() {
77+
function testIt() {
78+
$foo = $value instanceof static ? '(' . $value . ')' : $value;
79+
$bar = $value instanceof static ? function_call($value) : $value;
80+
$baz = $value instanceof static ? array($value) : $value;
81+
$bal = $value instanceof static ? \className::$property : $value;
82+
$bal = $value instanceof static ? CONSTANT_NAME : $value;
83+
}
84+
}

src/Standards/PSR12/Tests/Functions/NullableTypeDeclarationUnitTest.inc.fixed

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,19 @@ class TestTokenizingOfNullableVsInlineThen {
6464
}
6565
}
6666

67+
// Issue #2641.
6768
$foo = new static(
6869
is_null($a) ? foo($a) : $a,
6970
is_null($b) ? $b : $c
7071
);
72+
73+
// Issue #2791.
74+
class testInstanceOf() {
75+
function testIt() {
76+
$foo = $value instanceof static ? '(' . $value . ')' : $value;
77+
$bar = $value instanceof static ? function_call($value) : $value;
78+
$baz = $value instanceof static ? array($value) : $value;
79+
$bal = $value instanceof static ? \className::$property : $value;
80+
$bal = $value instanceof static ? CONSTANT_NAME : $value;
81+
}
82+
}

src/Tokenizers/PHP.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,65 @@ protected function tokenize($string)
10381038
$newToken = [];
10391039
$newToken['content'] = '?';
10401040

1041+
/*
1042+
* Check if the next non-empty token is one of the tokens which can be used
1043+
* in type declarations. If not, it's definitely a ternary.
1044+
* At this point, the only token types which need to be taken into consideration
1045+
* as potential type declarations are T_STRING, T_ARRAY, T_CALLABLE and T_NS_SEPARATOR.
1046+
*/
1047+
1048+
$lastRelevantNonEmpty = null;
1049+
1050+
for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
1051+
if (is_array($tokens[$i]) === true) {
1052+
$tokenType = $tokens[$i][0];
1053+
} else {
1054+
$tokenType = $tokens[$i];
1055+
}
1056+
1057+
if (isset(Util\Tokens::$emptyTokens[$tokenType]) === true) {
1058+
continue;
1059+
}
1060+
1061+
if ($tokenType === T_STRING
1062+
|| $tokenType === T_ARRAY
1063+
|| $tokenType === T_NS_SEPARATOR
1064+
) {
1065+
$lastRelevantNonEmpty = $tokenType;
1066+
continue;
1067+
}
1068+
1069+
if (($tokenType !== T_CALLABLE
1070+
&& isset($lastRelevantNonEmpty) === false)
1071+
|| ($lastRelevantNonEmpty === T_ARRAY
1072+
&& $tokenType === '(')
1073+
|| ($lastRelevantNonEmpty === T_STRING
1074+
&& ($tokenType === T_DOUBLE_COLON
1075+
|| $tokenType === '('
1076+
|| $tokenType === ':'))
1077+
) {
1078+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
1079+
echo "\t\t* token $stackPtr changed from ? to T_INLINE_THEN".PHP_EOL;
1080+
}
1081+
1082+
$newToken['code'] = T_INLINE_THEN;
1083+
$newToken['type'] = 'T_INLINE_THEN';
1084+
1085+
$insideInlineIf[] = $stackPtr;
1086+
1087+
$finalTokens[$newStackPtr] = $newToken;
1088+
$newStackPtr++;
1089+
continue 2;
1090+
}
1091+
1092+
break;
1093+
}//end for
1094+
1095+
/*
1096+
* This can still be a nullable type or a ternary.
1097+
* Do additional checking.
1098+
*/
1099+
10411100
$prevNonEmpty = null;
10421101
$lastSeenNonEmpty = null;
10431102

0 commit comments

Comments
 (0)