diff --git a/package.xml b/package.xml
index 4932f5df71..4ec06d3f57 100644
--- a/package.xml
+++ b/package.xml
@@ -109,6 +109,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
+
+
@@ -1979,6 +1981,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
+
+
@@ -2038,6 +2042,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
+
+
diff --git a/src/Tokenizers/PHP.php b/src/Tokenizers/PHP.php
index 6135e957cf..3c5969ade3 100644
--- a/src/Tokenizers/PHP.php
+++ b/src/Tokenizers/PHP.php
@@ -812,6 +812,81 @@ protected function tokenize($string)
continue;
}//end if
+ /*
+ As of PHP 8.0 fully qualified, partially qualified and namespace relative
+ identifier names are tokenized differently.
+ This "undoes" the new tokenization so the tokenization will be the same in
+ in PHP 5, 7 and 8.
+ */
+
+ if (PHP_VERSION_ID >= 80000
+ && $tokenIsArray === true
+ && ($token[0] === T_NAME_QUALIFIED
+ || $token[0] === T_NAME_FULLY_QUALIFIED
+ || $token[0] === T_NAME_RELATIVE)
+ ) {
+ $name = $token[1];
+
+ if ($token[0] === T_NAME_FULLY_QUALIFIED) {
+ $newToken = [];
+ $newToken['code'] = T_NS_SEPARATOR;
+ $newToken['type'] = 'T_NS_SEPARATOR';
+ $newToken['content'] = '\\';
+ $finalTokens[$newStackPtr] = $newToken;
+ ++$newStackPtr;
+
+ $name = ltrim($name, '\\');
+ }
+
+ if ($token[0] === T_NAME_RELATIVE) {
+ $newToken = [];
+ $newToken['code'] = T_NAMESPACE;
+ $newToken['type'] = 'T_NAMESPACE';
+ $newToken['content'] = substr($name, 0, 9);
+ $finalTokens[$newStackPtr] = $newToken;
+ ++$newStackPtr;
+
+ $newToken = [];
+ $newToken['code'] = T_NS_SEPARATOR;
+ $newToken['type'] = 'T_NS_SEPARATOR';
+ $newToken['content'] = '\\';
+ $finalTokens[$newStackPtr] = $newToken;
+ ++$newStackPtr;
+
+ $name = substr($name, 10);
+ }
+
+ $parts = explode('\\', $name);
+ $partCount = count($parts);
+ $lastPart = ($partCount - 1);
+
+ foreach ($parts as $i => $part) {
+ $newToken = [];
+ $newToken['code'] = T_STRING;
+ $newToken['type'] = 'T_STRING';
+ $newToken['content'] = $part;
+ $finalTokens[$newStackPtr] = $newToken;
+ ++$newStackPtr;
+
+ if ($i !== $lastPart) {
+ $newToken = [];
+ $newToken['code'] = T_NS_SEPARATOR;
+ $newToken['type'] = 'T_NS_SEPARATOR';
+ $newToken['content'] = '\\';
+ $finalTokens[$newStackPtr] = $newToken;
+ ++$newStackPtr;
+ }
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ $type = Util\Tokens::tokenName($token[0]);
+ $content = Util\Common::prepareForOutput($token[1]);
+ echo "\t\t* token $stackPtr split into individual tokens; was: $type => $content".PHP_EOL;
+ }
+
+ continue;
+ }//end if
+
/*
Before PHP 7.0, the "yield from" was tokenized as
T_YIELD, T_WHITESPACE and T_STRING. So look for
@@ -1122,6 +1197,9 @@ protected function tokenize($string)
}
if ($tokenType === T_STRING
+ || $tokenType === T_NAME_FULLY_QUALIFIED
+ || $tokenType === T_NAME_RELATIVE
+ || $tokenType === T_NAME_QUALIFIED
|| $tokenType === T_ARRAY
|| $tokenType === T_NS_SEPARATOR
) {
@@ -1278,6 +1356,10 @@ protected function tokenize($string)
tokenized as T_STRING even if it appears to be a different token,
such as when writing code like: function default(): foo
so go forward and change the token type before it is processed.
+
+ Note: this should not be done for `function Level\Name` within a
+ group use statement for the PHP 8 identifier name tokens as it
+ would interfere with the re-tokenization of those.
*/
if ($tokenIsArray === true
@@ -1295,7 +1377,10 @@ protected function tokenize($string)
}
}
- if ($x < $numTokens && is_array($tokens[$x]) === true) {
+ if ($x < $numTokens
+ && is_array($tokens[$x]) === true
+ && $tokens[$x][0] !== T_NAME_QUALIFIED
+ ) {
if (PHP_CODESNIFFER_VERBOSITY > 1) {
$oldType = Util\Tokens::tokenName($tokens[$x][0]);
echo "\t\t* token $x changed from $oldType to T_STRING".PHP_EOL;
diff --git a/src/Util/Tokens.php b/src/Util/Tokens.php
index bc3a32414a..a374735343 100644
--- a/src/Util/Tokens.php
+++ b/src/Util/Tokens.php
@@ -124,6 +124,19 @@
define('T_FN', 'PHPCS_T_FN');
}
+// Some PHP 8.0 tokens, replicated for lower versions.
+if (defined('T_NAME_QUALIFIED') === false) {
+ define('T_NAME_QUALIFIED', 'PHPCS_T_NAME_QUALIFIED');
+}
+
+if (defined('T_NAME_FULLY_QUALIFIED') === false) {
+ define('T_NAME_FULLY_QUALIFIED', 'PHPCS_T_NAME_FULLY_QUALIFIED');
+}
+
+if (defined('T_NAME_RELATIVE') === false) {
+ define('T_NAME_RELATIVE', 'PHPCS_T_NAME_RELATIVE');
+}
+
// Tokens used for parsing doc blocks.
define('T_DOC_COMMENT_STAR', 'PHPCS_T_DOC_COMMENT_STAR');
define('T_DOC_COMMENT_WHITESPACE', 'PHPCS_T_DOC_COMMENT_WHITESPACE');
diff --git a/tests/Core/Tokenizer/UndoNamespacedNameSingleTokenTest.inc b/tests/Core/Tokenizer/UndoNamespacedNameSingleTokenTest.inc
new file mode 100644
index 0000000000..f64dd62321
--- /dev/null
+++ b/tests/Core/Tokenizer/UndoNamespacedNameSingleTokenTest.inc
@@ -0,0 +1,147 @@
+
+ * @copyright 2020 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
+
+use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest;
+
+class UndoNamespacedNameSingleTokenTest extends AbstractMethodUnitTest
+{
+
+
+ /**
+ * Test that identifier names are tokenized the same across PHP versions, based on the PHP 5/7 tokenization.
+ *
+ * @param string $testMarker The comment prefacing the test.
+ * @param array $expectedTokens The tokenization expected.
+ *
+ * @dataProvider dataIdentifierTokenization
+ * @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
+ *
+ * @return void
+ */
+ public function testIdentifierTokenization($testMarker, $expectedTokens)
+ {
+ $tokens = self::$phpcsFile->getTokens();
+ $identifier = $this->getTargetToken($testMarker, constant($expectedTokens[0]['type']));
+
+ foreach ($expectedTokens as $key => $tokenInfo) {
+ $this->assertSame(constant($tokenInfo['type']), $tokens[$identifier]['code']);
+ $this->assertSame($tokenInfo['type'], $tokens[$identifier]['type']);
+ $this->assertSame($tokenInfo['content'], $tokens[$identifier]['content']);
+
+ ++$identifier;
+ }
+
+ }//end testIdentifierTokenization()
+
+
+ /**
+ * Data provider.
+ *
+ * @see testIdentifierTokenization()
+ *
+ * @return array
+ */
+ public function dataIdentifierTokenization()
+ {
+ return [
+ [
+ '/* testNamespaceDeclaration */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Package',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testNamespaceDeclarationWithLevels */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Vendor',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'SubLevel',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Domain',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testUseStatement */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testUseStatementWithLevels */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Vendor',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Level',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Domain',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testFunctionUseStatement */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function_name',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testFunctionUseStatementWithLevels */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Vendor',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Level',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function_in_ns',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testConstantUseStatement */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'const',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'CONSTANT_NAME',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testConstantUseStatementWithLevels */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'const',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Vendor',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Level',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'OTHER_CONSTANT',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testMultiUseUnqualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'UnqualifiedClassName',
+ ],
+ [
+ 'type' => 'T_COMMA',
+ 'content' => ',',
+ ],
+ ],
+ ],
+ [
+ '/* testMultiUsePartiallyQualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Sublevel',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'PartiallyClassName',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testGroupUseStatement */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Vendor',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Level',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_OPEN_USE_GROUP',
+ 'content' => '{',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'AnotherDomain',
+ ],
+ [
+ 'type' => 'T_COMMA',
+ 'content' => ',',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function_grouped',
+ ],
+ [
+ 'type' => 'T_COMMA',
+ 'content' => ',',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'const',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'CONSTANT_GROUPED',
+ ],
+ [
+ 'type' => 'T_COMMA',
+ 'content' => ',',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Sub',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'YetAnotherDomain',
+ ],
+ [
+ 'type' => 'T_COMMA',
+ 'content' => ',',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'SubLevelA',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function_grouped_too',
+ ],
+ [
+ 'type' => 'T_COMMA',
+ 'content' => ',',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'const',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'SubLevelB',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'CONSTANT_GROUPED_TOO',
+ ],
+ [
+ 'type' => 'T_COMMA',
+ 'content' => ',',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_CLOSE_USE_GROUP',
+ 'content' => '}',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testClassName */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'MyClass',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ ],
+ ],
+ [
+ '/* testExtendedFQN */',
+ [
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Vendor',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Level',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'FQN',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ ],
+ ],
+ [
+ '/* testImplementsRelative */',
+ [
+ [
+ 'type' => 'T_NAMESPACE',
+ 'content' => 'namespace',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Name',
+ ],
+ [
+ 'type' => 'T_COMMA',
+ 'content' => ',',
+ ],
+ ],
+ ],
+ [
+ '/* testImplementsFQN */',
+ [
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Fully',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Qualified',
+ ],
+ [
+ 'type' => 'T_COMMA',
+ 'content' => ',',
+ ],
+ ],
+ ],
+ [
+ '/* testImplementsUnqualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Unqualified',
+ ],
+ [
+ 'type' => 'T_COMMA',
+ 'content' => ',',
+ ],
+ ],
+ ],
+ [
+ '/* testImplementsPartiallyQualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Sub',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Level',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Name',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ ],
+ ],
+ [
+ '/* testFunctionName */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function_name',
+ ],
+ [
+ 'type' => 'T_OPEN_PARENTHESIS',
+ 'content' => '(',
+ ],
+ ],
+ ],
+ [
+ '/* testTypeDeclarationRelative */',
+ [
+ [
+ 'type' => 'T_NAMESPACE',
+ 'content' => 'namespace',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Name',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ ],
+ ],
+ [
+ '/* testTypeDeclarationFQN */',
+ [
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Fully',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Qualified',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Name',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ ],
+ ],
+ [
+ '/* testTypeDeclarationUnqualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Unqualified',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ ],
+ ],
+ [
+ '/* testTypeDeclarationPartiallyQualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Sublevel',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Name',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ ],
+ ],
+ [
+ '/* testReturnTypeFQN */',
+ [
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Name',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ ],
+ ],
+ [
+ '/* testFunctionCallRelative */',
+ [
+ [
+ 'type' => 'T_NAMESPACE',
+ 'content' => 'NameSpace',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function_name',
+ ],
+ [
+ 'type' => 'T_OPEN_PARENTHESIS',
+ 'content' => '(',
+ ],
+ ],
+ ],
+ [
+ '/* testFunctionCallFQN */',
+ [
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Vendor',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Package',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function_name',
+ ],
+ [
+ 'type' => 'T_OPEN_PARENTHESIS',
+ 'content' => '(',
+ ],
+ ],
+ ],
+ [
+ '/* testFunctionCallUnqualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function_name',
+ ],
+ [
+ 'type' => 'T_OPEN_PARENTHESIS',
+ 'content' => '(',
+ ],
+ ],
+ ],
+ [
+ '/* testFunctionPartiallyQualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Level',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function_name',
+ ],
+ [
+ 'type' => 'T_OPEN_PARENTHESIS',
+ 'content' => '(',
+ ],
+ ],
+ ],
+ [
+ '/* testCatchRelative */',
+ [
+ [
+ 'type' => 'T_NAMESPACE',
+ 'content' => 'namespace',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'SubLevel',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Exception',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ ],
+ ],
+ [
+ '/* testCatchFQN */',
+ [
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Exception',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ ],
+ ],
+ [
+ '/* testCatchUnqualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Exception',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ ],
+ ],
+ [
+ '/* testCatchPartiallyQualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Level',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Exception',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ ],
+ ],
+ [
+ '/* testNewRelative */',
+ [
+ [
+ 'type' => 'T_NAMESPACE',
+ 'content' => 'namespace',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_OPEN_PARENTHESIS',
+ 'content' => '(',
+ ],
+ ],
+ ],
+ [
+ '/* testNewFQN */',
+ [
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Vendor',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_OPEN_PARENTHESIS',
+ 'content' => '(',
+ ],
+ ],
+ ],
+ [
+ '/* testNewUnqualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testNewPartiallyQualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Level',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testDoubleColonRelative */',
+ [
+ [
+ 'type' => 'T_NAMESPACE',
+ 'content' => 'namespace',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_DOUBLE_COLON',
+ 'content' => '::',
+ ],
+ ],
+ ],
+ [
+ '/* testDoubleColonFQN */',
+ [
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_DOUBLE_COLON',
+ 'content' => '::',
+ ],
+ ],
+ ],
+ [
+ '/* testDoubleColonUnqualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_DOUBLE_COLON',
+ 'content' => '::',
+ ],
+ ],
+ ],
+ [
+ '/* testDoubleColonPartiallyQualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Level',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_DOUBLE_COLON',
+ 'content' => '::',
+ ],
+ ],
+ ],
+ [
+ '/* testInstanceOfRelative */',
+ [
+ [
+ 'type' => 'T_NAMESPACE',
+ 'content' => 'namespace',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testInstanceOfFQN */',
+ [
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Full',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_CLOSE_PARENTHESIS',
+ 'content' => ')',
+ ],
+ ],
+ ],
+ [
+ '/* testInstanceOfUnqualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ ],
+ ],
+ [
+ '/* testInstanceOfPartiallyQualified */',
+ [
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Partially',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'ClassName',
+ ],
+ [
+ 'type' => 'T_SEMICOLON',
+ 'content' => ';',
+ ],
+ ],
+ ],
+ [
+ '/* testInvalidInPHP8Whitespace */',
+ [
+ [
+ 'type' => 'T_NAMESPACE',
+ 'content' => 'namespace',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Sublevel',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'function_name',
+ ],
+ [
+ 'type' => 'T_OPEN_PARENTHESIS',
+ 'content' => '(',
+ ],
+ ],
+ ],
+ [
+ '/* testInvalidInPHP8Comments */',
+ [
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Fully',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_PHPCS_IGNORE',
+ 'content' => '// phpcs:ignore Stnd.Cat.Sniff -- for reasons
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Qualified',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_COMMENT',
+ 'content' => '/* comment */',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => ' ',
+ ],
+ [
+ 'type' => 'T_NS_SEPARATOR',
+ 'content' => '\\',
+ ],
+ [
+ 'type' => 'T_STRING',
+ 'content' => 'Name',
+ ],
+ [
+ 'type' => 'T_WHITESPACE',
+ 'content' => '
+',
+ ],
+ ],
+ ],
+ ];
+
+ }//end dataIdentifierTokenization()
+
+
+}//end class