Skip to content

Commit 059989d

Browse files
committed
Merge branch 'feature/php-8.2-dynamic-properties-are-deprecated' of https://github.com/jrfnl/PHP_CodeSniffer
2 parents ae84ad2 + 48c2ae3 commit 059989d

20 files changed

+991
-47
lines changed

package.xml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,32 @@ http://pear.php.net/dtd/package-2.0.xsd">
144144
</dir>
145145
</dir>
146146
<dir name="Ruleset">
147+
<dir name="Fixtures">
148+
<dir name="Sniffs">
149+
<dir name="Category">
150+
<file baseinstalldir="" name="SetPropertyAllowedAsDeclaredSniff.php" role="test" />
151+
<file baseinstalldir="" name="SetPropertyAllowedViaMagicMethodSniff.php" role="test" />
152+
<file baseinstalldir="" name="SetPropertyAllowedViaStdClassSniff.php" role="test" />
153+
<file baseinstalldir="" name="SetPropertyNotAllowedViaAttributeSniff.php" role="test" />
154+
</dir>
155+
</dir>
156+
</dir>
147157
<file baseinstalldir="" name="RuleInclusionTest.php" role="test" />
148158
<file baseinstalldir="" name="RuleInclusionTest.xml" role="test" />
149159
<file baseinstalldir="" name="RuleInclusionTest-include.xml" role="test" />
150160
<file baseinstalldir="" name="RuleInclusionAbsoluteLinuxTest.php" role="test" />
151161
<file baseinstalldir="" name="RuleInclusionAbsoluteLinuxTest.xml" role="test" />
152162
<file baseinstalldir="" name="RuleInclusionAbsoluteWindowsTest.php" role="test" />
153163
<file baseinstalldir="" name="RuleInclusionAbsoluteWindowsTest.xml" role="test" />
164+
<file baseinstalldir="" name="SetSniffPropertyTest.php" role="test" />
165+
<file baseinstalldir="" name="SetPropertyAllowedAsDeclaredTest.xml" role="test" />
166+
<file baseinstalldir="" name="SetPropertyAllowedViaMagicMethodTest.xml" role="test" />
167+
<file baseinstalldir="" name="SetPropertyAllowedViaStdClassTest.xml" role="test" />
168+
<file baseinstalldir="" name="SetPropertyAppliesPropertyToMultipleSniffsInCategoryTest.xml" role="test" />
169+
<file baseinstalldir="" name="SetPropertyThrowsErrorOnInvalidPropertyTest.xml" role="test" />
170+
<file baseinstalldir="" name="SetPropertyNotAllowedViaAttributeTest.xml" role="test" />
171+
<file baseinstalldir="" name="SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForStandardTest.xml" role="test" />
172+
<file baseinstalldir="" name="SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForCategoryTest.xml" role="test" />
154173
</dir>
155174
<dir name="Sniffs">
156175
<file baseinstalldir="" name="AbstractArraySniffTest.inc" role="test" />
@@ -2134,6 +2153,19 @@ http://pear.php.net/dtd/package-2.0.xsd">
21342153
<install as="CodeSniffer/Core/Ruleset/RuleInclusionAbsoluteLinuxTest.xml" name="tests/Core/Ruleset/RuleInclusionAbsoluteLinuxTest.xml" />
21352154
<install as="CodeSniffer/Core/Ruleset/RuleInclusionAbsoluteWindowsTest.php" name="tests/Core/Ruleset/RuleInclusionAbsoluteWindowsTest.php" />
21362155
<install as="CodeSniffer/Core/Ruleset/RuleInclusionAbsoluteWindowsTest.xml" name="tests/Core/Ruleset/RuleInclusionAbsoluteWindowsTest.xml" />
2156+
<install as="CodeSniffer/Core/Ruleset/SetSniffPropertyTest.php" name="tests/Core/Ruleset/SetSniffPropertyTest.php" />
2157+
<install as="CodeSniffer/Core/Ruleset/SetPropertyAllowedAsDeclaredTest.xml" name="tests/Core/Ruleset/SetPropertyAllowedAsDeclaredTest.xml" />
2158+
<install as="CodeSniffer/Core/Ruleset/SetPropertyAllowedViaMagicMethodTest.xml" name="tests/Core/Ruleset/SetPropertyAllowedViaMagicMethodTest.xml" />
2159+
<install as="CodeSniffer/Core/Ruleset/SetPropertyAllowedViaStdClassTest.xml" name="tests/Core/Ruleset/SetPropertyAllowedViaStdClassTest.xml" />
2160+
<install as="CodeSniffer/Core/Ruleset/SetPropertyAppliesPropertyToMultipleSniffsInCategoryTest.xml" name="tests/Core/Ruleset/SetPropertyAppliesPropertyToMultipleSniffsInCategoryTest.xml" />
2161+
<install as="CodeSniffer/Core/Ruleset/SetPropertyNotAllowedViaAttributeTest.xml" name="tests/Core/Ruleset/SetPropertyNotAllowedViaAttributeTest.xml" />
2162+
<install as="CodeSniffer/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForCategoryTest.xml" name="tests/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForCategoryTest.xml" />
2163+
<install as="CodeSniffer/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForStandardTest.xml" name="tests/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForStandardTest.xml" />
2164+
<install as="CodeSniffer/Core/Ruleset/SetPropertyThrowsErrorOnInvalidPropertyTest.xml" name="tests/Core/Ruleset/SetPropertyThrowsErrorOnInvalidPropertyTest.xml" />
2165+
<install as="CodeSniffer/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedAsDeclaredSniff.php" name="tests/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedAsDeclaredSniff.php" />
2166+
<install as="CodeSniffer/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedViaMagicMethodSniff.php" name="tests/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedViaMagicMethodSniff.php" />
2167+
<install as="CodeSniffer/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedViaStdClassSniff.php" name="tests/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedViaStdClassSniff.php" />
2168+
<install as="CodeSniffer/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyNotAllowedViaAttributeSniff.php" name="tests/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyNotAllowedViaAttributeSniff.php" />
21372169
<install as="CodeSniffer/Core/Sniffs/AbstractArraySniffTest.inc" name="tests/Core/Sniffs/AbstractArraySniffTest.inc" />
21382170
<install as="CodeSniffer/Core/Sniffs/AbstractArraySniffTest.php" name="tests/Core/Sniffs/AbstractArraySniffTest.php" />
21392171
<install as="CodeSniffer/Core/Sniffs/AbstractArraySniffTestable.php" name="tests/Core/Sniffs/AbstractArraySniffTestable.php" />
@@ -2242,6 +2274,19 @@ http://pear.php.net/dtd/package-2.0.xsd">
22422274
<install as="CodeSniffer/Core/Ruleset/RuleInclusionAbsoluteLinuxTest.xml" name="tests/Core/Ruleset/RuleInclusionAbsoluteLinuxTest.xml" />
22432275
<install as="CodeSniffer/Core/Ruleset/RuleInclusionAbsoluteWindowsTest.php" name="tests/Core/Ruleset/RuleInclusionAbsoluteWindowsTest.php" />
22442276
<install as="CodeSniffer/Core/Ruleset/RuleInclusionAbsoluteWindowsTest.xml" name="tests/Core/Ruleset/RuleInclusionAbsoluteWindowsTest.xml" />
2277+
<install as="CodeSniffer/Core/Ruleset/SetSniffPropertyTest.php" name="tests/Core/Ruleset/SetSniffPropertyTest.php" />
2278+
<install as="CodeSniffer/Core/Ruleset/SetPropertyAllowedAsDeclaredTest.xml" name="tests/Core/Ruleset/SetPropertyAllowedAsDeclaredTest.xml" />
2279+
<install as="CodeSniffer/Core/Ruleset/SetPropertyAllowedViaMagicMethodTest.xml" name="tests/Core/Ruleset/SetPropertyAllowedViaMagicMethodTest.xml" />
2280+
<install as="CodeSniffer/Core/Ruleset/SetPropertyAllowedViaStdClassTest.xml" name="tests/Core/Ruleset/SetPropertyAllowedViaStdClassTest.xml" />
2281+
<install as="CodeSniffer/Core/Ruleset/SetPropertyNotAllowedViaAttributeTest.xml" name="tests/Core/Ruleset/SetPropertyNotAllowedViaAttributeTest.xml" />
2282+
<install as="CodeSniffer/Core/Ruleset/SetPropertyAppliesPropertyToMultipleSniffsInCategoryTest.xml" name="tests/Core/Ruleset/SetPropertyAppliesPropertyToMultipleSniffsInCategoryTest.xml" />
2283+
<install as="CodeSniffer/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForCategoryTest.xml" name="tests/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForCategoryTest.xml" />
2284+
<install as="CodeSniffer/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForStandardTest.xml" name="tests/Core/Ruleset/SetPropertyDoesNotThrowErrorOnInvalidPropertyWhenSetForStandardTest.xml" />
2285+
<install as="CodeSniffer/Core/Ruleset/SetPropertyThrowsErrorOnInvalidPropertyTest.xml" name="tests/Core/Ruleset/SetPropertyThrowsErrorOnInvalidPropertyTest.xml" />
2286+
<install as="CodeSniffer/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedAsDeclaredSniff.php" name="tests/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedAsDeclaredSniff.php" />
2287+
<install as="CodeSniffer/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedViaMagicMethodSniff.php" name="tests/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedViaMagicMethodSniff.php" />
2288+
<install as="CodeSniffer/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedViaStdClassSniff.php" name="tests/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyAllowedViaStdClassSniff.php" />
2289+
<install as="CodeSniffer/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyNotAllowedViaAttributeSniff.php" name="tests/Core/Ruleset/Fixtures/Sniffs/Category/SetPropertyNotAllowedViaAttributeSniff.php" />
22452290
<install as="CodeSniffer/Core/Sniffs/AbstractArraySniffTest.inc" name="tests/Core/Sniffs/AbstractArraySniffTest.inc" />
22462291
<install as="CodeSniffer/Core/Sniffs/AbstractArraySniffTest.php" name="tests/Core/Sniffs/AbstractArraySniffTest.php" />
22472292
<install as="CodeSniffer/Core/Sniffs/AbstractArraySniffTestable.php" name="tests/Core/Sniffs/AbstractArraySniffTestable.php" />

