Skip to content

Commit

Permalink
minor #37783 [ClassLoader][Routing] Fix namespace parsing on php 8 (d…
Browse files Browse the repository at this point in the history
…errabus)

This PR was merged into the 3.4 branch.

Discussion
----------

[ClassLoader][Routing] Fix namespace parsing on php 8

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | N/A
| License       | MIT
| Doc PR        | N/A

The way namespace declarations are parsed has changed in php 8 (see php/php-src#5827). This PR should fix the corresponding issues in the ClassLoader and Routing components.

Note that Doctrine Annotations suffers from the same issue (doctrine/annotations#339). I had to run the Routing tests locally with doctrine/annotations#344 applied.

Commits
-------

3d293b2 [ClassLoader][Routing] Fix namespace parsing on php 8.
  • Loading branch information
fabpot committed Aug 10, 2020
2 parents cd5769f + 3d293b2 commit 1dcb67e
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
7 changes: 6 additions & 1 deletion src/Symfony/Component/ClassLoader/ClassCollectionLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ public static function fixNamespaceDeclarations($source)
$inNamespace = false;
$tokens = token_get_all($source);

$nsTokens = [T_WHITESPACE => true, T_NS_SEPARATOR => true, T_STRING => true];
if (\defined('T_NAME_QUALIFIED')) {
$nsTokens[T_NAME_QUALIFIED] = true;
}

for ($i = 0; isset($tokens[$i]); ++$i) {
$token = $tokens[$i];
if (!isset($token[1]) || 'b"' === $token) {
Expand All @@ -230,7 +235,7 @@ public static function fixNamespaceDeclarations($source)
$rawChunk .= $token[1];

// namespace name and whitespaces
while (isset($tokens[++$i][1]) && \in_array($tokens[$i][0], [T_WHITESPACE, T_NS_SEPARATOR, T_STRING])) {
while (isset($tokens[++$i][1], $nsTokens[$tokens[$i][0]])) {
$rawChunk .= $tokens[$i][1];
}
if ('{' === $tokens[$i]) {
Expand Down
7 changes: 6 additions & 1 deletion src/Symfony/Component/ClassLoader/ClassMapGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ private static function findClasses($path)
$contents = file_get_contents($path);
$tokens = token_get_all($contents);

$nsTokens = [T_STRING => true, T_NS_SEPARATOR => true];
if (\defined('T_NAME_QUALIFIED')) {
$nsTokens[T_NAME_QUALIFIED] = true;
}

$classes = [];

$namespace = '';
Expand All @@ -110,7 +115,7 @@ private static function findClasses($path)
$namespace = '';
// If there is a namespace, extract it
while (isset($tokens[++$i][1])) {
if (\in_array($tokens[$i][0], [T_STRING, T_NS_SEPARATOR])) {
if (isset($nsTokens[$tokens[$i][0]])) {
$namespace .= $tokens[$i][1];
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ protected function findClass($file)
throw new \InvalidArgumentException(sprintf('The file "%s" does not contain PHP code. Did you forgot to add the "<?php" start tag at the beginning of the file?', $file));
}

$nsTokens = [T_NS_SEPARATOR => true, T_STRING => true];
if (\defined('T_NAME_QUALIFIED')) {
$nsTokens[T_NAME_QUALIFIED] = true;
}

for ($i = 0; isset($tokens[$i]); ++$i) {
$token = $tokens[$i];

Expand All @@ -108,9 +113,9 @@ protected function findClass($file)
return $namespace.'\\'.$token[1];
}

if (true === $namespace && T_STRING === $token[0]) {
if (true === $namespace && isset($nsTokens[$token[0]])) {
$namespace = $token[1];
while (isset($tokens[++$i][1]) && \in_array($tokens[$i][0], [T_NS_SEPARATOR, T_STRING])) {
while (isset($tokens[++$i][1], $nsTokens[$tokens[$i][0]])) {
$namespace .= $tokens[$i][1];
}
$token = $tokens[$i];
Expand Down

0 comments on commit 1dcb67e

Please sign in to comment.