Skip to content

Commit 90dd786

Browse files
committed
PEAR/PSR2/FunctionCallSignature: support anonymous classes
The function call spacing for anonymous class instantiations was so far not checked by these or any other PHPCS native sniffs. In my opinion, object instantiations of anonymous classes should be treated the same an object instantiations of non-anonymous classes. The `PEAR.Functions.FunctionCallSignature` and the `PSR2.Methods.FunctionCallSignature` sniffs check the object instantiation spacing for non-anonymous classes, so seem like the logical place to also check the spacing for anonymous class object instantiations. To add this support, the `T_ANON_CLASS` token has been added to the `Tokens::$functionNameTokens` array. Notes: * As PSR12 does not specify the spacing between the `class` keyword and the open parenthesis (or rather is unclear about it), I am explicitly excluding anonymous classes from the "space before open parenthesis" check. Related: squizlabs/PHP_CodeSniffer 3200 * I have verified all other uses of the `Tokens::$functionNameTokens` array within PHPCS. - The `Generic.WhiteSpace.ArbitraryParenthesesSpacing` sniff is not affected by the change and already contains a test to verify this. - The `Squiz.Operators.ComparisonOperatorUsage` sniff also is not affected by the change. I have added tests to confirm this in a separate commit. * Obviously external standards using the token array _may_ be affected by the change, but a scan of the most popular external standards showed me that the token array is rarely used and when it is used, is mostly used incorrectly. The only sniff using the array, which looks to be using it correctly and which may be affected, is the `WebImpressCodingStandard.WhiteSpace.ScopeIndent` sniff. Whether this is positive or negative is up to michalbundyra to determine. Includes unit tests for both the `PEAR.Functions.FunctionCallSignature` and the `PSR2.Methods.FunctionCallSignature` sniffs .
1 parent 177890c commit 90dd786

8 files changed

+101
-1
lines changed

src/Standards/PEAR/Sniffs/Functions/FunctionCallSignatureSniff.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ public function process(File $phpcsFile, $stackPtr)
120120

121121
$closeBracket = $tokens[$openBracket]['parenthesis_closer'];
122122

123-
if (($stackPtr + 1) !== $openBracket) {
123+
if ($tokens[$stackPtr]['code'] !== T_ANON_CLASS
124+
&& ($stackPtr + 1) !== $openBracket
125+
) {
124126
// Checking this: $value = my_function[*](...).
125127
$error = 'Space before opening parenthesis of function call prohibited';
126128
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBeforeOpenBracket');

src/Standards/PEAR/Tests/Functions/FunctionCallSignatureUnitTest.inc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,3 +548,24 @@ array_fill_keys(
548548
), value: true,
549549
);
550550
// phpcs:set PEAR.Functions.FunctionCallSignature allowMultipleArguments true
551+
552+
// Anonymous object instantiations are treated the same as a normal call.
553+
$anon = new class() {};
554+
$anon = new class($foo, true) {};
555+
$anon = new class(
556+
$foo,
557+
true,
558+
10
559+
) {};
560+
561+
$anon = new class( ) {};
562+
$anon = new class( $foo, true ) {};
563+
$anon = new class($foo,
564+
565+
true, 10) {};
566+
567+
// ... though do not enforce no space between the class keyword and the open parenthesis.
568+
$anon = new class () {};
569+
570+
// And anonymous object instantiations without parentheses are ignored.
571+
$anon = new class {};

src/Standards/PEAR/Tests/Functions/FunctionCallSignatureUnitTest.inc.fixed

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,3 +563,25 @@ array_fill_keys(
563563
value: true,
564564
);
565565
// phpcs:set PEAR.Functions.FunctionCallSignature allowMultipleArguments true
566+
567+
// Anonymous object instantiations are treated the same as a normal call.
568+
$anon = new class() {};
569+
$anon = new class($foo, true) {};
570+
$anon = new class(
571+
$foo,
572+
true,
573+
10
574+
) {};
575+
576+
$anon = new class() {};
577+
$anon = new class($foo, true) {};
578+
$anon = new class(
579+
$foo,
580+
true, 10
581+
) {};
582+
583+
// ... though do not enforce no space between the class keyword and the open parenthesis.
584+
$anon = new class () {};
585+
586+
// And anonymous object instantiations without parentheses are ignored.
587+
$anon = new class {};

src/Standards/PEAR/Tests/Functions/FunctionCallSignatureUnitTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ public function getErrorList($testFile='FunctionCallSignatureUnitTest.inc')
131131
546 => 1,
132132
547 => 1,
133133
548 => 1,
134+
561 => 2,
135+
562 => 2,
136+
563 => 1,
137+
564 => 1,
138+
565 => 2,
134139
];
135140

136141
}//end getErrorList()

src/Standards/PSR2/Tests/Methods/FunctionCallSignatureUnitTest.inc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,24 @@ array_fill_keys(
265265
), value: true,
266266
);
267267
// phpcs:set PSR2.Methods.FunctionCallSignature allowMultipleArguments false
268+
269+
// Anonymous object instantiations are treated the same as a normal call.
270+
$anon = new class() {};
271+
$anon = new class($foo, true) {};
272+
$anon = new class(
273+
$foo,
274+
true,
275+
10
276+
) {};
277+
278+
$anon = new class( ) {};
279+
$anon = new class( $foo, true ) {};
280+
$anon = new class($foo,
281+
282+
true, 10) {};
283+
284+
// ... though do not enforce no space between the class keyword and the open parenthesis.
285+
$anon = new class () {};
286+
287+
// And anonymous object instantiations without parentheses are ignored.
288+
$anon = new class {};

src/Standards/PSR2/Tests/Methods/FunctionCallSignatureUnitTest.inc.fixed

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,26 @@ array_fill_keys(
281281
), value: true,
282282
);
283283
// phpcs:set PSR2.Methods.FunctionCallSignature allowMultipleArguments false
284+
285+
// Anonymous object instantiations are treated the same as a normal call.
286+
$anon = new class() {};
287+
$anon = new class($foo, true) {};
288+
$anon = new class(
289+
$foo,
290+
true,
291+
10
292+
) {};
293+
294+
$anon = new class() {};
295+
$anon = new class($foo, true) {};
296+
$anon = new class(
297+
$foo,
298+
true,
299+
10
300+
) {};
301+
302+
// ... though do not enforce no space between the class keyword and the open parenthesis.
303+
$anon = new class () {};
304+
305+
// And anonymous object instantiations without parentheses are ignored.
306+
$anon = new class {};

src/Standards/PSR2/Tests/Methods/FunctionCallSignatureUnitTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ public function getErrorList()
7171
258 => 1,
7272
263 => 1,
7373
264 => 1,
74+
278 => 2,
75+
279 => 2,
76+
280 => 1,
77+
281 => 1,
78+
282 => 3,
7479
];
7580

7681
}//end getErrorList()

src/Util/Tokens.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ final class Tokens
630630
T_SELF => T_SELF,
631631
T_PARENT => T_PARENT,
632632
T_STATIC => T_STATIC,
633+
T_ANON_CLASS => T_ANON_CLASS,
633634
];
634635

635636
/**

0 commit comments

Comments
 (0)