phpcs.xml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
<exclude-pattern>*/src/Standards/*/Tests/*\.(inc|css|js)$</exclude-pattern>
1212
<exclude-pattern>*/tests/Core/*/*\.(inc|css|js)$</exclude-pattern>
13+
<exclude-pattern>*/tests/Core/*/Fixtures/*\.php$</exclude-pattern>
1314

1415
<arg name="basepath" value="."/>
1516
<arg name="colors"/>

scripts/ValidatePEAR/ValidatePEARPackageXML.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,11 @@ protected function checkFileTag($tag, $currentDirectory='')
232232
$valid = false;
233233
} else {
234234
// Limited validation of the "role" tags.
235-
if (strpos($name, 'Test.') !== false && $role !== 'test') {
235+
if ((strpos($name, 'tests/') === 0 || strpos($name, 'Test.') !== false) && $role !== 'test') {
236236
echo "- Test files should have the role 'test'. Found: '$role' for file '{$name}'.".PHP_EOL;
237237
$valid = false;
238-
} else if ((strpos($name, 'Standard.xml') !== false || strpos($name, 'Sniff.php') !== false)
238+
} else if (strpos($name, 'tests/') !== 0
239+
&& (strpos($name, 'Standard.xml') !== false || strpos($name, 'Sniff.php') !== false)
239240
&& $role !== 'php'
240241
) {
241242
echo "- Sniff files, including sniff documentation files should have the role 'php'. Found: '$role' for file '{$name}'.".PHP_EOL;

src/Files/File.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,12 @@ public function process()
379379
if (isset($this->ruleset->sniffCodes[$parts[0]]) === true) {
380380
$listenerCode = array_shift($parts);
381381
$propertyCode = array_shift($parts);
382-
$propertyValue = rtrim(implode(' ', $parts), " */\r\n");
382+
$settings = [
383+
'value' => rtrim(implode(' ', $parts), " */\r\n"),
384+
'scope' => 'sniff',
385+
];
383386
$listenerClass = $this->ruleset->sniffCodes[$listenerCode];
384-
$this->ruleset->setSniffProperty($listenerClass, $propertyCode, $propertyValue);
387+
$this->ruleset->setSniffProperty($listenerClass, $propertyCode, $settings);
385388
}
386389
}
387390
}
@@ -403,9 +406,12 @@ public function process()
403406
$listenerCode = $token['sniffCode'];
404407
if (isset($this->ruleset->sniffCodes[$listenerCode]) === true) {
405408
$propertyCode = $token['sniffProperty'];
406-
$propertyValue = $token['sniffPropertyValue'];
409+
$settings = [
410+
'value' => $token['sniffPropertyValue'],
411+
'scope' => 'sniff',
412+
];
407413
$listenerClass = $this->ruleset->sniffCodes[$listenerCode];
408-
$this->ruleset->setSniffProperty($listenerClass, $propertyCode, $propertyValue);
414+
$this->ruleset->setSniffProperty($listenerClass, $propertyCode, $settings);
409415
}
410416
}
411417
}//end if

