Skip to content

Commit d174d8c

Browse files
committed
Merge branch 'PHP8.1_Support-for-explicit-octal-notation' of https://github.com/MarkBaker/PHP_CodeSniffer
2 parents 878472a + b363a7c commit d174d8c

File tree

5 files changed

+111
-0
lines changed

5 files changed

+111
-0
lines changed

src/Tokenizers/PHP.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,29 @@ protected function tokenize($string)
646646
}//end if
647647
}//end if
648648

649+
/*
650+
For Explicit Octal Notation prior to PHP 8.1 we need to combine the
651+
T_LNUMBER and T_STRING token values into a single token value, and
652+
then ignore the T_STRING token.
653+
*/
654+
655+
if (PHP_VERSION_ID < 80100
656+
&& $tokenIsArray === true && $token[1] === '0'
657+
&& (isset($tokens[($stackPtr + 1)]) === true
658+
&& is_array($tokens[($stackPtr + 1)]) === true
659+
&& $tokens[($stackPtr + 1)][0] === T_STRING
660+
&& strtolower($tokens[($stackPtr + 1)][1][0]) === 'o')
661+
) {
662+
$finalTokens[$newStackPtr] = [
663+
'code' => T_LNUMBER,
664+
'type' => 'T_LNUMBER',
665+
'content' => $token[1] .= $tokens[($stackPtr + 1)][1],
666+
];
667+
$stackPtr++;
668+
$newStackPtr++;
669+
continue;
670+
}
671+
649672
/*
650673
PHP 8.1 introduced two dedicated tokens for the & character.
651674
Retokenizing both of these to T_BITWISE_AND, which is the
@@ -1330,6 +1353,7 @@ protected function tokenize($string)
13301353
if ($newType === T_LNUMBER
13311354
&& ((stripos($newContent, '0x') === 0 && hexdec(str_replace('_', '', $newContent)) > PHP_INT_MAX)
13321355
|| (stripos($newContent, '0b') === 0 && bindec(str_replace('_', '', $newContent)) > PHP_INT_MAX)
1356+
|| (stripos($newContent, '0o') === 0 && octdec(str_replace('_', '', $newContent)) > PHP_INT_MAX)
13331357
|| (stripos($newContent, '0x') !== 0
13341358
&& stripos($newContent, 'e') !== false || strpos($newContent, '.') !== false)
13351359
|| (strpos($newContent, '0') === 0 && stripos($newContent, '0x') !== 0
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
/* testExplicitOctal */
4+
$foo = 0o137041;
5+
6+
/* testExplicitOctal capitalised */
7+
$bar = 0O137041;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
/**
3+
* Tests the tokenization of explicit octal notation to PHP < 8.1.
4+
*
5+
* @author Mark Baker <mark@demon-angel.eu>
6+
* @copyright 2019 Squiz Pty Ltd (ABN 77 084 670 600)
7+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8+
*/
9+
10+
namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
11+
12+
use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest;
13+
14+
class BackfillExplicitOctalNotationTest extends AbstractMethodUnitTest
15+
{
16+
17+
18+
/**
19+
* Test that explicitly-defined octal values are tokenized as a single number and not as a number and a string.
20+
*
21+
* @param array $testData The data required for the specific test case.
22+
*
23+
* @dataProvider dataExplicitOctalNotation
24+
* @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
25+
*
26+
* @return void
27+
*/
28+
public function testExplicitOctalNotation($testData)
29+
{
30+
$tokens = self::$phpcsFile->getTokens();
31+
32+
$number = $this->getTargetToken($testData['marker'], [T_LNUMBER]);
33+
34+
$this->assertSame(constant($testData['type']), $tokens[$number]['code']);
35+
$this->assertSame($testData['type'], $tokens[$number]['type']);
36+
$this->assertSame($testData['value'], $tokens[$number]['content']);
37+
38+
}//end testExplicitOctalNotation()
39+
40+
41+
/**
42+
* Data provider.
43+
*
44+
* @see testExplicitOctalNotation()
45+
*
46+
* @return array
47+
*/
48+
public function dataExplicitOctalNotation()
49+
{
50+
return [
51+
[
52+
[
53+
'marker' => '/* testExplicitOctal */',
54+
'type' => 'T_LNUMBER',
55+
'value' => '0o137041',
56+
],
57+
],
58+
[
59+
[
60+
'marker' => '/* testExplicitOctal capitalised */',
61+
'type' => 'T_LNUMBER',
62+
'value' => '0O137041',
63+
],
64+
],
65+
];
66+
67+
}//end dataExplicitOctalNotation()
68+
69+
70+
}//end class

tests/Core/Tokenizer/BackfillNumericSeparatorTest.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ $foo = 0b0101_1111;
3434
/* testOctal */
3535
$foo = 0137_041;
3636

37+
/* testExplicitOctal */
38+
$foo = 0o137_041;
39+
3740
/* testIntMoreThanMax */
3841
$foo = 10_223_372_036_854_775_807;
3942

tests/Core/Tokenizer/BackfillNumericSeparatorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ public function dataTestBackfill()
132132
'value' => '0137_041',
133133
],
134134
],
135+
[
136+
[
137+
'marker' => '/* testExplicitOctal */',
138+
'type' => 'T_LNUMBER',
139+
'value' => '0o137_041',
140+
],
141+
],
135142
[
136143
[
137144
'marker' => '/* testIntMoreThanMax */',

0 commit comments

Comments
 (0)