From 6888c0f00c1c7aee70b680c6e3515d4146ed5902 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 27 Nov 2024 13:19:32 +0100 Subject: [PATCH 1/4] Ruleset: hard deprecate $supportedTokenizers set to CSS/JS only Support for the JS and CSS Tokenizers will be removed in PHPCS 4.0. This was announced in squizlabs/PHP_CodeSniffer 2448 and has been formalized via a soft deprecation (documentation and changelog only) in the PHPCS 3.9.0 release (see 276). This commit implements a deprecation notice to alert sniff maintainers and ruleset maintainers to sniffs which are exclusively aimed at CSS and/or JS files. This deprecation notice will not be shown if the sniff is formally deprecated via an implementation of the `DeprecatedSniff` interface (to prevent duplicate notifications). Refs: * https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/tag/3.3.0 Fixes 740 Includes an update to two tests in the `PopulateTokenListenersTest` to make these use one of the newly introduced fixtures to make these tests less dependent on the actual sniffs in PHPCS. --- src/Ruleset.php | 23 +++++- tests/Core/Filters/Filter/AcceptTest.xml | 2 + .../ImplementsDeprecatedInterfaceSniff.php | 46 ++++++++++++ .../ListensForCSSAndJSSniff.php | 30 ++++++++ .../ListensForCSSAndUnrecognizedSniff.php | 30 ++++++++ .../ListensForCSSSniff.php | 27 +++++++ .../ListensForEmptySniff.php | 27 +++++++ .../SupportedTokenizers/ListensForJSSniff.php | 27 +++++++ .../ListensForPHPAndCSSAndJSSniff.php | 34 +++++++++ .../ListensForUnrecognizedTokenizersSniff.php | 30 ++++++++ ...eTokenListenersSupportedTokenizersTest.php | 73 +++++++++++++++++++ ...eTokenListenersSupportedTokenizersTest.xml | 8 ++ .../Ruleset/PopulateTokenListenersTest.php | 20 ++--- .../Ruleset/PopulateTokenListenersTest.xml | 2 +- ...ssRulesetAutoExpandSniffsDirectoryTest.xml | 1 + ...nInvalidPropertyWhenSetForStandardTest.xml | 1 + .../Ruleset/ShowSniffDeprecationsTest.xml | 1 + 17 files changed, 369 insertions(+), 13 deletions(-) create mode 100644 tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ImplementsDeprecatedInterfaceSniff.php create mode 100644 tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ListensForCSSAndJSSniff.php create mode 100644 tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ListensForCSSAndUnrecognizedSniff.php create mode 100644 tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ListensForCSSSniff.php create mode 100644 tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ListensForEmptySniff.php create mode 100644 tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ListensForJSSniff.php create mode 100644 tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ListensForPHPAndCSSAndJSSniff.php create mode 100644 tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ListensForUnrecognizedTokenizersSniff.php create mode 100644 tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.php create mode 100644 tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.xml diff --git a/src/Ruleset.php b/src/Ruleset.php index b6279bf9f3..df6aab08c5 100644 --- a/src/Ruleset.php +++ b/src/Ruleset.php @@ -1457,7 +1457,9 @@ public function populateTokenListeners() $sniffCode = Common::getSniffCode($sniffClass); $this->sniffCodes[$sniffCode] = $sniffClass; + $isDeprecated = false; if ($this->sniffs[$sniffClass] instanceof DeprecatedSniff) { + $isDeprecated = true; $this->deprecatedSniffs[$sniffCode] = $sniffClass; } @@ -1470,13 +1472,30 @@ public function populateTokenListeners() $tokenizers = []; $vars = get_class_vars($sniffClass); - if (isset($vars['supportedTokenizers']) === true) { + if (empty($vars['supportedTokenizers']) === false) { foreach ($vars['supportedTokenizers'] as $tokenizer) { $tokenizers[$tokenizer] = $tokenizer; } + + if ($isDeprecated === false + && in_array('PHP', $vars['supportedTokenizers'], true) === false + ) { + if (in_array('CSS', $vars['supportedTokenizers'], true) === true + || in_array('JS', $vars['supportedTokenizers'], true) === true + ) { + $message = 'Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + } else { + // Just in case someone has an integration with a custom tokenizer. + $message = 'Support for custom tokenizers will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + } + + $message .= 'The %s sniff is listening for %s.'; + $message = sprintf($message, $sniffCode, implode(', ', $vars['supportedTokenizers'])); + $this->msgCache->add($message, MessageCollector::DEPRECATED); + } } else { $tokenizers = ['PHP' => 'PHP']; - } + }//end if $tokens = $this->sniffs[$sniffClass]->register(); if (is_array($tokens) === false) { diff --git a/tests/Core/Filters/Filter/AcceptTest.xml b/tests/Core/Filters/Filter/AcceptTest.xml index 3d3e1de080..2800298ebf 100644 --- a/tests/Core/Filters/Filter/AcceptTest.xml +++ b/tests/Core/Filters/Filter/AcceptTest.xml @@ -8,6 +8,8 @@ */Other/Main\.php$ + + /anything/* diff --git a/tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ImplementsDeprecatedInterfaceSniff.php b/tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ImplementsDeprecatedInterfaceSniff.php new file mode 100644 index 0000000000..af095072bd --- /dev/null +++ b/tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SupportedTokenizers/ImplementsDeprecatedInterfaceSniff.php @@ -0,0 +1,46 @@ + + * @copyright 2025 PHPCSStandards and contributors + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Tests\Core\Ruleset; + +use PHP_CodeSniffer\Ruleset; +use PHP_CodeSniffer\Tests\ConfigDouble; +use PHP_CodeSniffer\Tests\Core\Ruleset\AbstractRulesetTestCase; + +/** + * Test the Ruleset::populateTokenListeners() method shows a deprecation notice for sniffs supporting JS and/or CSS tokenizers. + * + * @covers \PHP_CodeSniffer\Ruleset::populateTokenListeners + */ +final class PopulateTokenListenersSupportedTokenizersTest extends AbstractRulesetTestCase +{ + + + /** + * Verify that a deprecation notice is shown if a non-deprecated sniff supports the JS/CSS tokenizer(s). + * + * Additionally, this test verifies that: + * - No deprecation notice is thrown if the complete sniff is deprecated. + * - No deprecation notice is thrown when the sniff _also_ supports PHP. + * - No deprecation notice is thrown when no tokenizers are supported (not sure why anyone would do that, but :shrug:). + * + * @return void + */ + public function testDeprecatedTokenizersTriggerDeprecationNotice() + { + // Set up the ruleset. + $standard = __DIR__.'/PopulateTokenListenersSupportedTokenizersTest.xml'; + $config = new ConfigDouble(["--standard=$standard"]); + + // Using different expectations per OS as the order in which files are gathered differs per OS. + if (stripos(PHP_OS, 'WIN') === 0) { + $expected = 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSSAndJS sniff is listening for CSS, JS.'.PHP_EOL; + $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSSAndUnrecognized sniff is listening for CSS, Unrecognized.'.PHP_EOL; + $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSS sniff is listening for CSS.'.PHP_EOL; + $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + $expected .= 'The TestStandard.SupportedTokenizers.ListensForJS sniff is listening for JS.'.PHP_EOL; + $expected .= 'DEPRECATED: Support for custom tokenizers will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + $expected .= 'The TestStandard.SupportedTokenizers.ListensForUnrecognizedTokenizers sniff is listening for SCSS, TypeScript.'.PHP_EOL.PHP_EOL; + } else { + $expected = 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + $expected .= 'The TestStandard.SupportedTokenizers.ListensForJS sniff is listening for JS.'.PHP_EOL; + $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSSAndJS sniff is listening for CSS, JS.'.PHP_EOL; + $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSSAndUnrecognized sniff is listening for CSS, Unrecognized.'.PHP_EOL; + $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSS sniff is listening for CSS.'.PHP_EOL; + $expected .= 'DEPRECATED: Support for custom tokenizers will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + $expected .= 'The TestStandard.SupportedTokenizers.ListensForUnrecognizedTokenizers sniff is listening for SCSS, TypeScript.'.PHP_EOL.PHP_EOL; + }//end if + + $this->expectOutputString($expected); + + new Ruleset($config); + + }//end testDeprecatedTokenizersTriggerDeprecationNotice() + + +}//end class diff --git a/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.xml b/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.xml new file mode 100644 index 0000000000..1a02eba182 --- /dev/null +++ b/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/Core/Ruleset/PopulateTokenListenersTest.php b/tests/Core/Ruleset/PopulateTokenListenersTest.php index 6f79c10da1..347ffddee7 100644 --- a/tests/Core/Ruleset/PopulateTokenListenersTest.php +++ b/tests/Core/Ruleset/PopulateTokenListenersTest.php @@ -131,31 +131,31 @@ public function testRegistersSniffsToListenToTokens($sniffClass, $expectedCount) public static function dataSniffListensToTokenss() { return [ - 'Generic.Files.EndFileNewline' => [ - 'sniffClass' => 'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\Files\\EndFileNewlineSniff', + 'TestStandard.SupportedTokenizers.ListensForPHPAndCSSAndJS' => [ + 'sniffClass' => 'Fixtures\\TestStandard\\Sniffs\\SupportedTokenizers\\ListensForPHPAndCSSAndJSSniff', 'expectedCount' => 2, ], - 'Generic.NamingConventions.UpperCaseConstantName' => [ + 'Generic.NamingConventions.UpperCaseConstantName' => [ 'sniffClass' => 'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\NamingConventions\\UpperCaseConstantNameSniff', 'expectedCount' => 2, ], - 'PSR1.Files.SideEffects' => [ + 'PSR1.Files.SideEffects' => [ 'sniffClass' => 'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Files\\SideEffectsSniff', 'expectedCount' => 1, ], - 'PSR12.ControlStructures.BooleanOperatorPlacement' => [ + 'PSR12.ControlStructures.BooleanOperatorPlacement' => [ 'sniffClass' => 'PHP_CodeSniffer\\Standards\\PSR12\\Sniffs\\ControlStructures\\BooleanOperatorPlacementSniff', 'expectedCount' => 5, ], - 'Squiz.ControlStructures.ForEachLoopDeclaration' => [ + 'Squiz.ControlStructures.ForEachLoopDeclaration' => [ 'sniffClass' => 'PHP_CodeSniffer\\Standards\\Squiz\\Sniffs\\ControlStructures\\ForEachLoopDeclarationSniff', 'expectedCount' => 1, ], - 'TestStandard.Deprecated.WithReplacement' => [ + 'TestStandard.Deprecated.WithReplacement' => [ 'sniffClass' => 'Fixtures\\TestStandard\\Sniffs\\Deprecated\\WithReplacementSniff', 'expectedCount' => 1, ], - 'TestStandard.ValidSniffs.RegisterEmptyArray' => [ + 'TestStandard.ValidSniffs.RegisterEmptyArray' => [ 'sniffClass' => 'Fixtures\\TestStandard\\Sniffs\\ValidSniffs\\RegisterEmptyArraySniff', 'expectedCount' => 0, ], @@ -313,7 +313,7 @@ public function testSetsClassAndSourceIndexes() */ public function testSetsSupportedTokenizersToPHPByDefault() { - $exclude = 'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\Files\\EndFileNewlineSniff'; + $exclude = 'Fixtures\\TestStandard\\Sniffs\\SupportedTokenizers\\ListensForPHPAndCSSAndJSSniff'; $expected = ['PHP' => 'PHP']; foreach (self::$ruleset->tokenListeners as $token => $listeners) { @@ -354,7 +354,7 @@ public function testSetsSupportedTokenizersToPHPByDefault() */ public function testSetsSupportedTokenizersWhenProvidedBySniff($token) { - $sniffClass = 'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\Files\\EndFileNewlineSniff'; + $sniffClass = 'Fixtures\\TestStandard\\Sniffs\\SupportedTokenizers\\ListensForPHPAndCSSAndJSSniff'; $expected = [ 'PHP' => 'PHP', 'JS' => 'JS', diff --git a/tests/Core/Ruleset/PopulateTokenListenersTest.xml b/tests/Core/Ruleset/PopulateTokenListenersTest.xml index f61ab500d0..2116048ad0 100644 --- a/tests/Core/Ruleset/PopulateTokenListenersTest.xml +++ b/tests/Core/Ruleset/PopulateTokenListenersTest.xml @@ -21,7 +21,7 @@ - + diff --git a/tests/Core/Ruleset/ProcessRulesetAutoExpandSniffsDirectoryTest.xml b/tests/Core/Ruleset/ProcessRulesetAutoExpandSniffsDirectoryTest.xml index 3b8b4c9b41..4ca8458e95 100644 --- a/tests/Core/Ruleset/ProcessRulesetAutoExpandSniffsDirectoryTest.xml +++ b/tests/Core/Ruleset/ProcessRulesetAutoExpandSniffsDirectoryTest.xml @@ -4,6 +4,7 @@ + diff --git a/tests/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForStandardTest.xml b/tests/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForStandardTest.xml index 8ce97e2dd3..a7c05017d0 100644 --- a/tests/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForStandardTest.xml +++ b/tests/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForStandardTest.xml @@ -2,6 +2,7 @@ + diff --git a/tests/Core/Ruleset/ShowSniffDeprecationsTest.xml b/tests/Core/Ruleset/ShowSniffDeprecationsTest.xml index ab632b1959..8dee19d8e1 100644 --- a/tests/Core/Ruleset/ShowSniffDeprecationsTest.xml +++ b/tests/Core/Ruleset/ShowSniffDeprecationsTest.xml @@ -5,6 +5,7 @@ + From 72dbaeda523ae723e76b06230a503987ce7a1be9 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 18 Mar 2025 09:37:38 +0100 Subject: [PATCH 2/4] PopulateTokenListenersSupportedTokenizersTest: refactor the test ... as the order in which the files are found is OS-dependent, which makes the order of the messages OS-dependent, which made the test unstable. Fixed now. --- ...eTokenListenersSupportedTokenizersTest.php | 104 ++++++++++++------ 1 file changed, 71 insertions(+), 33 deletions(-) diff --git a/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.php b/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.php index cb8c56b6ac..86d870db22 100644 --- a/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.php +++ b/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.php @@ -21,6 +21,29 @@ final class PopulateTokenListenersSupportedTokenizersTest extends AbstractRulesetTestCase { + /** + * The Config object. + * + * @var \PHP_CodeSniffer\Config + */ + private static $config; + + + /** + * Initialize the config and ruleset objects for this test. + * + * @beforeClass + * + * @return void + */ + public static function initializeConfig() + { + // Set up the ruleset. + $standard = __DIR__.'/PopulateTokenListenersSupportedTokenizersTest.xml'; + self::$config = new ConfigDouble(["--standard=$standard"]); + + }//end initializeConfig() + /** * Verify that a deprecation notice is shown if a non-deprecated sniff supports the JS/CSS tokenizer(s). @@ -30,44 +53,59 @@ final class PopulateTokenListenersSupportedTokenizersTest extends AbstractRulese * - No deprecation notice is thrown when the sniff _also_ supports PHP. * - No deprecation notice is thrown when no tokenizers are supported (not sure why anyone would do that, but :shrug:). * + * {@internal The test uses a data provider to verify the messages as the _order_ of the messages depends + * on the OS on which the tests are run (order in which files are retrieved), which makes the order within the + * complete message to unpredictable to test in one go.} + * + * @param string $expected The expected message output in regex format. + * + * @dataProvider dataDeprecatedTokenizersTriggerDeprecationNotice + * * @return void */ - public function testDeprecatedTokenizersTriggerDeprecationNotice() + public function testDeprecatedTokenizersTriggerDeprecationNotice($expected) { - // Set up the ruleset. - $standard = __DIR__.'/PopulateTokenListenersSupportedTokenizersTest.xml'; - $config = new ConfigDouble(["--standard=$standard"]); - - // Using different expectations per OS as the order in which files are gathered differs per OS. - if (stripos(PHP_OS, 'WIN') === 0) { - $expected = 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSSAndJS sniff is listening for CSS, JS.'.PHP_EOL; - $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSSAndUnrecognized sniff is listening for CSS, Unrecognized.'.PHP_EOL; - $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSS sniff is listening for CSS.'.PHP_EOL; - $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - $expected .= 'The TestStandard.SupportedTokenizers.ListensForJS sniff is listening for JS.'.PHP_EOL; - $expected .= 'DEPRECATED: Support for custom tokenizers will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - $expected .= 'The TestStandard.SupportedTokenizers.ListensForUnrecognizedTokenizers sniff is listening for SCSS, TypeScript.'.PHP_EOL.PHP_EOL; - } else { - $expected = 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - $expected .= 'The TestStandard.SupportedTokenizers.ListensForJS sniff is listening for JS.'.PHP_EOL; - $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSSAndJS sniff is listening for CSS, JS.'.PHP_EOL; - $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSSAndUnrecognized sniff is listening for CSS, Unrecognized.'.PHP_EOL; - $expected .= 'DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - $expected .= 'The TestStandard.SupportedTokenizers.ListensForCSS sniff is listening for CSS.'.PHP_EOL; - $expected .= 'DEPRECATED: Support for custom tokenizers will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - $expected .= 'The TestStandard.SupportedTokenizers.ListensForUnrecognizedTokenizers sniff is listening for SCSS, TypeScript.'.PHP_EOL.PHP_EOL; - }//end if - - $this->expectOutputString($expected); - - new Ruleset($config); + $this->expectOutputRegex($expected); + + new Ruleset(self::$config); }//end testDeprecatedTokenizersTriggerDeprecationNotice() + /** + * Data provider. + * + * @see testDeprecatedTokenizersTriggerDeprecationNotice() + * + * @return array> + */ + public static function dataDeprecatedTokenizersTriggerDeprecationNotice() + { + $cssJsDeprecated = '`DEPRECATED: Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4\.0\.\R'; + $cssJsDeprecated .= 'The %1$s sniff is listening for %2$s\.\R`'; + + $customTokenizer = '`DEPRECATED: Support for custom tokenizers will be removed in PHP_CodeSniffer 4\.0\.\R'; + $customTokenizer .= 'The %1$s sniff is listening for %2$s\.\R`'; + + return [ + 'Listens for CSS' => [ + 'expected' => sprintf($cssJsDeprecated, 'TestStandard.SupportedTokenizers.ListensForCSS', 'CSS'), + ], + 'Listens for JS' => [ + 'expected' => sprintf($cssJsDeprecated, 'TestStandard.SupportedTokenizers.ListensForJS', 'JS'), + ], + 'Listens for both CSS and JS' => [ + 'expected' => sprintf($cssJsDeprecated, 'TestStandard.SupportedTokenizers.ListensForCSSAndJS', 'CSS, JS'), + ], + 'Listens for CSS and something unrecognized' => [ + 'expected' => sprintf($cssJsDeprecated, 'TestStandard.SupportedTokenizers.ListensForCSSAndUnrecognized', 'CSS, Unrecognized'), + ], + 'Listens for only unrecognized tokenizers' => [ + 'expected' => sprintf($customTokenizer, 'TestStandard.SupportedTokenizers.ListensForUnrecognizedTokenizers', 'SCSS, TypeScript'), + ], + ]; + + }//end dataDeprecatedTokenizersTriggerDeprecationNotice() + + }//end class From d43248a02d814577a691cd8c9756f2e0805f3e7a Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 22 Mar 2025 19:49:54 +0100 Subject: [PATCH 3/4] PopulateTokenListenersSupportedTokenizersTest: fix typo --- .../Ruleset/PopulateTokenListenersSupportedTokenizersTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.php b/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.php index 86d870db22..87e6da802b 100644 --- a/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.php +++ b/tests/Core/Ruleset/PopulateTokenListenersSupportedTokenizersTest.php @@ -55,7 +55,7 @@ public static function initializeConfig() * * {@internal The test uses a data provider to verify the messages as the _order_ of the messages depends * on the OS on which the tests are run (order in which files are retrieved), which makes the order within the - * complete message to unpredictable to test in one go.} + * complete message too unpredictable to test in one go.} * * @param string $expected The expected message output in regex format. * From ba8ae35b01e359dcdd23203824b83b470a47a787 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 22 Mar 2025 19:53:47 +0100 Subject: [PATCH 4/4] Ruleset: decouple "supported tokenizers" deprecation from setting the value --- src/Ruleset.php | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/Ruleset.php b/src/Ruleset.php index df6aab08c5..81774a6b7a 100644 --- a/src/Ruleset.php +++ b/src/Ruleset.php @@ -1472,30 +1472,31 @@ public function populateTokenListeners() $tokenizers = []; $vars = get_class_vars($sniffClass); - if (empty($vars['supportedTokenizers']) === false) { - foreach ($vars['supportedTokenizers'] as $tokenizer) { - $tokenizers[$tokenizer] = $tokenizer; + if (empty($vars['supportedTokenizers']) === false + && $isDeprecated === false + && in_array('PHP', $vars['supportedTokenizers'], true) === false + ) { + if (in_array('CSS', $vars['supportedTokenizers'], true) === true + || in_array('JS', $vars['supportedTokenizers'], true) === true + ) { + $message = 'Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; + } else { + // Just in case someone has an integration with a custom tokenizer. + $message = 'Support for custom tokenizers will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; } - if ($isDeprecated === false - && in_array('PHP', $vars['supportedTokenizers'], true) === false - ) { - if (in_array('CSS', $vars['supportedTokenizers'], true) === true - || in_array('JS', $vars['supportedTokenizers'], true) === true - ) { - $message = 'Scanning CSS/JS files is deprecated and support will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - } else { - // Just in case someone has an integration with a custom tokenizer. - $message = 'Support for custom tokenizers will be removed in PHP_CodeSniffer 4.0.'.PHP_EOL; - } + $message .= 'The %s sniff is listening for %s.'; + $message = sprintf($message, $sniffCode, implode(', ', $vars['supportedTokenizers'])); + $this->msgCache->add($message, MessageCollector::DEPRECATED); + } - $message .= 'The %s sniff is listening for %s.'; - $message = sprintf($message, $sniffCode, implode(', ', $vars['supportedTokenizers'])); - $this->msgCache->add($message, MessageCollector::DEPRECATED); + if (isset($vars['supportedTokenizers']) === true) { + foreach ($vars['supportedTokenizers'] as $tokenizer) { + $tokenizers[$tokenizer] = $tokenizer; } } else { $tokenizers = ['PHP' => 'PHP']; - }//end if + } $tokens = $this->sniffs[$sniffClass]->register(); if (is_array($tokens) === false) {