diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 9185cd41b0..54be7ba686 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -139,7 +139,7 @@
- tests/Core/Tokenizer/StableCommentWhitespaceWinTest\.php
+ tests/Core/Tokenizer/PHP/StableCommentWhitespaceWinTest\.php
diff --git a/tests/Core/Tokenizer/AnonClassParenthesisOwnerTest.inc b/tests/Core/Tokenizer/PHP/AnonClassParenthesisOwnerTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/AnonClassParenthesisOwnerTest.inc
rename to tests/Core/Tokenizer/PHP/AnonClassParenthesisOwnerTest.inc
diff --git a/tests/Core/Tokenizer/AnonClassParenthesisOwnerTest.php b/tests/Core/Tokenizer/PHP/AnonClassParenthesisOwnerTest.php
similarity index 98%
rename from tests/Core/Tokenizer/AnonClassParenthesisOwnerTest.php
rename to tests/Core/Tokenizer/PHP/AnonClassParenthesisOwnerTest.php
index 79eb742e19..5277dade14 100644
--- a/tests/Core/Tokenizer/AnonClassParenthesisOwnerTest.php
+++ b/tests/Core/Tokenizer/PHP/AnonClassParenthesisOwnerTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class AnonClassParenthesisOwnerTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/ArrayKeywordTest.inc b/tests/Core/Tokenizer/PHP/ArrayKeywordTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/ArrayKeywordTest.inc
rename to tests/Core/Tokenizer/PHP/ArrayKeywordTest.inc
diff --git a/tests/Core/Tokenizer/ArrayKeywordTest.php b/tests/Core/Tokenizer/PHP/ArrayKeywordTest.php
similarity index 85%
rename from tests/Core/Tokenizer/ArrayKeywordTest.php
rename to tests/Core/Tokenizer/PHP/ArrayKeywordTest.php
index c6dac85978..37528d6d70 100644
--- a/tests/Core/Tokenizer/ArrayKeywordTest.php
+++ b/tests/Core/Tokenizer/PHP/ArrayKeywordTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class ArrayKeywordTest extends AbstractTokenizerTestCase
{
@@ -21,7 +23,6 @@ final class ArrayKeywordTest extends AbstractTokenizerTestCase
*
* @dataProvider dataArrayKeyword
* @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
- * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::createTokenMap
*
* @return void
*/
@@ -35,10 +36,6 @@ public function testArrayKeyword($testMarker, $testContent='array')
$this->assertSame(T_ARRAY, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_ARRAY (code)');
$this->assertSame('T_ARRAY', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_ARRAY (type)');
- $this->assertArrayHasKey('parenthesis_owner', $tokenArray, 'Parenthesis owner is not set');
- $this->assertArrayHasKey('parenthesis_opener', $tokenArray, 'Parenthesis opener is not set');
- $this->assertArrayHasKey('parenthesis_closer', $tokenArray, 'Parenthesis closer is not set');
-
}//end testArrayKeyword()
@@ -84,7 +81,6 @@ public static function dataArrayKeyword()
*
* @dataProvider dataArrayType
* @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
- * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::createTokenMap
*
* @return void
*/
@@ -98,10 +94,6 @@ public function testArrayType($testMarker, $testContent='array')
$this->assertSame(T_STRING, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (code)');
$this->assertSame('T_STRING', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (type)');
- $this->assertArrayNotHasKey('parenthesis_owner', $tokenArray, 'Parenthesis owner is set');
- $this->assertArrayNotHasKey('parenthesis_opener', $tokenArray, 'Parenthesis opener is set');
- $this->assertArrayNotHasKey('parenthesis_closer', $tokenArray, 'Parenthesis closer is set');
-
}//end testArrayType()
@@ -163,7 +155,6 @@ public static function dataArrayType()
*
* @dataProvider dataNotArrayKeyword
* @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
- * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::createTokenMap
*
* @return void
*/
@@ -177,10 +168,6 @@ public function testNotArrayKeyword($testMarker, $testContent='array')
$this->assertSame(T_STRING, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (code)');
$this->assertSame('T_STRING', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (type)');
- $this->assertArrayNotHasKey('parenthesis_owner', $tokenArray, 'Parenthesis owner is set');
- $this->assertArrayNotHasKey('parenthesis_opener', $tokenArray, 'Parenthesis opener is set');
- $this->assertArrayNotHasKey('parenthesis_closer', $tokenArray, 'Parenthesis closer is set');
-
}//end testNotArrayKeyword()
diff --git a/tests/Core/Tokenizer/AttributesTest.inc b/tests/Core/Tokenizer/PHP/AttributesTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/AttributesTest.inc
rename to tests/Core/Tokenizer/PHP/AttributesTest.inc
diff --git a/tests/Core/Tokenizer/AttributesTest.php b/tests/Core/Tokenizer/PHP/AttributesTest.php
similarity index 99%
rename from tests/Core/Tokenizer/AttributesTest.php
rename to tests/Core/Tokenizer/PHP/AttributesTest.php
index 764a9bef42..24b7f07953 100644
--- a/tests/Core/Tokenizer/AttributesTest.php
+++ b/tests/Core/Tokenizer/PHP/AttributesTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class AttributesTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/BackfillEnumTest.inc b/tests/Core/Tokenizer/PHP/BackfillEnumTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/BackfillEnumTest.inc
rename to tests/Core/Tokenizer/PHP/BackfillEnumTest.inc
diff --git a/tests/Core/Tokenizer/BackfillEnumTest.php b/tests/Core/Tokenizer/PHP/BackfillEnumTest.php
similarity index 98%
rename from tests/Core/Tokenizer/BackfillEnumTest.php
rename to tests/Core/Tokenizer/PHP/BackfillEnumTest.php
index 3ce48f6553..d97a90b807 100644
--- a/tests/Core/Tokenizer/BackfillEnumTest.php
+++ b/tests/Core/Tokenizer/PHP/BackfillEnumTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class BackfillEnumTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc b/tests/Core/Tokenizer/PHP/BackfillExplicitOctalNotationTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc
rename to tests/Core/Tokenizer/PHP/BackfillExplicitOctalNotationTest.inc
diff --git a/tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.php b/tests/Core/Tokenizer/PHP/BackfillExplicitOctalNotationTest.php
similarity index 97%
rename from tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.php
rename to tests/Core/Tokenizer/PHP/BackfillExplicitOctalNotationTest.php
index ffa03cc884..64c82be3e4 100644
--- a/tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.php
+++ b/tests/Core/Tokenizer/PHP/BackfillExplicitOctalNotationTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class BackfillExplicitOctalNotationTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/BackfillFnTokenTest.inc b/tests/Core/Tokenizer/PHP/BackfillFnTokenTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/BackfillFnTokenTest.inc
rename to tests/Core/Tokenizer/PHP/BackfillFnTokenTest.inc
diff --git a/tests/Core/Tokenizer/BackfillFnTokenTest.php b/tests/Core/Tokenizer/PHP/BackfillFnTokenTest.php
similarity index 99%
rename from tests/Core/Tokenizer/BackfillFnTokenTest.php
rename to tests/Core/Tokenizer/PHP/BackfillFnTokenTest.php
index 194a85102d..2632337a5c 100644
--- a/tests/Core/Tokenizer/BackfillFnTokenTest.php
+++ b/tests/Core/Tokenizer/PHP/BackfillFnTokenTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class BackfillFnTokenTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/BackfillMatchTokenTest.inc b/tests/Core/Tokenizer/PHP/BackfillMatchTokenTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/BackfillMatchTokenTest.inc
rename to tests/Core/Tokenizer/PHP/BackfillMatchTokenTest.inc
diff --git a/tests/Core/Tokenizer/BackfillMatchTokenTest.php b/tests/Core/Tokenizer/PHP/BackfillMatchTokenTest.php
similarity index 99%
rename from tests/Core/Tokenizer/BackfillMatchTokenTest.php
rename to tests/Core/Tokenizer/PHP/BackfillMatchTokenTest.php
index 9f7df35402..42076c0422 100644
--- a/tests/Core/Tokenizer/BackfillMatchTokenTest.php
+++ b/tests/Core/Tokenizer/PHP/BackfillMatchTokenTest.php
@@ -8,8 +8,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
final class BackfillMatchTokenTest extends AbstractTokenizerTestCase
diff --git a/tests/Core/Tokenizer/BackfillNumericSeparatorTest.inc b/tests/Core/Tokenizer/PHP/BackfillNumericSeparatorTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/BackfillNumericSeparatorTest.inc
rename to tests/Core/Tokenizer/PHP/BackfillNumericSeparatorTest.inc
diff --git a/tests/Core/Tokenizer/BackfillNumericSeparatorTest.php b/tests/Core/Tokenizer/PHP/BackfillNumericSeparatorTest.php
similarity index 99%
rename from tests/Core/Tokenizer/BackfillNumericSeparatorTest.php
rename to tests/Core/Tokenizer/PHP/BackfillNumericSeparatorTest.php
index b27dd8a059..53146730c7 100644
--- a/tests/Core/Tokenizer/BackfillNumericSeparatorTest.php
+++ b/tests/Core/Tokenizer/PHP/BackfillNumericSeparatorTest.php
@@ -7,8 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
final class BackfillNumericSeparatorTest extends AbstractTokenizerTestCase
diff --git a/tests/Core/Tokenizer/BackfillReadonlyTest.inc b/tests/Core/Tokenizer/PHP/BackfillReadonlyTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/BackfillReadonlyTest.inc
rename to tests/Core/Tokenizer/PHP/BackfillReadonlyTest.inc
diff --git a/tests/Core/Tokenizer/BackfillReadonlyTest.php b/tests/Core/Tokenizer/PHP/BackfillReadonlyTest.php
similarity index 99%
rename from tests/Core/Tokenizer/BackfillReadonlyTest.php
rename to tests/Core/Tokenizer/PHP/BackfillReadonlyTest.php
index 0befb47b75..7756afaf08 100644
--- a/tests/Core/Tokenizer/BackfillReadonlyTest.php
+++ b/tests/Core/Tokenizer/PHP/BackfillReadonlyTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class BackfillReadonlyTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/BitwiseOrTest.inc b/tests/Core/Tokenizer/PHP/BitwiseOrTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/BitwiseOrTest.inc
rename to tests/Core/Tokenizer/PHP/BitwiseOrTest.inc
diff --git a/tests/Core/Tokenizer/BitwiseOrTest.php b/tests/Core/Tokenizer/PHP/BitwiseOrTest.php
similarity index 98%
rename from tests/Core/Tokenizer/BitwiseOrTest.php
rename to tests/Core/Tokenizer/PHP/BitwiseOrTest.php
index ade73e1af4..0648d61323 100644
--- a/tests/Core/Tokenizer/BitwiseOrTest.php
+++ b/tests/Core/Tokenizer/PHP/BitwiseOrTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class BitwiseOrTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/ContextSensitiveKeywordsTest.inc b/tests/Core/Tokenizer/PHP/ContextSensitiveKeywordsTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/ContextSensitiveKeywordsTest.inc
rename to tests/Core/Tokenizer/PHP/ContextSensitiveKeywordsTest.inc
diff --git a/tests/Core/Tokenizer/ContextSensitiveKeywordsTest.php b/tests/Core/Tokenizer/PHP/ContextSensitiveKeywordsTest.php
similarity index 99%
rename from tests/Core/Tokenizer/ContextSensitiveKeywordsTest.php
rename to tests/Core/Tokenizer/PHP/ContextSensitiveKeywordsTest.php
index f70b9caa89..57eb349546 100644
--- a/tests/Core/Tokenizer/ContextSensitiveKeywordsTest.php
+++ b/tests/Core/Tokenizer/PHP/ContextSensitiveKeywordsTest.php
@@ -7,8 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
final class ContextSensitiveKeywordsTest extends AbstractTokenizerTestCase
diff --git a/tests/Core/Tokenizer/DNFTypesTest.inc b/tests/Core/Tokenizer/PHP/DNFTypesTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/DNFTypesTest.inc
rename to tests/Core/Tokenizer/PHP/DNFTypesTest.inc
diff --git a/tests/Core/Tokenizer/DNFTypesTest.php b/tests/Core/Tokenizer/PHP/DNFTypesTest.php
similarity index 83%
rename from tests/Core/Tokenizer/DNFTypesTest.php
rename to tests/Core/Tokenizer/PHP/DNFTypesTest.php
index a0474e2fd0..cdbe1314a1 100644
--- a/tests/Core/Tokenizer/DNFTypesTest.php
+++ b/tests/Core/Tokenizer/PHP/DNFTypesTest.php
@@ -7,8 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
final class DNFTypesTest extends AbstractTokenizerTestCase
@@ -18,17 +19,16 @@ final class DNFTypesTest extends AbstractTokenizerTestCase
/**
* Test that parentheses when **not** used in a type declaration are correctly tokenized.
*
- * @param string $testMarker The comment prefacing the target token.
- * @param int|false $owner Optional. The parentheses owner or false when no parentheses owner is expected.
- * @param bool $skipCheckInside Optional. Skip checking correct token type inside the parentheses.
- * Use judiciously for combined normal + DNF tests only.
+ * @param string $testMarker The comment prefacing the target token.
+ * @param bool $skipCheckInside Optional. Skip checking correct token type inside the parentheses.
+ * Use judiciously for combined normal + DNF tests only.
*
* @dataProvider dataNormalParentheses
- * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::createParenthesisNestingMap
+ * @covers PHP_CodeSniffer\Tokenizers\PHP::processAdditional
*
* @return void
*/
- public function testNormalParentheses($testMarker, $owner=false, $skipCheckInside=false)
+ public function testNormalParentheses($testMarker, $skipCheckInside=false)
{
$tokens = $this->phpcsFile->getTokens();
@@ -39,17 +39,6 @@ public function testNormalParentheses($testMarker, $owner=false, $skipCheckInsid
$this->assertSame(T_OPEN_PARENTHESIS, $opener['code'], 'Token tokenized as '.$opener['type'].', not T_OPEN_PARENTHESIS (code)');
$this->assertSame('T_OPEN_PARENTHESIS', $opener['type'], 'Token tokenized as '.$opener['type'].', not T_OPEN_PARENTHESIS (type)');
- if ($owner !== false) {
- $this->assertArrayHasKey('parenthesis_owner', $opener, 'Parenthesis owner is not set');
- $this->assertSame(($openPtr + $owner), $opener['parenthesis_owner'], 'Opener parenthesis owner is not the expected token');
- } else {
- $this->assertArrayNotHasKey('parenthesis_owner', $opener, 'Parenthesis owner is set');
- }
-
- $this->assertArrayHasKey('parenthesis_opener', $opener, 'Parenthesis opener is not set');
- $this->assertArrayHasKey('parenthesis_closer', $opener, 'Parenthesis closer is not set');
- $this->assertSame($openPtr, $opener['parenthesis_opener'], 'Parenthesis opener is not the expected token');
-
$closePtr = $opener['parenthesis_closer'];
$closer = $tokens[$closePtr];
@@ -57,22 +46,7 @@ public function testNormalParentheses($testMarker, $owner=false, $skipCheckInsid
$this->assertSame(T_CLOSE_PARENTHESIS, $closer['code'], 'Token tokenized as '.$closer['type'].', not T_CLOSE_PARENTHESIS (code)');
$this->assertSame('T_CLOSE_PARENTHESIS', $closer['type'], 'Token tokenized as '.$closer['type'].', not T_CLOSE_PARENTHESIS (type)');
- if ($owner !== false) {
- $this->assertArrayHasKey('parenthesis_owner', $closer, 'Parenthesis owner is not set');
- $this->assertSame(($openPtr + $owner), $closer['parenthesis_owner'], 'Closer parenthesis owner is not the expected token');
- } else {
- $this->assertArrayNotHasKey('parenthesis_owner', $closer, 'Parenthesis owner is set');
- }
-
- $this->assertArrayHasKey('parenthesis_opener', $closer, 'Parenthesis opener is not set');
- $this->assertArrayHasKey('parenthesis_closer', $closer, 'Parenthesis closer is not set');
- $this->assertSame($closePtr, $closer['parenthesis_closer'], 'Parenthesis closer is not the expected token');
-
for ($i = ($openPtr + 1); $i < $closePtr; $i++) {
- $this->assertArrayHasKey('nested_parenthesis', $tokens[$i], "Nested parenthesis key not set on token $i ({$tokens[$i]['type']})");
- $this->assertArrayHasKey($openPtr, $tokens[$i]['nested_parenthesis'], 'Nested parenthesis is missing target parentheses set');
- $this->assertSame($closePtr, $tokens[$i]['nested_parenthesis'][$openPtr], 'Nested parenthesis closer not set correctly');
-
// If there are ampersands, make sure these are tokenized as bitwise and.
if ($skipCheckInside === false && $tokens[$i]['content'] === '&') {
$this->assertSame(T_BITWISE_AND, $tokens[$i]['code'], 'Token tokenized as '.$tokens[$i]['type'].', not T_BITWISE_AND (code)');
@@ -133,44 +107,36 @@ public static function dataNormalParentheses()
],
'parens with owner: function; & in default value' => [
'testMarker' => '/* testParensOwnerFunctionAmpersandInDefaultValue */',
- 'owner' => -3,
],
'parens with owner: closure; param declared by & ref' => [
'testMarker' => '/* testParensOwnerClosureAmpersandParamRef */',
- 'owner' => -1,
],
'parens with owner: if' => [
'testMarker' => '/* testParensOwnerIf */',
- 'owner' => -2,
],
'parens without owner in if condition' => [
'testMarker' => '/* testParensNoOwnerInIfCondition */',
],
'parens with owner: for' => [
'testMarker' => '/* testParensOwnerFor */',
- 'owner' => -2,
],
'parens without owner in for condition' => [
'testMarker' => '/* testParensNoOwnerInForCondition */',
],
'parens with owner: match' => [
'testMarker' => '/* testParensOwnerMatch */',
- 'owner' => -1,
],
'parens with owner: array' => [
'testMarker' => '/* testParensOwnerArray */',
- 'owner' => -2,
],
'parens without owner in array; function call with & in callable' => [
'testMarker' => '/* testParensNoOwnerFunctionCallWithAmpersandInCallable */',
],
'parens with owner: fn; & in return value' => [
'testMarker' => '/* testParensOwnerArrowFn */',
- 'owner' => -1,
],
'parens with owner: list with reference vars' => [
'testMarker' => '/* testParensOwnerListWithRefVars */',
- 'owner' => -1,
],
'parens without owner, function call with DNF look-a-like param' => [
'testMarker' => '/* testParensNoOwnerFunctionCallwithDNFLookALikeParam */',
@@ -199,11 +165,9 @@ public static function dataNormalParentheses()
],
'parens with owner: closure; & in default value' => [
'testMarker' => '/* testParensOwnerClosureAmpersandInDefaultValue */',
- 'owner' => -2,
],
'parens with owner: fn; dnf used within' => [
'testMarker' => '/* testParensOwnerArrowDNFUsedWithin */',
- 'owner' => -2,
'skipCheckInside' => true,
],
'parens without owner: default value for param in arrow function' => [
@@ -228,7 +192,6 @@ public static function dataNormalParentheses()
*
* @dataProvider dataDNFTypeParentheses
* @covers PHP_CodeSniffer\Tokenizers\PHP::processAdditional
- * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::createParenthesisNestingMap
*
* @return void
*/
@@ -243,11 +206,6 @@ public function testDNFTypeParentheses($testMarker)
$this->assertSame(T_TYPE_OPEN_PARENTHESIS, $opener['code'], 'Token tokenized as '.$opener['type'].', not T_TYPE_OPEN_PARENTHESIS (code)');
$this->assertSame('T_TYPE_OPEN_PARENTHESIS', $opener['type'], 'Token tokenized as '.$opener['type'].', not T_TYPE_OPEN_PARENTHESIS (type)');
- $this->assertArrayNotHasKey('parenthesis_owner', $opener, 'Parenthesis owner is set');
- $this->assertArrayHasKey('parenthesis_opener', $opener, 'Parenthesis opener is not set');
- $this->assertArrayHasKey('parenthesis_closer', $opener, 'Parenthesis closer is not set');
- $this->assertSame($openPtr, $opener['parenthesis_opener'], 'Parenthesis opener is not the expected token');
-
$closePtr = $opener['parenthesis_closer'];
$closer = $tokens[$closePtr];
@@ -255,17 +213,8 @@ public function testDNFTypeParentheses($testMarker)
$this->assertSame(T_TYPE_CLOSE_PARENTHESIS, $closer['code'], 'Token tokenized as '.$closer['type'].', not T_TYPE_CLOSE_PARENTHESIS (code)');
$this->assertSame('T_TYPE_CLOSE_PARENTHESIS', $closer['type'], 'Token tokenized as '.$closer['type'].', not T_TYPE_CLOSE_PARENTHESIS (type)');
- $this->assertArrayNotHasKey('parenthesis_owner', $closer, 'Parenthesis owner is set');
- $this->assertArrayHasKey('parenthesis_opener', $closer, 'Parenthesis opener is not set');
- $this->assertArrayHasKey('parenthesis_closer', $closer, 'Parenthesis closer is not set');
- $this->assertSame($closePtr, $closer['parenthesis_closer'], 'Parenthesis closer is not the expected token');
-
$intersectionCount = 0;
for ($i = ($openPtr + 1); $i < $closePtr; $i++) {
- $this->assertArrayHasKey('nested_parenthesis', $tokens[$i], "Nested parenthesis key not set on token $i ({$tokens[$i]['type']})");
- $this->assertArrayHasKey($openPtr, $tokens[$i]['nested_parenthesis'], 'Nested parenthesis is missing target parentheses set');
- $this->assertSame($closePtr, $tokens[$i]['nested_parenthesis'][$openPtr], 'Nested parenthesis closer not set correctly');
-
if ($tokens[$i]['content'] === '&') {
$this->assertSame(
T_TYPE_INTERSECTION,
diff --git a/tests/Core/Tokenizer/DefaultKeywordTest.inc b/tests/Core/Tokenizer/PHP/DefaultKeywordTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/DefaultKeywordTest.inc
rename to tests/Core/Tokenizer/PHP/DefaultKeywordTest.inc
diff --git a/tests/Core/Tokenizer/PHP/DefaultKeywordTest.php b/tests/Core/Tokenizer/PHP/DefaultKeywordTest.php
new file mode 100644
index 0000000000..c32d337547
--- /dev/null
+++ b/tests/Core/Tokenizer/PHP/DefaultKeywordTest.php
@@ -0,0 +1,255 @@
+
+ * @copyright 2020-2021 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
+
+final class DefaultKeywordTest extends AbstractTokenizerTestCase
+{
+
+
+ /**
+ * Test the retokenization of the `default` keyword for match structure to `T_MATCH_DEFAULT`.
+ *
+ * Note: Cases and default structures within a match structure do *NOT* get case/default scope
+ * conditions, in contrast to case and default structures in switch control structures.
+ *
+ * @param string $testMarker The comment prefacing the target token.
+ * @param string $testContent The token content to look for.
+ *
+ * @dataProvider dataMatchDefault
+ * @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
+ *
+ * @return void
+ */
+ public function testMatchDefault($testMarker, $testContent='default')
+ {
+ $tokens = $this->phpcsFile->getTokens();
+
+ $token = $this->getTargetToken($testMarker, [T_MATCH_DEFAULT, T_DEFAULT, T_STRING], $testContent);
+ $tokenArray = $tokens[$token];
+
+ $this->assertSame(T_MATCH_DEFAULT, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_MATCH_DEFAULT (code)');
+ $this->assertSame('T_MATCH_DEFAULT', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_MATCH_DEFAULT (type)');
+
+ }//end testMatchDefault()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testMatchDefault()
+ *
+ * @return array>
+ */
+ public static function dataMatchDefault()
+ {
+ return [
+ 'simple_match_default' => [
+ 'testMarker' => '/* testSimpleMatchDefault */',
+ ],
+ 'match_default_in_switch_case_1' => [
+ 'testMarker' => '/* testMatchDefaultNestedInSwitchCase1 */',
+ ],
+ 'match_default_in_switch_case_2' => [
+ 'testMarker' => '/* testMatchDefaultNestedInSwitchCase2 */',
+ ],
+ 'match_default_in_switch_default' => [
+ 'testMarker' => '/* testMatchDefaultNestedInSwitchDefault */',
+ ],
+ 'match_default_containing_switch' => [
+ 'testMarker' => '/* testMatchDefault */',
+ ],
+
+ 'match_default_with_nested_long_array_and_default_key' => [
+ 'testMarker' => '/* testMatchDefaultWithNestedLongArrayWithClassConstantKey */',
+ 'testContent' => 'DEFAULT',
+ ],
+ 'match_default_with_nested_long_array_and_default_key_2' => [
+ 'testMarker' => '/* testMatchDefaultWithNestedLongArrayWithClassConstantKeyLevelDown */',
+ 'testContent' => 'DEFAULT',
+ ],
+ 'match_default_with_nested_short_array_and_default_key' => [
+ 'testMarker' => '/* testMatchDefaultWithNestedShortArrayWithClassConstantKey */',
+ 'testContent' => 'DEFAULT',
+ ],
+ 'match_default_with_nested_short_array_and_default_key_2' => [
+ 'testMarker' => '/* testMatchDefaultWithNestedShortArrayWithClassConstantKeyLevelDown */',
+ 'testContent' => 'DEFAULT',
+ ],
+ 'match_default_in_long_array' => [
+ 'testMarker' => '/* testMatchDefaultNestedInLongArray */',
+ 'testContent' => 'DEFAULT',
+ ],
+ 'match_default_in_short_array' => [
+ 'testMarker' => '/* testMatchDefaultNestedInShortArray */',
+ 'testContent' => 'DEFAULT',
+ ],
+ ];
+
+ }//end dataMatchDefault()
+
+
+ /**
+ * Verify that the retokenization of `T_DEFAULT` tokens in match constructs, doesn't negatively
+ * impact the tokenization of `T_DEFAULT` tokens in switch control structures.
+ *
+ * @param string $testMarker The comment prefacing the target token.
+ * @param string $testContent The token content to look for.
+ *
+ * @dataProvider dataSwitchDefault
+ * @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
+ *
+ * @return void
+ */
+ public function testSwitchDefault($testMarker, $testContent='default')
+ {
+ $tokens = $this->phpcsFile->getTokens();
+
+ $token = $this->getTargetToken($testMarker, [T_MATCH_DEFAULT, T_DEFAULT, T_STRING], $testContent);
+ $tokenArray = $tokens[$token];
+
+ $this->assertSame(T_DEFAULT, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_DEFAULT (code)');
+ $this->assertSame('T_DEFAULT', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_DEFAULT (type)');
+
+ }//end testSwitchDefault()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testSwitchDefault()
+ *
+ * @return array>
+ */
+ public static function dataSwitchDefault()
+ {
+ return [
+ 'simple_switch_default' => [
+ 'testMarker' => '/* testSimpleSwitchDefault */',
+ ],
+ 'simple_switch_default_with_curlies' => [
+ 'testMarker' => '/* testSimpleSwitchDefaultWithCurlies */',
+ ],
+ 'switch_default_toplevel' => [
+ 'testMarker' => '/* testSwitchDefault */',
+ ],
+ 'switch_default_nested_in_match_case' => [
+ 'testMarker' => '/* testSwitchDefaultNestedInMatchCase */',
+ ],
+ 'switch_default_nested_in_match_default' => [
+ 'testMarker' => '/* testSwitchDefaultNestedInMatchDefault */',
+ ],
+ ];
+
+ }//end dataSwitchDefault()
+
+
+ /**
+ * Verify that the retokenization of `T_DEFAULT` tokens in match constructs, doesn't negatively
+ * impact the tokenization of `T_STRING` tokens with the contents 'default' which aren't in
+ * actual fact the default keyword.
+ *
+ * @param string $testMarker The comment prefacing the target token.
+ * @param string $testContent The token content to look for.
+ *
+ * @dataProvider dataNotDefaultKeyword
+ * @covers PHP_CodeSniffer\Tokenizers\PHP::processAdditional
+ *
+ * @return void
+ */
+ public function testNotDefaultKeyword($testMarker, $testContent='DEFAULT')
+ {
+ $tokens = $this->phpcsFile->getTokens();
+
+ $token = $this->getTargetToken($testMarker, [T_MATCH_DEFAULT, T_DEFAULT, T_STRING], $testContent);
+ $tokenArray = $tokens[$token];
+
+ $this->assertSame(T_STRING, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (code)');
+ $this->assertSame('T_STRING', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (type)');
+
+ }//end testNotDefaultKeyword()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testNotDefaultKeyword()
+ *
+ * @return array>
+ */
+ public static function dataNotDefaultKeyword()
+ {
+ return [
+ 'class-constant-as-short-array-key' => [
+ 'testMarker' => '/* testClassConstantAsShortArrayKey */',
+ ],
+ 'class-property-as-short-array-key' => [
+ 'testMarker' => '/* testClassPropertyAsShortArrayKey */',
+ ],
+ 'namespaced-constant-as-short-array-key' => [
+ 'testMarker' => '/* testNamespacedConstantAsShortArrayKey */',
+ ],
+ 'fqn-global-constant-as-short-array-key' => [
+ 'testMarker' => '/* testFQNGlobalConstantAsShortArrayKey */',
+ ],
+ 'class-constant-as-long-array-key' => [
+ 'testMarker' => '/* testClassConstantAsLongArrayKey */',
+ ],
+ 'class-constant-as-yield-key' => [
+ 'testMarker' => '/* testClassConstantAsYieldKey */',
+ ],
+
+ 'class-constant-as-long-array-key-nested-in-match' => [
+ 'testMarker' => '/* testClassConstantAsLongArrayKeyNestedInMatch */',
+ ],
+ 'class-constant-as-long-array-key-nested-in-match-2' => [
+ 'testMarker' => '/* testClassConstantAsLongArrayKeyNestedInMatchLevelDown */',
+ ],
+ 'class-constant-as-short-array-key-nested-in-match' => [
+ 'testMarker' => '/* testClassConstantAsShortArrayKeyNestedInMatch */',
+ ],
+ 'class-constant-as-short-array-key-nested-in-match-2' => [
+ 'testMarker' => '/* testClassConstantAsShortArrayKeyNestedInMatchLevelDown */',
+ ],
+ 'class-constant-as-long-array-key-with-nested-match' => [
+ 'testMarker' => '/* testClassConstantAsLongArrayKeyWithNestedMatch */',
+ ],
+ 'class-constant-as-short-array-key-with-nested-match' => [
+ 'testMarker' => '/* testClassConstantAsShortArrayKeyWithNestedMatch */',
+ ],
+
+ 'class-constant-in-switch-case' => [
+ 'testMarker' => '/* testClassConstantInSwitchCase */',
+ ],
+ 'class-property-in-switch-case' => [
+ 'testMarker' => '/* testClassPropertyInSwitchCase */',
+ ],
+ 'namespaced-constant-in-switch-case' => [
+ 'testMarker' => '/* testNamespacedConstantInSwitchCase */',
+ ],
+ 'namespace-relative-constant-in-switch-case' => [
+ 'testMarker' => '/* testNamespaceRelativeConstantInSwitchCase */',
+ ],
+
+ 'class-constant-declaration' => [
+ 'testMarker' => '/* testClassConstant */',
+ ],
+ 'class-method-declaration' => [
+ 'testMarker' => '/* testMethodDeclaration */',
+ 'testContent' => 'default',
+ ],
+ ];
+
+ }//end dataNotDefaultKeyword()
+
+
+}//end class
diff --git a/tests/Core/Tokenizer/DoubleArrowTest.inc b/tests/Core/Tokenizer/PHP/DoubleArrowTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/DoubleArrowTest.inc
rename to tests/Core/Tokenizer/PHP/DoubleArrowTest.inc
diff --git a/tests/Core/Tokenizer/DoubleArrowTest.php b/tests/Core/Tokenizer/PHP/DoubleArrowTest.php
similarity index 99%
rename from tests/Core/Tokenizer/DoubleArrowTest.php
rename to tests/Core/Tokenizer/PHP/DoubleArrowTest.php
index 768ff65d74..2d050d2518 100644
--- a/tests/Core/Tokenizer/DoubleArrowTest.php
+++ b/tests/Core/Tokenizer/PHP/DoubleArrowTest.php
@@ -9,7 +9,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class DoubleArrowTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/DoubleQuotedStringTest.inc b/tests/Core/Tokenizer/PHP/DoubleQuotedStringTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/DoubleQuotedStringTest.inc
rename to tests/Core/Tokenizer/PHP/DoubleQuotedStringTest.inc
diff --git a/tests/Core/Tokenizer/DoubleQuotedStringTest.php b/tests/Core/Tokenizer/PHP/DoubleQuotedStringTest.php
similarity index 98%
rename from tests/Core/Tokenizer/DoubleQuotedStringTest.php
rename to tests/Core/Tokenizer/PHP/DoubleQuotedStringTest.php
index 83ba0aab7a..6fb3643f95 100644
--- a/tests/Core/Tokenizer/DoubleQuotedStringTest.php
+++ b/tests/Core/Tokenizer/PHP/DoubleQuotedStringTest.php
@@ -8,7 +8,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class DoubleQuotedStringTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/EnumCaseTest.inc b/tests/Core/Tokenizer/PHP/EnumCaseTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/EnumCaseTest.inc
rename to tests/Core/Tokenizer/PHP/EnumCaseTest.inc
diff --git a/tests/Core/Tokenizer/EnumCaseTest.php b/tests/Core/Tokenizer/PHP/EnumCaseTest.php
similarity index 89%
rename from tests/Core/Tokenizer/EnumCaseTest.php
rename to tests/Core/Tokenizer/PHP/EnumCaseTest.php
index f5b68507d6..f80e19dc32 100644
--- a/tests/Core/Tokenizer/EnumCaseTest.php
+++ b/tests/Core/Tokenizer/PHP/EnumCaseTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class EnumCaseTest extends AbstractTokenizerTestCase
{
@@ -20,7 +22,6 @@ final class EnumCaseTest extends AbstractTokenizerTestCase
*
* @dataProvider dataEnumCases
* @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
- * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::recurseScopeMap
*
* @return void
*/
@@ -33,10 +34,6 @@ public function testEnumCases($testMarker)
$this->assertSame(T_ENUM_CASE, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_ENUM_CASE (code)');
$this->assertSame('T_ENUM_CASE', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_ENUM_CASE (type)');
- $this->assertArrayNotHasKey('scope_condition', $tokenArray, 'Scope condition is set');
- $this->assertArrayNotHasKey('scope_opener', $tokenArray, 'Scope opener is set');
- $this->assertArrayNotHasKey('scope_closer', $tokenArray, 'Scope closer is set');
-
}//end testEnumCases()
@@ -69,7 +66,6 @@ public static function dataEnumCases()
*
* @dataProvider dataNotEnumCases
* @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
- * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::recurseScopeMap
*
* @return void
*/
@@ -82,10 +78,6 @@ public function testNotEnumCases($testMarker)
$this->assertSame(T_CASE, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_CASE (code)');
$this->assertSame('T_CASE', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_CASE (type)');
- $this->assertArrayHasKey('scope_condition', $tokenArray, 'Scope condition is not set');
- $this->assertArrayHasKey('scope_opener', $tokenArray, 'Scope opener is not set');
- $this->assertArrayHasKey('scope_closer', $tokenArray, 'Scope closer is not set');
-
}//end testNotEnumCases()
diff --git a/tests/Core/Tokenizer/FinallyTest.inc b/tests/Core/Tokenizer/PHP/FinallyTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/FinallyTest.inc
rename to tests/Core/Tokenizer/PHP/FinallyTest.inc
diff --git a/tests/Core/Tokenizer/FinallyTest.php b/tests/Core/Tokenizer/PHP/FinallyTest.php
similarity index 96%
rename from tests/Core/Tokenizer/FinallyTest.php
rename to tests/Core/Tokenizer/PHP/FinallyTest.php
index a73ac57e50..d74c781ae3 100644
--- a/tests/Core/Tokenizer/FinallyTest.php
+++ b/tests/Core/Tokenizer/PHP/FinallyTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class FinallyTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/GotoLabelTest.inc b/tests/Core/Tokenizer/PHP/GotoLabelTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/GotoLabelTest.inc
rename to tests/Core/Tokenizer/PHP/GotoLabelTest.inc
diff --git a/tests/Core/Tokenizer/GotoLabelTest.php b/tests/Core/Tokenizer/PHP/GotoLabelTest.php
similarity index 97%
rename from tests/Core/Tokenizer/GotoLabelTest.php
rename to tests/Core/Tokenizer/PHP/GotoLabelTest.php
index 6917e939ea..8e6a5f5ceb 100644
--- a/tests/Core/Tokenizer/GotoLabelTest.php
+++ b/tests/Core/Tokenizer/PHP/GotoLabelTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class GotoLabelTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/HeredocStringTest.inc b/tests/Core/Tokenizer/PHP/HeredocStringTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/HeredocStringTest.inc
rename to tests/Core/Tokenizer/PHP/HeredocStringTest.inc
diff --git a/tests/Core/Tokenizer/HeredocStringTest.php b/tests/Core/Tokenizer/PHP/HeredocStringTest.php
similarity index 98%
rename from tests/Core/Tokenizer/HeredocStringTest.php
rename to tests/Core/Tokenizer/PHP/HeredocStringTest.php
index da3f361b2d..75f64d4799 100644
--- a/tests/Core/Tokenizer/HeredocStringTest.php
+++ b/tests/Core/Tokenizer/PHP/HeredocStringTest.php
@@ -8,7 +8,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class HeredocStringTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/NamedFunctionCallArgumentsTest.inc b/tests/Core/Tokenizer/PHP/NamedFunctionCallArgumentsTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/NamedFunctionCallArgumentsTest.inc
rename to tests/Core/Tokenizer/PHP/NamedFunctionCallArgumentsTest.inc
diff --git a/tests/Core/Tokenizer/NamedFunctionCallArgumentsTest.php b/tests/Core/Tokenizer/PHP/NamedFunctionCallArgumentsTest.php
similarity index 99%
rename from tests/Core/Tokenizer/NamedFunctionCallArgumentsTest.php
rename to tests/Core/Tokenizer/PHP/NamedFunctionCallArgumentsTest.php
index 058129f560..14d0c6da51 100644
--- a/tests/Core/Tokenizer/NamedFunctionCallArgumentsTest.php
+++ b/tests/Core/Tokenizer/PHP/NamedFunctionCallArgumentsTest.php
@@ -7,8 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
final class NamedFunctionCallArgumentsTest extends AbstractTokenizerTestCase
diff --git a/tests/Core/Tokenizer/NullsafeObjectOperatorTest.inc b/tests/Core/Tokenizer/PHP/NullsafeObjectOperatorTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/NullsafeObjectOperatorTest.inc
rename to tests/Core/Tokenizer/PHP/NullsafeObjectOperatorTest.inc
diff --git a/tests/Core/Tokenizer/NullsafeObjectOperatorTest.php b/tests/Core/Tokenizer/PHP/NullsafeObjectOperatorTest.php
similarity index 97%
rename from tests/Core/Tokenizer/NullsafeObjectOperatorTest.php
rename to tests/Core/Tokenizer/PHP/NullsafeObjectOperatorTest.php
index f97ff69786..95bfc154ea 100644
--- a/tests/Core/Tokenizer/NullsafeObjectOperatorTest.php
+++ b/tests/Core/Tokenizer/PHP/NullsafeObjectOperatorTest.php
@@ -7,8 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
final class NullsafeObjectOperatorTest extends AbstractTokenizerTestCase
diff --git a/tests/Core/Tokenizer/OtherContextSensitiveKeywordsTest.inc b/tests/Core/Tokenizer/PHP/OtherContextSensitiveKeywordsTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/OtherContextSensitiveKeywordsTest.inc
rename to tests/Core/Tokenizer/PHP/OtherContextSensitiveKeywordsTest.inc
diff --git a/tests/Core/Tokenizer/OtherContextSensitiveKeywordsTest.php b/tests/Core/Tokenizer/PHP/OtherContextSensitiveKeywordsTest.php
similarity index 99%
rename from tests/Core/Tokenizer/OtherContextSensitiveKeywordsTest.php
rename to tests/Core/Tokenizer/PHP/OtherContextSensitiveKeywordsTest.php
index 1b8d19881d..3eff0e96d6 100644
--- a/tests/Core/Tokenizer/OtherContextSensitiveKeywordsTest.php
+++ b/tests/Core/Tokenizer/PHP/OtherContextSensitiveKeywordsTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
/**
* Tests the conversion of PHPCS native context sensitive keyword tokens to T_STRING.
diff --git a/tests/Core/Tokenizer/ResolveSimpleTokenTest.inc b/tests/Core/Tokenizer/PHP/ResolveSimpleTokenTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/ResolveSimpleTokenTest.inc
rename to tests/Core/Tokenizer/PHP/ResolveSimpleTokenTest.inc
diff --git a/tests/Core/Tokenizer/ResolveSimpleTokenTest.php b/tests/Core/Tokenizer/PHP/ResolveSimpleTokenTest.php
similarity index 98%
rename from tests/Core/Tokenizer/ResolveSimpleTokenTest.php
rename to tests/Core/Tokenizer/PHP/ResolveSimpleTokenTest.php
index 706b1fe3c7..4045f775a4 100644
--- a/tests/Core/Tokenizer/ResolveSimpleTokenTest.php
+++ b/tests/Core/Tokenizer/PHP/ResolveSimpleTokenTest.php
@@ -7,8 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
/**
diff --git a/tests/Core/Tokenizer/ShortArrayTest.inc b/tests/Core/Tokenizer/PHP/ShortArrayTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/ShortArrayTest.inc
rename to tests/Core/Tokenizer/PHP/ShortArrayTest.inc
diff --git a/tests/Core/Tokenizer/ShortArrayTest.php b/tests/Core/Tokenizer/PHP/ShortArrayTest.php
similarity index 98%
rename from tests/Core/Tokenizer/ShortArrayTest.php
rename to tests/Core/Tokenizer/PHP/ShortArrayTest.php
index 189523863e..06e76621ff 100644
--- a/tests/Core/Tokenizer/ShortArrayTest.php
+++ b/tests/Core/Tokenizer/PHP/ShortArrayTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class ShortArrayTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/StableCommentWhitespaceTest.inc b/tests/Core/Tokenizer/PHP/StableCommentWhitespaceTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/StableCommentWhitespaceTest.inc
rename to tests/Core/Tokenizer/PHP/StableCommentWhitespaceTest.inc
diff --git a/tests/Core/Tokenizer/StableCommentWhitespaceTest.php b/tests/Core/Tokenizer/PHP/StableCommentWhitespaceTest.php
similarity index 99%
rename from tests/Core/Tokenizer/StableCommentWhitespaceTest.php
rename to tests/Core/Tokenizer/PHP/StableCommentWhitespaceTest.php
index b3b19c6bae..6a58ccbbd7 100644
--- a/tests/Core/Tokenizer/StableCommentWhitespaceTest.php
+++ b/tests/Core/Tokenizer/PHP/StableCommentWhitespaceTest.php
@@ -13,8 +13,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
final class StableCommentWhitespaceTest extends AbstractTokenizerTestCase
diff --git a/tests/Core/Tokenizer/StableCommentWhitespaceWinTest.inc b/tests/Core/Tokenizer/PHP/StableCommentWhitespaceWinTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/StableCommentWhitespaceWinTest.inc
rename to tests/Core/Tokenizer/PHP/StableCommentWhitespaceWinTest.inc
diff --git a/tests/Core/Tokenizer/StableCommentWhitespaceWinTest.php b/tests/Core/Tokenizer/PHP/StableCommentWhitespaceWinTest.php
similarity index 99%
rename from tests/Core/Tokenizer/StableCommentWhitespaceWinTest.php
rename to tests/Core/Tokenizer/PHP/StableCommentWhitespaceWinTest.php
index 2d0ce30d85..dbb103060a 100644
--- a/tests/Core/Tokenizer/StableCommentWhitespaceWinTest.php
+++ b/tests/Core/Tokenizer/PHP/StableCommentWhitespaceWinTest.php
@@ -10,8 +10,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
final class StableCommentWhitespaceWinTest extends AbstractTokenizerTestCase
diff --git a/tests/Core/Tokenizer/TypeIntersectionTest.inc b/tests/Core/Tokenizer/PHP/TypeIntersectionTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/TypeIntersectionTest.inc
rename to tests/Core/Tokenizer/PHP/TypeIntersectionTest.inc
diff --git a/tests/Core/Tokenizer/TypeIntersectionTest.php b/tests/Core/Tokenizer/PHP/TypeIntersectionTest.php
similarity index 98%
rename from tests/Core/Tokenizer/TypeIntersectionTest.php
rename to tests/Core/Tokenizer/PHP/TypeIntersectionTest.php
index bcbc8918cb..99c96edce4 100644
--- a/tests/Core/Tokenizer/TypeIntersectionTest.php
+++ b/tests/Core/Tokenizer/PHP/TypeIntersectionTest.php
@@ -8,7 +8,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class TypeIntersectionTest extends AbstractTokenizerTestCase
{
diff --git a/tests/Core/Tokenizer/TypedConstantsTest.inc b/tests/Core/Tokenizer/PHP/TypedConstantsTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/TypedConstantsTest.inc
rename to tests/Core/Tokenizer/PHP/TypedConstantsTest.inc
diff --git a/tests/Core/Tokenizer/TypedConstantsTest.php b/tests/Core/Tokenizer/PHP/TypedConstantsTest.php
similarity index 99%
rename from tests/Core/Tokenizer/TypedConstantsTest.php
rename to tests/Core/Tokenizer/PHP/TypedConstantsTest.php
index 8b66f926d3..60c21b9dc9 100644
--- a/tests/Core/Tokenizer/TypedConstantsTest.php
+++ b/tests/Core/Tokenizer/PHP/TypedConstantsTest.php
@@ -12,8 +12,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
final class TypedConstantsTest extends AbstractTokenizerTestCase
diff --git a/tests/Core/Tokenizer/UndoNamespacedNameSingleTokenTest.inc b/tests/Core/Tokenizer/PHP/UndoNamespacedNameSingleTokenTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/UndoNamespacedNameSingleTokenTest.inc
rename to tests/Core/Tokenizer/PHP/UndoNamespacedNameSingleTokenTest.inc
diff --git a/tests/Core/Tokenizer/UndoNamespacedNameSingleTokenTest.php b/tests/Core/Tokenizer/PHP/UndoNamespacedNameSingleTokenTest.php
similarity index 99%
rename from tests/Core/Tokenizer/UndoNamespacedNameSingleTokenTest.php
rename to tests/Core/Tokenizer/PHP/UndoNamespacedNameSingleTokenTest.php
index 9e1038dcfb..18e2275768 100644
--- a/tests/Core/Tokenizer/UndoNamespacedNameSingleTokenTest.php
+++ b/tests/Core/Tokenizer/PHP/UndoNamespacedNameSingleTokenTest.php
@@ -17,8 +17,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\PHP;
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
use PHP_CodeSniffer\Util\Tokens;
final class UndoNamespacedNameSingleTokenTest extends AbstractTokenizerTestCase
diff --git a/tests/Core/Tokenizer/Tokenizer/CreateParenthesisNestingMapDNFTypesTest.inc b/tests/Core/Tokenizer/Tokenizer/CreateParenthesisNestingMapDNFTypesTest.inc
new file mode 100644
index 0000000000..6c671ebfdf
--- /dev/null
+++ b/tests/Core/Tokenizer/Tokenizer/CreateParenthesisNestingMapDNFTypesTest.inc
@@ -0,0 +1,185 @@
+ 10 ) {}
+
+/* testParensOwnerFor */
+for ($i =0; $i < /* testParensNoOwnerInForCondition */ ( CONST_A & CONST_B ); $i++ );
+
+/* testParensOwnerMatch */
+$match = match(CONST_A & CONST_B) {
+ default => $a,
+};
+
+/* testParensOwnerArray */
+$array = array (
+ 'text',
+ \CONST_A & \Fully\Qualified\CONST_B,
+ /* testParensNoOwnerFunctionCallWithAmpersandInCallable */
+ do_something($a, /* testParensOwnerArrowFn */ fn($b) => $a & $b, $c),
+);
+
+/* testParensOwnerListWithRefVars */
+list(&$a, &$b) = $array;
+
+/* testParensNoOwnerFunctionCallwithDNFLookALikeParam */
+$obj->static((CONST_A&CONST_B)|CONST_C | $var);
+
+
+/*
+ * DNF parentheses.
+ */
+
+class DNFTypes {
+ /* testDNFTypeOOConstUnqualifiedClasses */
+ public const (A&B)|D UNQUALIFIED = new Foo;
+
+ /* testDNFTypeOOConstReverseModifierOrder */
+ protected final const int|(Foo&Bar)|float MODIFIERS_REVERSED /* testParensNoOwnerOOConstDefaultValue */ = (E_WARNING & E_NOTICE) | E_DEPRECATED;
+
+ const
+ /* testDNFTypeOOConstMulti1 */
+ (A&B) |
+ /* testDNFTypeOOConstMulti2 */
+ (C&D) | // phpcs:ignore Stnd.Cat.Sniff
+ /* testDNFTypeOOConstMulti3 */
+ (Y&D)
+ | null MULTI_DNF = false;
+
+ /* testDNFTypeOOConstNamespaceRelative */
+ final protected const (namespace\Sub\NameA&namespace\Sub\NameB)|namespace\Sub\NameC NAMESPACE_RELATIVE = new namespace\Sub\NameB;
+
+ /* testDNFTypeOOConstPartiallyQualified */
+ const Partially\Qualified\NameC|(Partially\Qualified\NameA&Partially\Qualified\NameB) PARTIALLY_QUALIFIED = new Partially\Qualified\NameA;
+
+ /* testDNFTypeOOConstFullyQualified */
+ const (\Fully\Qualified\NameA&\Fully\Qualified\NameB)|\Fully\Qualified\NameC FULLY_QUALIFIED = new \Fully\Qualified\NameB();
+
+ /* testDNFTypePropertyUnqualifiedClasses */
+ public static (Foo&Bar)|object $obj;
+
+ /* testDNFTypePropertyReverseModifierOrder */
+ static protected string|(A&B)|bool $dnf /* testParensNoOwnerPropertyDefaultValue1 */ = ( E_WARNING & E_NOTICE ) | /* testParensNoOwnerPropertyDefaultValue2 */ (E_ALL & E_DEPRECATED);
+
+ private
+ /* testDNFTypePropertyMultiNamespaceRelative */
+ (namespace\Sub\NameA&namespace\Sub\NameB) |
+ /* testDNFTypePropertyMultiPartiallyQualified */
+ (Partially\Qualified\NameA&Partially\Qualified\NameB) | // phpcs:ignore Stnd.Cat.Sniff
+ false
+ /* testDNFTypePropertyMultiFullyQualified */
+ | (\Fully\Qualified\NameA&\Fully\Qualified\NameB) $multiDnf;
+
+ /* testDNFTypePropertyWithReadOnlyKeyword1 */
+ protected readonly (A&B) | /* testDNFTypePropertyWithReadOnlyKeyword2 */ (C&D) $readonly;
+
+ /* testDNFTypePropertyWithStaticAndReadOnlyKeywords */
+ static readonly (A&B&C)|array $staticReadonly;
+
+ /* testDNFTypePropertyWithOnlyStaticKeyword */
+ static (A&B&C)|true $obj;
+
+ public function paramTypes(
+ /* testDNFTypeParam1WithAttribute */
+ #[MyAttribute]
+ (\Foo&Bar)|int|float $paramA /* testParensNoOwnerParamDefaultValue */ = SOMETHING | (CONSTANT_A & CONSTANT_B),
+
+ /* testDNFTypeParam2 */
+ (Foo&\Bar) /* testDNFTypeParam3 */ |(Baz&Fop) &...$paramB = null,
+ ) {
+ /* testParensNoOwnerInReturnValue1 */
+ return (
+ /* testParensNoOwnerInReturnValue2 */
+ ($a1 & $b1) |
+ /* testParensNoOwnerInReturnValue3 */
+ ($a2 & $b2)
+ ) + $c;
+ }
+
+ public function identifierNames(
+ /* testDNFTypeParamNamespaceRelative */
+ (namespace\Sub\NameA&namespace\Sub\NameB)|false $paramA,
+ /* testDNFTypeParamPartiallyQualified */
+ Partially\Qualified\NameC|(Partially\Qualified\NameA&Partially\Qualified\NameB) $paramB,
+ /* testDNFTypeParamFullyQualified */
+ name|(\Fully\Qualified\NameA&\Fully\Qualified\NameB) $paramC,
+ ) {}
+
+ public function __construct(
+ /* testDNFTypeConstructorPropertyPromotion1 */
+ public (A&B)| /* testDNFTypeConstructorPropertyPromotion2 */ (A&D) $property
+ ) {}
+
+ public function returnType()/* testDNFTypeReturnType1 */ : A|(B&D)|/* testDNFTypeReturnType2 */(B&W)|null {}
+
+ abstract public function abstractMethod(): /* testDNFTypeAbstractMethodReturnType1 */ (X&Y) /* testDNFTypeAbstractMethodReturnType2 */ |(W&Z);
+
+ public function identifierNamesReturnRelative(
+ ) : /* testDNFTypeReturnTypeNamespaceRelative */ (namespace\Sub\NameA&namespace\Sub\NameB)|namespace\Sub\NameC {}
+
+ public function identifierNamesReturnPQ(
+ ) : /* testDNFTypeReturnPartiallyQualified */Partially\Qualified\NameA|(Partially\Qualified\NameB&Partially\Qualified\NameC) {}
+
+ // Illegal type: segments which are strict subsets of others are disallowed, but that's not the concern of the tokenizer.
+ public function identifierNamesReturnFQ(
+ ) /* testDNFTypeReturnFullyQualified */ : (\Fully\Qualified\NameA&\Fully\Qualified\NameB)|\Fully\Qualified\NameB {}
+}
+
+function globalFunctionWithSpreadAndReference(
+ /* testDNFTypeWithReference */
+ float|(B&A) &$paramA,
+ /* testDNFTypeWithSpreadOperator */
+ string|(B|D) ...$paramB
+) {}
+
+
+$closureWithParamType = function ( /* testDNFTypeClosureParamIllegalNullable */ ?(A&B)|bool $string) {};
+
+/* testParensOwnerClosureAmpersandInDefaultValue */
+$closureWithReturnType = function ($string = NONSENSE & FAKE) /* testDNFTypeClosureReturn */ : (\Package\MyA&PackageB)|null {};
+
+/* testParensOwnerArrowDNFUsedWithin */
+$arrowWithParamType = fn (
+ /* testDNFTypeArrowParam */
+ object|(A&B&C)|array $param,
+ /* testParensNoOwnerAmpersandInDefaultValue */ ?int $int = (CONSTA & CONSTB )| CONST_C
+)
+ /* testParensNoOwnerInArrowReturnExpression */
+ => ($param & $foo ) | $int;
+
+$arrowWithReturnType = fn ($param) : /* testDNFTypeArrowReturnType */ int|(A&B) => $param * 10;
+
+$arrowWithParamReturnByRef = fn &(
+ /* testDNFTypeArrowParamWithReturnByRef */
+ (A&B)|null $param
+) => $param * 10;
+
+function InvalidSyntaxes(
+ /* testDNFTypeParamIllegalUnnecessaryParens */
+ (A&B) $parensNotNeeded
+
+ /* testDNFTypeParamIllegalIntersectUnionReversed */
+ A&(B|D) $onlyIntersectAllowedWithinParensAndUnionOutside
+
+ /* testDNFTypeParamIllegalNestedParens */
+ A|(B&(D|W)|null) $nestedParensNotAllowed
+) {}
diff --git a/tests/Core/Tokenizer/Tokenizer/CreateParenthesisNestingMapDNFTypesTest.php b/tests/Core/Tokenizer/Tokenizer/CreateParenthesisNestingMapDNFTypesTest.php
new file mode 100644
index 0000000000..7198690ddf
--- /dev/null
+++ b/tests/Core/Tokenizer/Tokenizer/CreateParenthesisNestingMapDNFTypesTest.php
@@ -0,0 +1,375 @@
+
+ * @copyright 2024 PHPCSStandards and contributors
+ * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\Tokenizer;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
+
+final class CreateParenthesisNestingMapDNFTypesTest extends AbstractTokenizerTestCase
+{
+
+
+ /**
+ * Test that parentheses when **not** used in a type declaration are correctly tokenized.
+ *
+ * @param string $testMarker The comment prefacing the target token.
+ * @param int|false $owner Optional. The parentheses owner or false when no parentheses owner is expected.
+ *
+ * @dataProvider dataNormalParentheses
+ * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::createParenthesisNestingMap
+ *
+ * @return void
+ */
+ public function testNormalParentheses($testMarker, $owner=false)
+ {
+ $tokens = $this->phpcsFile->getTokens();
+
+ $openPtr = $this->getTargetToken($testMarker, [T_OPEN_PARENTHESIS, T_TYPE_OPEN_PARENTHESIS]);
+ $opener = $tokens[$openPtr];
+
+ // Make sure we're looking at the right token.
+ $this->assertSame(T_OPEN_PARENTHESIS, $opener['code'], 'Token tokenized as '.$opener['type'].', not T_OPEN_PARENTHESIS (code)');
+
+ if ($owner !== false) {
+ $this->assertArrayHasKey('parenthesis_owner', $opener, 'Parenthesis owner is not set');
+ $this->assertSame(($openPtr + $owner), $opener['parenthesis_owner'], 'Opener parenthesis owner is not the expected token');
+ } else {
+ $this->assertArrayNotHasKey('parenthesis_owner', $opener, 'Parenthesis owner is set');
+ }
+
+ $this->assertArrayHasKey('parenthesis_opener', $opener, 'Parenthesis opener is not set');
+ $this->assertArrayHasKey('parenthesis_closer', $opener, 'Parenthesis closer is not set');
+ $this->assertSame($openPtr, $opener['parenthesis_opener'], 'Parenthesis opener is not the expected token');
+
+ $closePtr = $opener['parenthesis_closer'];
+ $closer = $tokens[$closePtr];
+
+ // Make sure we're looking at the right token.
+ $this->assertSame(T_CLOSE_PARENTHESIS, $closer['code'], 'Token tokenized as '.$closer['type'].', not T_CLOSE_PARENTHESIS (code)');
+
+ if ($owner !== false) {
+ $this->assertArrayHasKey('parenthesis_owner', $closer, 'Parenthesis owner is not set');
+ $this->assertSame(($openPtr + $owner), $closer['parenthesis_owner'], 'Closer parenthesis owner is not the expected token');
+ } else {
+ $this->assertArrayNotHasKey('parenthesis_owner', $closer, 'Parenthesis owner is set');
+ }
+
+ $this->assertArrayHasKey('parenthesis_opener', $closer, 'Parenthesis opener is not set');
+ $this->assertArrayHasKey('parenthesis_closer', $closer, 'Parenthesis closer is not set');
+ $this->assertSame($closePtr, $closer['parenthesis_closer'], 'Parenthesis closer is not the expected token');
+
+ for ($i = ($openPtr + 1); $i < $closePtr; $i++) {
+ $this->assertArrayHasKey('nested_parenthesis', $tokens[$i], "Nested parenthesis key not set on token $i ({$tokens[$i]['type']})");
+ $this->assertArrayHasKey($openPtr, $tokens[$i]['nested_parenthesis'], 'Nested parenthesis is missing target parentheses set');
+ $this->assertSame($closePtr, $tokens[$i]['nested_parenthesis'][$openPtr], 'Nested parenthesis closer not set correctly');
+ }
+
+ }//end testNormalParentheses()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testNormalParentheses()
+ *
+ * @return array>
+ */
+ public static function dataNormalParentheses()
+ {
+ // "Owner" offsets are relative to the open parenthesis.
+ return [
+ 'parens without owner' => [
+ 'testMarker' => '/* testParensNoOwner */',
+ ],
+ 'parens without owner in ternary then' => [
+ 'testMarker' => '/* testParensNoOwnerInTernary */',
+ ],
+ 'parens without owner in short ternary' => [
+ 'testMarker' => '/* testParensNoOwnerInShortTernary */',
+ ],
+ 'parens with owner: function; & in default value' => [
+ 'testMarker' => '/* testParensOwnerFunctionAmpersandInDefaultValue */',
+ 'owner' => -3,
+ ],
+ 'parens with owner: closure; param declared by & ref' => [
+ 'testMarker' => '/* testParensOwnerClosureAmpersandParamRef */',
+ 'owner' => -1,
+ ],
+ 'parens with owner: if' => [
+ 'testMarker' => '/* testParensOwnerIf */',
+ 'owner' => -2,
+ ],
+ 'parens without owner in if condition' => [
+ 'testMarker' => '/* testParensNoOwnerInIfCondition */',
+ ],
+ 'parens with owner: for' => [
+ 'testMarker' => '/* testParensOwnerFor */',
+ 'owner' => -2,
+ ],
+ 'parens without owner in for condition' => [
+ 'testMarker' => '/* testParensNoOwnerInForCondition */',
+ ],
+ 'parens with owner: match' => [
+ 'testMarker' => '/* testParensOwnerMatch */',
+ 'owner' => -1,
+ ],
+ 'parens with owner: array' => [
+ 'testMarker' => '/* testParensOwnerArray */',
+ 'owner' => -2,
+ ],
+ 'parens without owner in array; function call with & in callable' => [
+ 'testMarker' => '/* testParensNoOwnerFunctionCallWithAmpersandInCallable */',
+ ],
+ 'parens with owner: fn; & in return value' => [
+ 'testMarker' => '/* testParensOwnerArrowFn */',
+ 'owner' => -1,
+ ],
+ 'parens with owner: list with reference vars' => [
+ 'testMarker' => '/* testParensOwnerListWithRefVars */',
+ 'owner' => -1,
+ ],
+ 'parens without owner, function call with DNF look-a-like param' => [
+ 'testMarker' => '/* testParensNoOwnerFunctionCallwithDNFLookALikeParam */',
+ ],
+
+ 'parens without owner in OO const default value' => [
+ 'testMarker' => '/* testParensNoOwnerOOConstDefaultValue */',
+ ],
+ 'parens without owner in property default 1' => [
+ 'testMarker' => '/* testParensNoOwnerPropertyDefaultValue1 */',
+ ],
+ 'parens without owner in property default 2' => [
+ 'testMarker' => '/* testParensNoOwnerPropertyDefaultValue2 */',
+ ],
+ 'parens without owner in param default value' => [
+ 'testMarker' => '/* testParensNoOwnerParamDefaultValue */',
+ ],
+ 'parens without owner in return statement 1' => [
+ 'testMarker' => '/* testParensNoOwnerInReturnValue1 */',
+ ],
+ 'parens without owner in return statement 2' => [
+ 'testMarker' => '/* testParensNoOwnerInReturnValue2 */',
+ ],
+ 'parens without owner in return statement 3' => [
+ 'testMarker' => '/* testParensNoOwnerInReturnValue3 */',
+ ],
+ 'parens with owner: closure; & in default value' => [
+ 'testMarker' => '/* testParensOwnerClosureAmpersandInDefaultValue */',
+ 'owner' => -2,
+ ],
+ 'parens with owner: fn; dnf used within' => [
+ 'testMarker' => '/* testParensOwnerArrowDNFUsedWithin */',
+ 'owner' => -2,
+ ],
+ 'parens without owner: default value for param in arrow function' => [
+ 'testMarker' => '/* testParensNoOwnerAmpersandInDefaultValue */',
+ ],
+ 'parens without owner in arrow function return expression' => [
+ 'testMarker' => '/* testParensNoOwnerInArrowReturnExpression */',
+ ],
+ ];
+
+ }//end dataNormalParentheses()
+
+
+ /**
+ * Test that parentheses when used in a DNF type declaration are correctly tokenized.
+ *
+ * Includes verifying that:
+ * - the tokens between the parentheses all have a "nested_parenthesis" key.
+ * - all ampersands between the parentheses are tokenized as T_TYPE_INTERSECTION.
+ *
+ * @param string $testMarker The comment prefacing the target token.
+ *
+ * @dataProvider dataDNFTypeParentheses
+ * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::createParenthesisNestingMap
+ *
+ * @return void
+ */
+ public function testDNFTypeParentheses($testMarker)
+ {
+ $tokens = $this->phpcsFile->getTokens();
+
+ $openPtr = $this->getTargetToken($testMarker, [T_OPEN_PARENTHESIS, T_TYPE_OPEN_PARENTHESIS]);
+ $opener = $tokens[$openPtr];
+
+ // Make sure we're looking at the right token.
+ $this->assertSame(T_TYPE_OPEN_PARENTHESIS, $opener['code'], 'Token tokenized as '.$opener['type'].', not T_TYPE_OPEN_PARENTHESIS (code)');
+
+ $this->assertArrayNotHasKey('parenthesis_owner', $opener, 'Parenthesis owner is set');
+ $this->assertArrayHasKey('parenthesis_opener', $opener, 'Parenthesis opener is not set');
+ $this->assertArrayHasKey('parenthesis_closer', $opener, 'Parenthesis closer is not set');
+ $this->assertSame($openPtr, $opener['parenthesis_opener'], 'Parenthesis opener is not the expected token');
+
+ $closePtr = $opener['parenthesis_closer'];
+ $closer = $tokens[$closePtr];
+
+ // Make sure we're looking at the right token.
+ $this->assertSame(T_TYPE_CLOSE_PARENTHESIS, $closer['code'], 'Token tokenized as '.$closer['type'].', not T_TYPE_CLOSE_PARENTHESIS (code)');
+
+ $this->assertArrayNotHasKey('parenthesis_owner', $closer, 'Parenthesis owner is set');
+ $this->assertArrayHasKey('parenthesis_opener', $closer, 'Parenthesis opener is not set');
+ $this->assertArrayHasKey('parenthesis_closer', $closer, 'Parenthesis closer is not set');
+ $this->assertSame($closePtr, $closer['parenthesis_closer'], 'Parenthesis closer is not the expected token');
+
+ $intersectionCount = 0;
+ for ($i = ($openPtr + 1); $i < $closePtr; $i++) {
+ $this->assertArrayHasKey('nested_parenthesis', $tokens[$i], "Nested parenthesis key not set on token $i ({$tokens[$i]['type']})");
+ $this->assertArrayHasKey($openPtr, $tokens[$i]['nested_parenthesis'], 'Nested parenthesis is missing target parentheses set');
+ $this->assertSame($closePtr, $tokens[$i]['nested_parenthesis'][$openPtr], 'Nested parenthesis closer not set correctly');
+ }//end for
+
+ }//end testDNFTypeParentheses()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testDNFTypeParentheses()
+ *
+ * @return array>
+ */
+ public static function dataDNFTypeParentheses()
+ {
+ return [
+ 'OO const type: unqualified classes' => [
+ 'testMarker' => '/* testDNFTypeOOConstUnqualifiedClasses */',
+ ],
+ 'OO const type: modifiers in reverse order' => [
+ 'testMarker' => '/* testDNFTypeOOConstReverseModifierOrder */',
+ ],
+ 'OO const type: multi-dnf part 1' => [
+ 'testMarker' => '/* testDNFTypeOOConstMulti1 */',
+ ],
+ 'OO const type: multi-dnf part 2' => [
+ 'testMarker' => '/* testDNFTypeOOConstMulti2 */',
+ ],
+ 'OO const type: multi-dnf part 3' => [
+ 'testMarker' => '/* testDNFTypeOOConstMulti3 */',
+ ],
+ 'OO const type: namespace relative classes' => [
+ 'testMarker' => '/* testDNFTypeOOConstNamespaceRelative */',
+ ],
+ 'OO const type: partially qualified classes' => [
+ 'testMarker' => '/* testDNFTypeOOConstPartiallyQualified */',
+ ],
+ 'OO const type: fully qualified classes' => [
+ 'testMarker' => '/* testDNFTypeOOConstFullyQualified */',
+ ],
+
+ 'OO property type: unqualified classes' => [
+ 'testMarker' => '/* testDNFTypePropertyUnqualifiedClasses */',
+ ],
+ 'OO property type: modifiers in reverse order' => [
+ 'testMarker' => '/* testDNFTypePropertyReverseModifierOrder */',
+ ],
+ 'OO property type: multi-dnf namespace relative classes' => [
+ 'testMarker' => '/* testDNFTypePropertyMultiNamespaceRelative */',
+ ],
+ 'OO property type: multi-dnf partially qualified classes' => [
+ 'testMarker' => '/* testDNFTypePropertyMultiPartiallyQualified */',
+ ],
+ 'OO property type: multi-dnf fully qualified classes' => [
+ 'testMarker' => '/* testDNFTypePropertyMultiFullyQualified */',
+ ],
+
+ 'OO property type: multi-dnf with readonly keyword 1' => [
+ 'testMarker' => '/* testDNFTypePropertyWithReadOnlyKeyword1 */',
+ ],
+ 'OO property type: multi-dnf with readonly keyword 2' => [
+ 'testMarker' => '/* testDNFTypePropertyWithReadOnlyKeyword2 */',
+ ],
+ 'OO property type: with static and readonly keywords' => [
+ 'testMarker' => '/* testDNFTypePropertyWithStaticAndReadOnlyKeywords */',
+ ],
+ 'OO property type: with only static keyword' => [
+ 'testMarker' => '/* testDNFTypePropertyWithOnlyStaticKeyword */',
+ ],
+ 'OO method param type: first param' => [
+ 'testMarker' => '/* testDNFTypeParam1WithAttribute */',
+ ],
+ 'OO method param type: second param, first DNF' => [
+ 'testMarker' => '/* testDNFTypeParam2 */',
+ ],
+ 'OO method param type: second param, second DNF' => [
+ 'testMarker' => '/* testDNFTypeParam3 */',
+ ],
+ 'OO method param type: namespace relative classes' => [
+ 'testMarker' => '/* testDNFTypeParamNamespaceRelative */',
+ ],
+ 'OO method param type: partially qualified classes' => [
+ 'testMarker' => '/* testDNFTypeParamPartiallyQualified */',
+ ],
+ 'OO method param type: fully qualified classes' => [
+ 'testMarker' => '/* testDNFTypeParamFullyQualified */',
+ ],
+ 'Constructor property promotion with multi DNF 1' => [
+ 'testMarker' => '/* testDNFTypeConstructorPropertyPromotion1 */',
+ ],
+ 'Constructor property promotion with multi DNF 2' => [
+ 'testMarker' => '/* testDNFTypeConstructorPropertyPromotion2 */',
+ ],
+ 'OO method return type: multi DNF 1' => [
+ 'testMarker' => '/* testDNFTypeReturnType1 */',
+ ],
+ 'OO method return type: multi DNF 2' => [
+ 'testMarker' => '/* testDNFTypeReturnType2 */',
+ ],
+ 'OO abstract method return type: multi DNF 1' => [
+ 'testMarker' => '/* testDNFTypeAbstractMethodReturnType1 */',
+ ],
+ 'OO abstract method return type: multi DNF 2' => [
+ 'testMarker' => '/* testDNFTypeAbstractMethodReturnType2 */',
+ ],
+ 'OO method return type: namespace relative classes' => [
+ 'testMarker' => '/* testDNFTypeReturnTypeNamespaceRelative */',
+ ],
+ 'OO method return type: partially qualified classes' => [
+ 'testMarker' => '/* testDNFTypeReturnPartiallyQualified */',
+ ],
+ 'OO method return type: fully qualified classes' => [
+ 'testMarker' => '/* testDNFTypeReturnFullyQualified */',
+ ],
+ 'function param type: with reference' => [
+ 'testMarker' => '/* testDNFTypeWithReference */',
+ ],
+ 'function param type: with spread' => [
+ 'testMarker' => '/* testDNFTypeWithSpreadOperator */',
+ ],
+ 'closure param type: with illegal nullable' => [
+ 'testMarker' => '/* testDNFTypeClosureParamIllegalNullable */',
+ ],
+ 'closure return type' => [
+ 'testMarker' => '/* testDNFTypeClosureReturn */',
+ ],
+ 'arrow function param type' => [
+ 'testMarker' => '/* testDNFTypeArrowParam */',
+ ],
+ 'arrow function return type' => [
+ 'testMarker' => '/* testDNFTypeArrowReturnType */',
+ ],
+ 'arrow function param type with return by ref' => [
+ 'testMarker' => '/* testDNFTypeArrowParamWithReturnByRef */',
+ ],
+
+ 'illegal syntax: unnecessary parentheses (no union)' => [
+ 'testMarker' => '/* testDNFTypeParamIllegalUnnecessaryParens */',
+ ],
+ 'illegal syntax: union within parentheses, intersect outside' => [
+ 'testMarker' => '/* testDNFTypeParamIllegalIntersectUnionReversed */',
+ ],
+ 'illegal syntax: nested parentheses' => [
+ 'testMarker' => '/* testDNFTypeParamIllegalNestedParens */',
+ ],
+ ];
+
+ }//end dataDNFTypeParentheses()
+
+
+}//end class
diff --git a/tests/Core/Tokenizer/Tokenizer/CreateTokenMapArrayParenthesesTest.inc b/tests/Core/Tokenizer/Tokenizer/CreateTokenMapArrayParenthesesTest.inc
new file mode 100644
index 0000000000..6d8adfcbae
--- /dev/null
+++ b/tests/Core/Tokenizer/Tokenizer/CreateTokenMapArrayParenthesesTest.inc
@@ -0,0 +1,58 @@
+ 10);
+
+/* testArrayWithComment */
+$var = Array /*comment*/ (1 => 10);
+
+/* testNestingArray */
+$var = array(
+ /* testNestedArray */
+ array(
+ 'key' => 'value',
+
+ /* testClosureReturnType */
+ 'closure' => function($a) use($global) : Array {},
+ ),
+);
+
+/* testFunctionDeclarationParamType */
+function typedParam(array $a) {}
+
+/* testFunctionDeclarationReturnType */
+function returnType($a) : int|array|null {}
+
+class Bar {
+ /* testClassConst */
+ const ARRAY = [];
+
+ /* testClassMethod */
+ public function array() {}
+
+ /* testOOConstType */
+ const array /* testTypedOOConstName */ ARRAY = /* testOOConstDefault */ array();
+
+ /* testOOPropertyType */
+ protected array $property;
+}
+
+class DNFTypes {
+ /* testOOConstDNFType */
+ const (A&B)|array|(C&D) NAME = [];
+
+ /* testOOPropertyDNFType */
+ protected (A&B)|ARRAY|null $property;
+
+ /* testFunctionDeclarationParamDNFType */
+ public function name(null|array|(A&B) $param) {
+ /* testClosureDeclarationParamDNFType */
+ $cl = function ( array|(A&B) $param) {};
+
+ /* testArrowDeclarationReturnDNFType */
+ $arrow = fn($a): (A&B)|Array => new $a;
+ }
+}
diff --git a/tests/Core/Tokenizer/Tokenizer/CreateTokenMapArrayParenthesesTest.php b/tests/Core/Tokenizer/Tokenizer/CreateTokenMapArrayParenthesesTest.php
new file mode 100644
index 0000000000..e362448c9d
--- /dev/null
+++ b/tests/Core/Tokenizer/Tokenizer/CreateTokenMapArrayParenthesesTest.php
@@ -0,0 +1,212 @@
+
+ * @copyright 2021 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\Tokenizer;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
+
+final class CreateTokenMapArrayParenthesesTest extends AbstractTokenizerTestCase
+{
+
+
+ /**
+ * Test that the array keyword is correctly tokenized as `T_ARRAY`.
+ *
+ * @param string $testMarker The comment prefacing the target token.
+ * @param string $testContent Optional. The token content to look for.
+ *
+ * @dataProvider dataArrayKeyword
+ * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::createTokenMap
+ *
+ * @return void
+ */
+ public function testArrayKeyword($testMarker, $testContent='array')
+ {
+ $tokens = $this->phpcsFile->getTokens();
+
+ $token = $this->getTargetToken($testMarker, [T_ARRAY, T_STRING], $testContent);
+ $tokenArray = $tokens[$token];
+
+ // Make sure we're looking at the right token.
+ $this->assertSame(T_ARRAY, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_ARRAY (code)');
+
+ $this->assertArrayHasKey('parenthesis_owner', $tokenArray, 'Parenthesis owner is not set');
+ $this->assertArrayHasKey('parenthesis_opener', $tokenArray, 'Parenthesis opener is not set');
+ $this->assertArrayHasKey('parenthesis_closer', $tokenArray, 'Parenthesis closer is not set');
+
+ }//end testArrayKeyword()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testArrayKeyword()
+ *
+ * @return array>
+ */
+ public static function dataArrayKeyword()
+ {
+ return [
+ 'empty array' => [
+ 'testMarker' => '/* testEmptyArray */',
+ ],
+ 'array with space before parenthesis' => [
+ 'testMarker' => '/* testArrayWithSpace */',
+ ],
+ 'array with comment before parenthesis' => [
+ 'testMarker' => '/* testArrayWithComment */',
+ 'testContent' => 'Array',
+ ],
+ 'nested: outer array' => [
+ 'testMarker' => '/* testNestingArray */',
+ ],
+ 'nested: inner array' => [
+ 'testMarker' => '/* testNestedArray */',
+ ],
+ 'OO constant default value' => [
+ 'testMarker' => '/* testOOConstDefault */',
+ ],
+ ];
+
+ }//end dataArrayKeyword()
+
+
+ /**
+ * Test that the array keyword when used in a type declaration is correctly tokenized as `T_STRING`.
+ *
+ * @param string $testMarker The comment prefacing the target token.
+ * @param string $testContent Optional. The token content to look for.
+ *
+ * @dataProvider dataArrayType
+ * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::createTokenMap
+ *
+ * @return void
+ */
+ public function testArrayType($testMarker, $testContent='array')
+ {
+ $tokens = $this->phpcsFile->getTokens();
+
+ $token = $this->getTargetToken($testMarker, [T_ARRAY, T_STRING], $testContent);
+ $tokenArray = $tokens[$token];
+
+ // Make sure we're looking at the right token.
+ $this->assertSame(T_STRING, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (code)');
+
+ $this->assertArrayNotHasKey('parenthesis_owner', $tokenArray, 'Parenthesis owner is set');
+ $this->assertArrayNotHasKey('parenthesis_opener', $tokenArray, 'Parenthesis opener is set');
+ $this->assertArrayNotHasKey('parenthesis_closer', $tokenArray, 'Parenthesis closer is set');
+
+ }//end testArrayType()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testArrayType()
+ *
+ * @return array>
+ */
+ public static function dataArrayType()
+ {
+ return [
+ 'closure return type' => [
+ 'testMarker' => '/* testClosureReturnType */',
+ 'testContent' => 'Array',
+ ],
+ 'function param type' => [
+ 'testMarker' => '/* testFunctionDeclarationParamType */',
+ ],
+ 'function union return type' => [
+ 'testMarker' => '/* testFunctionDeclarationReturnType */',
+ ],
+ 'OO constant type' => [
+ 'testMarker' => '/* testOOConstType */',
+ ],
+ 'OO property type' => [
+ 'testMarker' => '/* testOOPropertyType */',
+ ],
+
+ 'OO constant DNF type' => [
+ 'testMarker' => '/* testOOConstDNFType */',
+ ],
+ 'OO property DNF type' => [
+ 'testMarker' => '/* testOOPropertyDNFType */',
+ 'testContent' => 'ARRAY',
+ ],
+ 'function param DNF type' => [
+ 'testMarker' => '/* testFunctionDeclarationParamDNFType */',
+ ],
+ 'closure param DNF type' => [
+ 'testMarker' => '/* testClosureDeclarationParamDNFType */',
+ ],
+ 'arrow return DNF type' => [
+ 'testMarker' => '/* testArrowDeclarationReturnDNFType */',
+ 'testContent' => 'Array',
+ ],
+ ];
+
+ }//end dataArrayType()
+
+
+ /**
+ * Verify that the retokenization of `T_ARRAY` tokens to `T_STRING` is handled correctly
+ * for tokens with the contents 'array' which aren't in actual fact the array keyword.
+ *
+ * @param string $testMarker The comment prefacing the target token.
+ * @param string $testContent The token content to look for.
+ *
+ * @dataProvider dataNotArrayKeyword
+ * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::createTokenMap
+ *
+ * @return void
+ */
+ public function testNotArrayKeyword($testMarker, $testContent='array')
+ {
+ $tokens = $this->phpcsFile->getTokens();
+
+ $token = $this->getTargetToken($testMarker, [T_ARRAY, T_STRING], $testContent);
+ $tokenArray = $tokens[$token];
+
+ // Make sure we're looking at the right token.
+ $this->assertSame(T_STRING, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (code)');
+
+ $this->assertArrayNotHasKey('parenthesis_owner', $tokenArray, 'Parenthesis owner is set');
+ $this->assertArrayNotHasKey('parenthesis_opener', $tokenArray, 'Parenthesis opener is set');
+ $this->assertArrayNotHasKey('parenthesis_closer', $tokenArray, 'Parenthesis closer is set');
+
+ }//end testNotArrayKeyword()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testNotArrayKeyword()
+ *
+ * @return array>
+ */
+ public static function dataNotArrayKeyword()
+ {
+ return [
+ 'class-constant-name' => [
+ 'testMarker' => '/* testClassConst */',
+ 'testContent' => 'ARRAY',
+ ],
+ 'class-method-name' => [
+ 'testMarker' => '/* testClassMethod */',
+ ],
+ 'class-constant-name-after-type' => [
+ 'testMarker' => '/* testTypedOOConstName */',
+ 'testContent' => 'ARRAY',
+ ],
+ ];
+
+ }//end dataNotArrayKeyword()
+
+
+}//end class
diff --git a/tests/Core/Tokenizer/HeredocNowdocCloserTest.inc b/tests/Core/Tokenizer/Tokenizer/HeredocNowdocCloserTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/HeredocNowdocCloserTest.inc
rename to tests/Core/Tokenizer/Tokenizer/HeredocNowdocCloserTest.inc
diff --git a/tests/Core/Tokenizer/HeredocNowdocCloserTest.php b/tests/Core/Tokenizer/Tokenizer/HeredocNowdocCloserTest.php
similarity index 96%
rename from tests/Core/Tokenizer/HeredocNowdocCloserTest.php
rename to tests/Core/Tokenizer/Tokenizer/HeredocNowdocCloserTest.php
index d43768f0e4..a2357db8ae 100644
--- a/tests/Core/Tokenizer/HeredocNowdocCloserTest.php
+++ b/tests/Core/Tokenizer/Tokenizer/HeredocNowdocCloserTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\Tokenizer;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
/**
* Heredoc/nowdoc closer token test.
diff --git a/tests/Core/Tokenizer/Tokenizer/RecurseScopeMapCaseKeywordConditionsTest.inc b/tests/Core/Tokenizer/Tokenizer/RecurseScopeMapCaseKeywordConditionsTest.inc
new file mode 100644
index 0000000000..13b87242e1
--- /dev/null
+++ b/tests/Core/Tokenizer/Tokenizer/RecurseScopeMapCaseKeywordConditionsTest.inc
@@ -0,0 +1,95 @@
+
+ * @copyright 2021 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\Tokenizer;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
+
+final class RecurseScopeMapCaseKeywordConditionsTest extends AbstractTokenizerTestCase
+{
+
+
+ /**
+ * Test that the enum "case" is converted to T_ENUM_CASE.
+ *
+ * @param string $testMarker The comment which prefaces the target token in the test file.
+ *
+ * @dataProvider dataEnumCases
+ * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::recurseScopeMap
+ *
+ * @return void
+ */
+ public function testEnumCases($testMarker)
+ {
+ $tokens = $this->phpcsFile->getTokens();
+ $enumCase = $this->getTargetToken($testMarker, [T_ENUM_CASE, T_CASE]);
+ $tokenArray = $tokens[$enumCase];
+
+ // Make sure we're looking at the right token.
+ $this->assertSame(T_ENUM_CASE, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_ENUM_CASE (code)');
+
+ $this->assertArrayNotHasKey('scope_condition', $tokenArray, 'Scope condition is set');
+ $this->assertArrayNotHasKey('scope_opener', $tokenArray, 'Scope opener is set');
+ $this->assertArrayNotHasKey('scope_closer', $tokenArray, 'Scope closer is set');
+
+ }//end testEnumCases()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testEnumCases()
+ *
+ * @return array>
+ */
+ public static function dataEnumCases()
+ {
+ return [
+ 'enum case, no value' => ['/* testPureEnumCase */'],
+ 'enum case, integer value' => ['/* testBackingIntegerEnumCase */'],
+ 'enum case, string value' => ['/* testBackingStringEnumCase */'],
+ 'enum case, integer value in more complex enum' => ['/* testEnumCaseInComplexEnum */'],
+ 'enum case, keyword in mixed case' => ['/* testEnumCaseIsCaseInsensitive */'],
+ 'enum case, after switch statement' => ['/* testEnumCaseAfterSwitch */'],
+ 'enum case, after switch statement using alternative syntax' => ['/* testEnumCaseAfterSwitchWithEndSwitch */'],
+ ];
+
+ }//end dataEnumCases()
+
+
+ /**
+ * Test that "case" that is not enum case is still tokenized as `T_CASE`.
+ *
+ * @param string $testMarker The comment which prefaces the target token in the test file.
+ *
+ * @dataProvider dataNotEnumCases
+ * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::recurseScopeMap
+ *
+ * @return void
+ */
+ public function testNotEnumCases($testMarker)
+ {
+ $tokens = $this->phpcsFile->getTokens();
+ $case = $this->getTargetToken($testMarker, [T_ENUM_CASE, T_CASE]);
+ $tokenArray = $tokens[$case];
+
+ // Make sure we're looking at the right token.
+ $this->assertSame(T_CASE, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_CASE (code)');
+
+ $this->assertArrayHasKey('scope_condition', $tokenArray, 'Scope condition is not set');
+ $this->assertArrayHasKey('scope_opener', $tokenArray, 'Scope opener is not set');
+ $this->assertArrayHasKey('scope_closer', $tokenArray, 'Scope closer is not set');
+
+ }//end testNotEnumCases()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testNotEnumCases()
+ *
+ * @return array>
+ */
+ public static function dataNotEnumCases()
+ {
+ return [
+ 'switch case with constant, semicolon condition end' => ['/* testCaseWithSemicolonIsNotEnumCase */'],
+ 'switch case with constant, colon condition end' => ['/* testCaseWithConstantIsNotEnumCase */'],
+ 'switch case with constant, comparison' => ['/* testCaseWithConstantAndIdenticalIsNotEnumCase */'],
+ 'switch case with constant, assignment' => ['/* testCaseWithAssigmentToConstantIsNotEnumCase */'],
+ 'switch case with constant, keyword in mixed case' => ['/* testIsNotEnumCaseIsCaseInsensitive */'],
+ 'switch case, body in curlies declares enum' => ['/* testCaseInSwitchWhenCreatingEnumInSwitch1 */'],
+ 'switch case, body after semicolon declares enum' => ['/* testCaseInSwitchWhenCreatingEnumInSwitch2 */'],
+ ];
+
+ }//end dataNotEnumCases()
+
+
+ /**
+ * Test that "case" that is not enum case is still tokenized as `T_CASE`.
+ *
+ * @param string $testMarker The comment which prefaces the target token in the test file.
+ *
+ * @dataProvider dataKeywordAsEnumCaseNameShouldBeString
+ * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::recurseScopeMap
+ *
+ * @return void
+ */
+ public function testKeywordAsEnumCaseNameShouldBeString($testMarker)
+ {
+ $tokens = $this->phpcsFile->getTokens();
+ $enumCaseName = $this->getTargetToken($testMarker, [T_STRING, T_INTERFACE, T_TRAIT, T_ENUM, T_FUNCTION, T_FALSE, T_DEFAULT, T_ARRAY]);
+ $tokenArray = $tokens[$enumCaseName];
+
+ // Make sure we're looking at the right token.
+ $this->assertSame(T_STRING, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (code)');
+
+ $this->assertArrayNotHasKey('scope_condition', $tokenArray, 'Scope condition is set');
+ $this->assertArrayNotHasKey('scope_opener', $tokenArray, 'Scope opener is set');
+ $this->assertArrayNotHasKey('scope_closer', $tokenArray, 'Scope closer is set');
+
+ }//end testKeywordAsEnumCaseNameShouldBeString()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testKeywordAsEnumCaseNameShouldBeString()
+ *
+ * @return array>
+ */
+ public static function dataKeywordAsEnumCaseNameShouldBeString()
+ {
+ return [
+ '"interface" as case name' => ['/* testKeywordAsEnumCaseNameShouldBeString1 */'],
+ '"trait" as case name' => ['/* testKeywordAsEnumCaseNameShouldBeString2 */'],
+ '"enum" as case name' => ['/* testKeywordAsEnumCaseNameShouldBeString3 */'],
+ '"function" as case name' => ['/* testKeywordAsEnumCaseNameShouldBeString4 */'],
+ '"false" as case name' => ['/* testKeywordAsEnumCaseNameShouldBeString5 */'],
+ '"default" as case name' => ['/* testKeywordAsEnumCaseNameShouldBeString6 */'],
+ '"array" as case name' => ['/* testKeywordAsEnumCaseNameShouldBeString7 */'],
+ ];
+
+ }//end dataKeywordAsEnumCaseNameShouldBeString()
+
+
+}//end class
diff --git a/tests/Core/Tokenizer/Tokenizer/RecurseScopeMapDefaultKeywordConditionsTest.inc b/tests/Core/Tokenizer/Tokenizer/RecurseScopeMapDefaultKeywordConditionsTest.inc
new file mode 100644
index 0000000000..648149d2ff
--- /dev/null
+++ b/tests/Core/Tokenizer/Tokenizer/RecurseScopeMapDefaultKeywordConditionsTest.inc
@@ -0,0 +1,203 @@
+ 1,
+ 2 => 2,
+ /* testSimpleMatchDefault */
+ default => 'default',
+ };
+}
+
+function switchWithDefault($i) {
+ switch ($i) {
+ case 1:
+ return 1;
+ case 2:
+ return 2;
+ /* testSimpleSwitchDefault */
+ default:
+ return 'default';
+ }
+}
+
+function switchWithDefaultAndCurlies($i) {
+ switch ($i) {
+ case 1:
+ return 1;
+ case 2:
+ return 2;
+ /* testSimpleSwitchDefaultWithCurlies */
+ default: {
+ return 'default';
+ }
+ }
+}
+
+function matchWithDefaultInSwitch() {
+ switch ($something) {
+ case 'foo':
+ $var = [1, 2, 3];
+ $var = match ($i) {
+ 1 => 1,
+ /* testMatchDefaultNestedInSwitchCase1 */
+ default => 'default',
+ };
+ continue;
+
+ case 'bar' :
+ $i = callMe($a, $b);
+ return match ($i) {
+ 1 => 1,
+ /* testMatchDefaultNestedInSwitchCase2 */
+ default => 'default',
+ };
+
+ /* testSwitchDefault */
+ default;
+ echo 'something', match ($i) {
+ 1, => 1,
+ /* testMatchDefaultNestedInSwitchDefault */
+ default, => 'default',
+ };
+ break;
+ }
+}
+
+function switchWithDefaultInMatch() {
+ $x = match ($y) {
+ 5, 8 => function($z) {
+ switch($z) {
+ case 'a';
+ $var = [1, 2, 3];
+ return 'a';
+ /* testSwitchDefaultNestedInMatchCase */
+ default:
+ $var = [1, 2, 3];
+ return 'default1';
+ }
+ },
+ /* testMatchDefault */
+ default => function($z) {
+ switch($z) {
+ case 'a':
+ $i = callMe($a, $b);
+ return 'b';
+ /* testSwitchDefaultNestedInMatchDefault */
+ default:
+ $i = callMe($a, $b);
+ return 'default2';
+ }
+ }
+ };
+}
+
+function shortArrayWithConstantKey() {
+ $arr = [
+ /* testClassConstantAsShortArrayKey */
+ SomeClass::DEFAULT => 1,
+ /* testClassPropertyAsShortArrayKey */
+ SomeClass->DEFAULT => 1,
+ /* testNamespacedConstantAsShortArrayKey */
+ // Intentional parse error PHP < 8.0. Reserved keyword used as namespaced constant.
+ SomeNamespace\DEFAULT => 1,
+ /* testFQNGlobalConstantAsShortArrayKey */
+ // Intentional parse error in PHP < 8.0. Reserved keyword used as global constant.
+ \DEFAULT => 1,
+ ];
+}
+
+function longArrayWithConstantKey() {
+ $arr = array(
+ /* testClassConstantAsLongArrayKey */
+ SomeClass::DEFAULT => 1,
+ );
+}
+
+function yieldWithConstantKey() {
+ /* testClassConstantAsYieldKey */
+ yield SomeClass::DEFAULT => 1;
+}
+
+function longArrayWithConstantKeyNestedInMatch() {
+ return match($x) {
+ /* testMatchDefaultWithNestedLongArrayWithClassConstantKey */
+ DEFAULT => array(
+ /* testClassConstantAsLongArrayKeyNestedInMatch */
+ SomeClass::DEFAULT => match($x) {
+ /* testMatchDefaultWithNestedLongArrayWithClassConstantKeyLevelDown */
+ DEFAULT => array(
+ /* testClassConstantAsLongArrayKeyNestedInMatchLevelDown */
+ SomeClass::DEFAULT => 1,
+ ),
+ },
+ ),
+ };
+}
+
+function shortArrayWithConstantKeyNestedInMatch() {
+ return match($x) {
+ /* testMatchDefaultWithNestedShortArrayWithClassConstantKey */
+ DEFAULT => [
+ /* testClassConstantAsShortArrayKeyNestedInMatch */
+ SomeClass::DEFAULT => match($x) {
+ /* testMatchDefaultWithNestedShortArrayWithClassConstantKeyLevelDown */
+ DEFAULT => [
+ /* testClassConstantAsShortArrayKeyNestedInMatchLevelDown */
+ SomeClass::DEFAULT => 1,
+ ],
+ },
+ ],
+ };
+}
+
+
+function longArrayWithConstantKeyWithNestedMatch() {
+ return array(
+ /* testClassConstantAsLongArrayKeyWithNestedMatch */
+ SomeClass::DEFAULT => match($x) {
+ /* testMatchDefaultNestedInLongArray */
+ DEFAULT => 'foo'
+ },
+ );
+}
+
+function shortArrayWithConstantKeyWithNestedMatch() {
+ return [
+ /* testClassConstantAsShortArrayKeyWithNestedMatch */
+ SomeClass::DEFAULT => match($x) {
+ /* testMatchDefaultNestedInShortArray */
+ DEFAULT => 'foo'
+ },
+ ];
+}
+
+function switchWithConstantNonDefault($i) {
+ switch ($i) {
+ /* testClassConstantInSwitchCase */
+ case SomeClass::DEFAULT:
+ return 1;
+
+ /* testClassPropertyInSwitchCase */
+ case SomeClass->DEFAULT:
+ return 2;
+
+ /* testNamespacedConstantInSwitchCase */
+ // Intentional parse error PHP < 8.0. Reserved keyword used as constant.
+ case SomeNamespace\DEFAULT:
+ return 2;
+
+ /* testNamespaceRelativeConstantInSwitchCase */
+ // Intentional parse error PHP < 8.0. Reserved keyword used as global constant.
+ case namespace\DEFAULT:
+ return 2;
+ }
+}
+
+class Foo {
+ /* testClassConstant */
+ const DEFAULT = 'foo';
+
+ /* testMethodDeclaration */
+ public function default() {}
+}
diff --git a/tests/Core/Tokenizer/DefaultKeywordTest.php b/tests/Core/Tokenizer/Tokenizer/RecurseScopeMapDefaultKeywordConditionsTest.php
similarity index 95%
rename from tests/Core/Tokenizer/DefaultKeywordTest.php
rename to tests/Core/Tokenizer/Tokenizer/RecurseScopeMapDefaultKeywordConditionsTest.php
index cee3d263de..fb3a76afbf 100644
--- a/tests/Core/Tokenizer/DefaultKeywordTest.php
+++ b/tests/Core/Tokenizer/Tokenizer/RecurseScopeMapDefaultKeywordConditionsTest.php
@@ -8,9 +8,11 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\Tokenizer;
-final class DefaultKeywordTest extends AbstractTokenizerTestCase
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
+
+final class RecurseScopeMapDefaultKeywordConditionsTest extends AbstractTokenizerTestCase
{
@@ -24,7 +26,6 @@ final class DefaultKeywordTest extends AbstractTokenizerTestCase
* @param string $testContent The token content to look for.
*
* @dataProvider dataMatchDefault
- * @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
* @covers PHP_CodeSniffer\Tokenizers\Tokenizer::recurseScopeMap
*
* @return void
@@ -36,8 +37,8 @@ public function testMatchDefault($testMarker, $testContent='default')
$token = $this->getTargetToken($testMarker, [T_MATCH_DEFAULT, T_DEFAULT, T_STRING], $testContent);
$tokenArray = $tokens[$token];
+ // Make sure we're looking at the right token.
$this->assertSame(T_MATCH_DEFAULT, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_MATCH_DEFAULT (code)');
- $this->assertSame('T_MATCH_DEFAULT', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_MATCH_DEFAULT (type)');
$this->assertArrayNotHasKey('scope_condition', $tokenArray, 'Scope condition is set');
$this->assertArrayNotHasKey('scope_opener', $tokenArray, 'Scope opener is set');
@@ -128,8 +129,8 @@ public function testSwitchDefault($testMarker, $openerOffset, $closerOffset, $co
$expectedScopeOpener = ($token + $openerOffset);
$expectedScopeCloser = ($token + $closerOffset);
+ // Make sure we're looking at the right token.
$this->assertSame(T_DEFAULT, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_DEFAULT (code)');
- $this->assertSame('T_DEFAULT', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_DEFAULT (type)');
$this->assertArrayHasKey('scope_condition', $tokenArray, 'Scope condition is not set');
$this->assertArrayHasKey('scope_opener', $tokenArray, 'Scope opener is not set');
@@ -226,7 +227,7 @@ public static function dataSwitchDefault()
* @param string $testContent The token content to look for.
*
* @dataProvider dataNotDefaultKeyword
- * @covers PHP_CodeSniffer\Tokenizers\PHP::processAdditional
+ * @covers PHP_CodeSniffer\Tokenizers\Tokenizer::recurseScopeMap
*
* @return void
*/
@@ -237,8 +238,8 @@ public function testNotDefaultKeyword($testMarker, $testContent='DEFAULT')
$token = $this->getTargetToken($testMarker, [T_MATCH_DEFAULT, T_DEFAULT, T_STRING], $testContent);
$tokenArray = $tokens[$token];
+ // Make sure we're looking at the right token.
$this->assertSame(T_STRING, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (code)');
- $this->assertSame('T_STRING', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (type)');
$this->assertArrayNotHasKey('scope_condition', $tokenArray, 'Scope condition is set');
$this->assertArrayNotHasKey('scope_opener', $tokenArray, 'Scope opener is set');
@@ -325,7 +326,6 @@ public static function dataNotDefaultKeyword()
*
* @link https://github.com/squizlabs/PHP_CodeSniffer/issues/3326
*
- * @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
* @covers PHP_CodeSniffer\Tokenizers\Tokenizer::recurseScopeMap
*
* @return void
diff --git a/tests/Core/Tokenizer/ScopeSettingWithNamespaceOperatorTest.inc b/tests/Core/Tokenizer/Tokenizer/ScopeSettingWithNamespaceOperatorTest.inc
similarity index 100%
rename from tests/Core/Tokenizer/ScopeSettingWithNamespaceOperatorTest.inc
rename to tests/Core/Tokenizer/Tokenizer/ScopeSettingWithNamespaceOperatorTest.inc
diff --git a/tests/Core/Tokenizer/ScopeSettingWithNamespaceOperatorTest.php b/tests/Core/Tokenizer/Tokenizer/ScopeSettingWithNamespaceOperatorTest.php
similarity index 97%
rename from tests/Core/Tokenizer/ScopeSettingWithNamespaceOperatorTest.php
rename to tests/Core/Tokenizer/Tokenizer/ScopeSettingWithNamespaceOperatorTest.php
index 5359b7282d..dba98cdb02 100644
--- a/tests/Core/Tokenizer/ScopeSettingWithNamespaceOperatorTest.php
+++ b/tests/Core/Tokenizer/Tokenizer/ScopeSettingWithNamespaceOperatorTest.php
@@ -7,7 +7,9 @@
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
-namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer\Tokenizer;
+
+use PHP_CodeSniffer\Tests\Core\Tokenizer\AbstractTokenizerTestCase;
final class ScopeSettingWithNamespaceOperatorTest extends AbstractTokenizerTestCase
{