Skip to content

Commit

Permalink
UseStatements::splitImportUseStatement(): improve handling of leading…
Browse files Browse the repository at this point in the history
… backslash

Import use statements should not be declared with a leading backslash and doing so is discouraged by PHP itself:

> Note that for namespaced names (fully qualified namespace names containing namespace separator, such as `Foo\Bar` as opposed to global names that do not, such as `FooBar`), the leading backslash is unnecessary and not recommended, as import names must be fully qualified, and are not processed relative to the current namespace.

Ref: https://www.php.net/manual/en/language.namespaces.importing.php

However, it is not a parse error to declare an import with a leading backslash. Until now, the behaviour of this method in such a case was undefined, which, in practice, meant that the leading backslash would be included in the full name.

For consistency, however, this is undesirable and makes the names found in the return value more awkward to handle by sniffs using the method.

This commit now explicitly defines the behaviour around leading backslashes in import use statements and prevents these from being included in the names in the return value.

Includes unit tests.
  • Loading branch information
jrfnl committed May 10, 2024
1 parent 08b7d23 commit f7e6542
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 7 deletions.
4 changes: 2 additions & 2 deletions PHPCSUtils/Utils/UseStatements.php
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,9 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr)
case \T_COMMA:
if ($name !== '') {
if ($useGroup === true) {
$statements[$type][$alias] = $baseName . $name;
$statements[$type][$alias] = \ltrim($baseName, '\\') . $name;
} else {
$statements[$type][$alias] = $name;
$statements[$type][$alias] = \ltrim($name, '\\');
}
}

Expand Down
19 changes: 14 additions & 5 deletions Tests/Utils/UseStatements/SplitImportUseStatementTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ use MyNamespace\MyClass;
/* testUsePlainAliased */
use MyNamespace \ YourClass as ClassAlias;

/* testUsePlainLeadingBackslash */
use \MyNamespace\TheirClass;

/* testUseMultipleWithComments */
use Vendor\Foo\ClassA as ClassABC,
Vendor \ /*comment*/ Bar \ /*another comment */ InterfaceB,
Expand All @@ -38,7 +41,7 @@ use CONST MyNamespace\MY_CONST;
use const MyNamespace\YOUR_CONST as CONST_ALIAS;

/* testUseConstMultiple */
use const foo\math\PI, foo\math\GOLDEN_RATIO as MATH_GOLDEN;
use const foo\math\PI, \foo\math\GOLDEN_RATIO as MATH_GOLDEN;

/* testGroupUse */
use some\namespacing\{
Expand All @@ -47,6 +50,12 @@ use some\namespacing\{
another\level\SomeClassC as C
};

/* testGroupUseLeadingBackslash */
use \world\namespacing\{
SomeClassA,
deeper\level\SomeClassB
};

/* testGroupUseFunctionTrailingComma */
use function bar\math\{
Msin,
Expand All @@ -70,15 +79,15 @@ use Some\NS\ {
};

/* testUsePlainReservedKeyword */
// Intentional parse error - use of reserved keyword in namespace.
// Intentional parse error for PHP < 8.0 - use of reserved keyword in namespace.
use Vendor\break\ClassName;

/* testUseFunctionPlainReservedKeyword */
// Intentional parse error - use of reserved keyword in namespace.
// Intentional parse error for PHP < 8.0 - use of reserved keyword in namespace.
use function Vendor\YourNamespace\switch\yourFunction;

/* testUseConstPlainReservedKeyword */
// Intentional parse error - use of reserved keyword in namespace.
// Intentional parse error for PHP < 8.0 - use of reserved keyword in namespace.
use const Vendor\YourNamespace\function\yourConst;

/* testUsePlainAliasReservedKeyword */
Expand All @@ -88,7 +97,7 @@ use Vendor\YourNamespace\ClassName as class;
/* testUsePlainAliasReservedKeywordFunction */
// Intentional parse error - use of reserved keyword as alias.
use Vendor\{
YourNamespace\ClassName as function
YourNamespace\ClassName as function
};

/* testUsePlainAliasReservedKeywordConst */
Expand Down
20 changes: 20 additions & 0 deletions Tests/Utils/UseStatements/SplitImportUseStatementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ public static function dataSplitImportUseStatement()
'const' => [],
],
],
'plain-with-leading-backslash' => [
'testMarker' => '/* testUsePlainLeadingBackslash */',
'expected' => [
'name' => ['TheirClass' => 'MyNamespace\TheirClass'],
'function' => [],
'const' => [],
],
],

'multiple-with-comments' => [
'testMarker' => '/* testUseMultipleWithComments */',
'expected' => [
Expand Down Expand Up @@ -203,6 +212,17 @@ public static function dataSplitImportUseStatement()
'const' => [],
],
],
'group-with-leading-backslash' => [
'testMarker' => '/* testGroupUseLeadingBackslash */',
'expected' => [
'name' => [
'SomeClassA' => 'world\namespacing\SomeClassA',
'SomeClassB' => 'world\namespacing\deeper\level\SomeClassB',
],
'function' => [],
'const' => [],
],
],
'group-function-trailing-comma' => [
'testMarker' => '/* testGroupUseFunctionTrailingComma */',
'expected' => [
Expand Down

0 comments on commit f7e6542

Please sign in to comment.