src/Ruleset.php

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHP_CodeSniffer\Exceptions\RuntimeException;
1515
use PHP_CodeSniffer\Util;
16+
use stdClass;
1617

1718
class Ruleset
1819
{
@@ -960,6 +961,11 @@ private function processRule($rule, $newSniffs, $depth=0)
960961
if (isset($rule->properties) === true
961962
&& $this->shouldProcessElement($rule->properties) === true
962963
) {
964+
$propertyScope = 'standard';
965+
if ($code === $ref || substr($ref, -9) === 'Sniff.php') {
966+
$propertyScope = 'sniff';
967+
}
968+
963969
foreach ($rule->properties->property as $prop) {
964970
if ($this->shouldProcessElement($prop) === false) {
965971
continue;
@@ -980,9 +986,9 @@ private function processRule($rule, $newSniffs, $depth=0)
980986
$values = [];
981987
if (isset($prop['extend']) === true
982988
&& (string) $prop['extend'] === 'true'
983-
&& isset($this->ruleset[$code]['properties'][$name]) === true
989+
&& isset($this->ruleset[$code]['properties'][$name]['value']) === true
984990
) {
985-
$values = $this->ruleset[$code]['properties'][$name];
991+
$values = $this->ruleset[$code]['properties'][$name]['value'];
986992
}
987993

988994
if (isset($prop->element) === true) {
@@ -1017,7 +1023,10 @@ private function processRule($rule, $newSniffs, $depth=0)
10171023
}
10181024
}//end if
10191025

1020-
$this->ruleset[$code]['properties'][$name] = $values;
1026+
$this->ruleset[$code]['properties'][$name] = [
1027+
'value' => $values,
1028+
'scope' => $propertyScope,
1029+
];
10211030
if (PHP_CODESNIFFER_VERBOSITY > 1) {
10221031
echo str_repeat("\t", $depth);
10231032
echo "\t\t=> array property \"$name\" set to \"$printValue\"";
@@ -1028,7 +1037,10 @@ private function processRule($rule, $newSniffs, $depth=0)
10281037
echo PHP_EOL;
10291038
}
10301039
} else {
1031-
$this->ruleset[$code]['properties'][$name] = (string) $prop['value'];
1040+
$this->ruleset[$code]['properties'][$name] = [
1041+
'value' => (string) $prop['value'],
1042+
'scope' => $propertyScope,
1043+
];
10321044
if (PHP_CODESNIFFER_VERBOSITY > 1) {
10331045
echo str_repeat("\t", $depth);
10341046
echo "\t\t=> property \"$name\" set to \"".(string) $prop['value'].'"';
@@ -1218,8 +1230,8 @@ public function populateTokenListeners()
12181230

12191231
// Set custom properties.
12201232
if (isset($this->ruleset[$sniffCode]['properties']) === true) {
1221-
foreach ($this->ruleset[$sniffCode]['properties'] as $name => $value) {
1222-
$this->setSniffProperty($sniffClass, $name, $value);
1233+
foreach ($this->ruleset[$sniffCode]['properties'] as $name => $settings) {
1234+
$this->setSniffProperty($sniffClass, $name, $settings);
12231235
}
12241236
}
12251237

@@ -1286,18 +1298,76 @@ public function populateTokenListeners()
12861298
*
12871299
* @param string $sniffClass The class name of the sniff.
12881300
* @param string $name The name of the property to change.
1289-
* @param string $value The new value of the property.
1301+
* @param array $settings Array with the new value of the property and the scope of the property being set.
12901302
*
12911303
* @return void
1304+
*
1305+
* @throws \PHP_CodeSniffer\Exceptions\RuntimeException When attempting to set a non-existent property on a sniff
1306+
* which doesn't declare the property or explicitly supports
1307+
* dynamic properties.
12921308
*/
1293-
public function setSniffProperty($sniffClass, $name, $value)
1309+
public function setSniffProperty($sniffClass, $name, $settings)
12941310
{
12951311
// Setting a property for a sniff we are not using.
12961312
if (isset($this->sniffs[$sniffClass]) === false) {
12971313
return;
12981314
}
12991315

1300-
$name = trim($name);
1316+
$name = trim($name);
1317+
$propertyName = $name;
1318+
if (substr($propertyName, -2) === '[]') {
1319+
$propertyName = substr($propertyName, 0, -2);
1320+
}
1321+
1322+
/*
1323+
* BC-compatibility layer for $settings using the pre-PHPCS 3.8.0 format.
1324+
*
1325+
* Prior to PHPCS 3.8.0, `$settings` was expected to only contain the new _value_
1326+
* for the property (which could be an array).
1327+
* Since PHPCS 3.8.0, `$settings` is expected to be an array with two keys: 'scope'
1328+
* and 'value', where 'scope' indicates whether the property should be set to the given 'value'
1329+
* for one individual sniff or for all sniffs in a standard.
1330+
*
1331+
* This BC-layer is only for integrations with PHPCS which may call this method directly
1332+
* and will be removed in PHPCS 4.0.0.
1333+
*/
1334+
1335+
if (is_array($settings) === false
1336+
|| isset($settings['scope'], $settings['value']) === false
1337+
) {
1338+
// This will be an "old" format value.
1339+
$settings = [
1340+
'value' => $settings,
1341+
'scope' => 'standard',
1342+
];
1343+
1344+
trigger_error(
1345+
__FUNCTION__.': the format of the $settings parameter has changed from (mixed) $value to array(\'scope\' => \'sniff|standard\', \'value\' => $value). Please update your integration code. See PR #3629 for more information.',
1346+
E_USER_DEPRECATED
1347+
);
1348+
}
1349+
1350+
$isSettable = false;
1351+
$sniffObject = $this->sniffs[$sniffClass];
1352+
if (property_exists($sniffObject, $propertyName) === true
1353+
|| ($sniffObject instanceof stdClass) === true
1354+
|| method_exists($sniffObject, '__set') === true
1355+
) {
1356+
$isSettable = true;
1357+
}
1358+
1359+
if ($isSettable === false) {
1360+
if ($settings['scope'] === 'sniff') {
1361+
$notice = "Ruleset invalid. Property \"$propertyName\" does not exist on sniff ";
1362+
$notice .= array_search($sniffClass, $this->sniffCodes, true);
1363+
throw new RuntimeException($notice);
1364+
}
1365+
1366+
return;
1367+
}
1368+
1369+
$value = $settings['value'];
1370+
13011371
if (is_string($value) === true) {
13021372
$value = trim($value);
13031373
}
@@ -1312,7 +1382,7 @@ public function setSniffProperty($sniffClass, $name, $value)
13121382
} else if ($value === 'false') {
13131383
$value = false;
13141384
} else if (substr($name, -2) === '[]') {
1315-
$name = substr($name, 0, -2);
1385+
$name = $propertyName;
13161386
$values = [];
13171387
if ($value !== null) {
13181388
foreach (explode(',', $value) as $val) {
@@ -1328,7 +1398,7 @@ public function setSniffProperty($sniffClass, $name, $value)
13281398
$value = $values;
13291399
}
13301400

1331-
$this->sniffs[$sniffClass]->$name = $value;
1401+
$sniffObject->$name = $value;
13321402

13331403
}//end setSniffProperty()
13341404

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
/**
3+
* Test fixture.
4+
*
5+
* @see \PHP_CodeSniffer\Tests\Core\Ruleset\SetSniffPropertyTest
6+
*/
7+
8+
namespace Fixtures\Sniffs\Category;
9+
10+
use PHP_CodeSniffer\Files\File;
11+
use PHP_CodeSniffer\Sniffs\Sniff;
12+
13+
class SetPropertyAllowedAsDeclaredSniff implements Sniff
14+
{
15+
16+
public $arbitrarystring;
17+
public $arbitraryarray;
18+
19+
public function register()
20+
{
21+
return [T_WHITESPACE];
22+
}
23+
24+
public function process(File $phpcsFile, $stackPtr)
25+
{
26+
// Do something.
27+
}
28+
}

0 commit comments

Comments
 (0)