From 4ca680f36f1a734496bb879cdd61ae7ffe38e2e0 Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Mon, 4 May 2020 22:29:19 +0200 Subject: [PATCH 001/218] Strings support class: - length: to calculate string length subtracting certain suffixes - split: to split a string trimming and removing empty values --- src/main/php/PHPMD/Support/Strings.php | 70 +++++++++++ src/test/php/PHPMD/Support/StringsTest.php | 133 +++++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 src/main/php/PHPMD/Support/Strings.php create mode 100644 src/test/php/PHPMD/Support/StringsTest.php diff --git a/src/main/php/PHPMD/Support/Strings.php b/src/main/php/PHPMD/Support/Strings.php new file mode 100644 index 000000000..fdc85c0d5 --- /dev/null +++ b/src/main/php/PHPMD/Support/Strings.php @@ -0,0 +1,70 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +namespace PHPMD\Support; + +use InvalidArgumentException; + +/** + * Utility class to provide string checks and manipulations + */ +class Strings +{ + /** + * Returns the length of the variable name, excluding at most one suffix. + * + * @param string $variableName Variable name to calculate the length for. + * @param array $subtractSuffixes Optional list of suffixes to exclude from the calculated length. + * @return int The length of the string, without suffix, if applicable. + */ + public static function length($variableName, array $subtractSuffixes = array()) + { + $variableNameLength = strlen($variableName); + + foreach ($subtractSuffixes as $suffix) { + $suffixLength = strlen($suffix); + if (substr($variableName, -$suffixLength) === $suffix) { + $variableNameLength -= $suffixLength; + break; + } + } + + return $variableNameLength; + } + + /** + * Split a string with the given separator, trim whitespaces around the parts and remove any empty strings + * + * @param string $separator The separator to split the string with, similar to explode + * @param string $string The string to split + * @return array The trimmed and filtered parts of the string + * @throws InvalidArgumentException When the separator is an empty string + */ + public static function split($separator, $string) + { + if ($separator === '') { + throw new InvalidArgumentException('Separator can\'t me empty string'); + } + + return array_filter( + array_map('trim', explode($separator, $string)), + function ($value) { + return $value !== ''; + } + ); + } +} diff --git a/src/test/php/PHPMD/Support/StringsTest.php b/src/test/php/PHPMD/Support/StringsTest.php new file mode 100644 index 000000000..e92cca064 --- /dev/null +++ b/src/test/php/PHPMD/Support/StringsTest.php @@ -0,0 +1,133 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +namespace PHPMD\Support; + +use PHPMD\AbstractTest; + +/** + * Test case for the {@link \PHPMD\Support\Strings} class. + * + * @covers \PHPMD\Support\Strings + */ +class StringsTest extends AbstractTest +{ + /** + * @return void + */ + public function testLengthEmptyString() + { + static::assertSame(0, Strings::length('')); + } + + /** + * @return void + */ + public function testLengthEmptyStringWithConfiguredSubtractSuffix() + { + static::assertSame(0, Strings::length('', array('Foo', 'Bar'))); + } + + /** + * @return void + */ + public function testLengthStringWithoutSubtractSuffixMatch() + { + static::assertSame(8, Strings::length('UnitTest', array('Foo', 'Bar'))); + } + + /** + * @return void + */ + public function testLengthStringWithSubtractSuffixMatch() + { + static::assertSame(4, Strings::length('UnitBar', array('Foo', 'Bar'))); + } + + /** + * @return void + */ + public function testLengthStringWithDoubleSuffixMatchSubtractOnce() + { + static::assertSame(7, Strings::length('UnitFooBar', array('Foo', 'Bar'))); + } + + /** + * @return void + */ + public function testLengthStringWithPrefixMatchShouldNotSubtract() + { + static::assertSame(11, Strings::length('FooUnitTest', array('Foo', 'Bar'))); + } + + /** + * @return void + */ + public function testSplitEmptySeparatorThrowsException() + { + $this->expectException('\InvalidArgumentException'); + Strings::split('', 'UnitTest'); + } + + /** + * @return void + */ + public function testSplitEmptyString() + { + static::assertSame(array(), Strings::split(',', '')); + } + + /** + * @return void + */ + public function testSplitStringWithoutMatchingSeparator() + { + static::assertSame(array('UnitTest'), Strings::split(',', 'UnitTest')); + } + + /** + * @return void + */ + public function testSplitStringWithMatchingSeparator() + { + static::assertSame(array('Unit', 'Test'), Strings::split(',', 'Unit,Test')); + } + + /** + * @return void + */ + public function testSplitStringTrimsLeadingAndTrailingWhitespace() + { + static::assertSame(array('Unit', 'Test'), Strings::split(',', 'Unit , Test')); + } + + /** + * @return void + */ + public function testSplitStringRemoveEmptyStringValues() + { + static::assertSame(array('Foo'), Strings::split(',', 'Foo,,,')); + } + + /** + * @return void + */ + public function testSplitStringShouldNotRemoveAZeroValue() + { + static::assertSame(array('0', '1', '2'), Strings::split(',', '0,1,2')); + } +} From c024596f8a8c248ec0c173d27ec19d9960d5f21b Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Mon, 4 May 2020 22:30:29 +0200 Subject: [PATCH 002/218] Strings support class: - length: to calculate string length subtracting certain suffixes - split: to split a string trimming and removing empty values --- src/main/php/PHPMD/Support/Strings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Support/Strings.php b/src/main/php/PHPMD/Support/Strings.php index fdc85c0d5..732d1e3ba 100644 --- a/src/main/php/PHPMD/Support/Strings.php +++ b/src/main/php/PHPMD/Support/Strings.php @@ -57,7 +57,7 @@ public static function length($variableName, array $subtractSuffixes = array()) public static function split($separator, $string) { if ($separator === '') { - throw new InvalidArgumentException('Separator can\'t me empty string'); + throw new InvalidArgumentException('Separator can\'t be empty string'); } return array_filter( From e2d66e1829cf53607f79b5f95f83334440f8abd3 Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Mon, 4 May 2020 22:34:05 +0200 Subject: [PATCH 003/218] Update LongVariable rule with getStringProperty and string split/length --- .../php/PHPMD/Rule/Naming/LongVariable.php | 46 ++----------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/LongVariable.php b/src/main/php/PHPMD/Rule/Naming/LongVariable.php index 15b13dc48..3e8f99a5e 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/LongVariable.php @@ -22,6 +22,7 @@ use PHPMD\Rule\ClassAware; use PHPMD\Rule\FunctionAware; use PHPMD\Rule\MethodAware; +use PHPMD\Support\Strings; /** * This rule class will detect variables, parameters and properties with really @@ -105,7 +106,7 @@ protected function checkNodeImage(AbstractNode $node) protected function checkMaximumLength(AbstractNode $node) { $threshold = $this->getIntProperty('maximum'); - if ($threshold >= $this->getStringLength($node->getImage(), $this->getSubtractSuffixList()) - 1) { + if ($threshold >= Strings::length($node->getImage(), $this->getSubtractSuffixList()) - 1) { return; } if ($this->isNameAllowedInContext($node)) { @@ -126,29 +127,6 @@ private function isNameAllowedInContext(AbstractNode $node) return $this->isChildOf($node, 'MemberPrimaryPrefix'); } - /** - * Returns the length of the variable name, excluding at most one suffix. - * - * @param string $variableName Variable name to calculate the length for. - * @param array $subtractSuffixes Optional list of suffixes to exclude from the calculated length. - * @return int The length of the string, without suffix, if applicable. - */ - private function getStringLength($variableName, array $subtractSuffixes) - { - $variableNameLength = strlen($variableName); - - foreach ($subtractSuffixes as $suffix) { - $suffixLength = strlen($suffix); - if (substr($variableName, -$suffixLength) === $suffix) { - $variableName = substr($variableName, 0, $variableNameLength - $suffixLength); - - return strlen($variableName); - } - } - - return $variableNameLength; - } - /** * Checks if the given node is a direct or indirect child of a node with * the given type. @@ -209,24 +187,10 @@ protected function isNotProcessed(AbstractNode $node) */ private function getSubtractSuffixList() { - if ($this->subtractSuffixes !== null) { - return $this->subtractSuffixes; + if ($this->subtractSuffixes === null) { + $this->subtractSuffixes = Strings::split(',', $this->getStringProperty('subtract-suffixes', '')); } - try { - $suffixes = $this->getStringProperty('subtract-suffixes'); - } catch (\OutOfBoundsException $e) { - return $this->subtractSuffixes = array(); - } - - return $this->subtractSuffixes = array_filter( - array_map( - 'trim', - explode(',', $suffixes) - ), - function ($value) { - return $value !== ''; - } - ); + return $this->subtractSuffixes; } } From b6ef2af347a12c8524f1ce8e52d69c549f9ebb9d Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Mon, 4 May 2020 23:13:55 +0200 Subject: [PATCH 004/218] LongVariable Rule + Tests --- .../php/PHPMD/Rule/Naming/LongClassName.php | 68 +++++++++ .../PHPMD/Rule/Naming/LongClassNameTest.php | 132 ++++++++++++++++++ ...stRuleAppliesToClassNameAboveThreshold.php | 24 ++++ ...ngthWithSuffixSubtractedAboveThreshold.php | 24 ++++ ...ClassNameLengthWithoutSuffixSubtracted.php | 24 ++++ ...leAppliesToInterfaceNameAboveThreshold.php | 24 ++++ ...uleNotAppliesToClassNameBelowThreshold.php | 24 ++++ ...ngthWithSuffixSubtractedBelowThreshold.php | 24 ++++ ...otAppliesToInterfaceNameBelowThreshold.php | 24 ++++ 9 files changed, 368 insertions(+) create mode 100644 src/main/php/PHPMD/Rule/Naming/LongClassName.php create mode 100644 src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php create mode 100644 src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameAboveThreshold.php create mode 100644 src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameLengthWithSuffixSubtractedAboveThreshold.php create mode 100644 src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameLengthWithoutSuffixSubtracted.php create mode 100644 src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToInterfaceNameAboveThreshold.php create mode 100644 src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToClassNameBelowThreshold.php create mode 100644 src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToClassNameLengthWithSuffixSubtractedBelowThreshold.php create mode 100644 src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToInterfaceNameBelowThreshold.php diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php new file mode 100644 index 000000000..f23018d08 --- /dev/null +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -0,0 +1,68 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +namespace PHPMD\Rule\Naming; + +use PHPMD\AbstractNode; +use PHPMD\AbstractRule; +use PHPMD\Rule\ClassAware; +use PHPMD\Rule\InterfaceAware; +use PHPMD\Support\Strings; + +/** + * This rule class will check if a class name doesn't exceed the configured length excluding + * certain configured suffixes. + */ +class LongClassName extends AbstractRule implements ClassAware, InterfaceAware +{ + /** + * Temporary cache of configured suffixes to subtract + * + * @var string[]|null + */ + private $subtractSuffixes; + + /** + * This method checks if a class name exceeds the configured maximum length + * and emits a rule violation. + * + * @param \PHPMD\AbstractNode $node + * @return void + */ + public function apply(AbstractNode $node) + { + $threshold = $this->getIntProperty('maximum'); + $length = Strings::length($node->getName(), $this->getSubtractSuffixList()); + if ($length >= $threshold) { + $this->addViolation($node, array($node->getName(), $threshold)); + } + } + + /** + * Gets array of suffixes from property + * + * @return string[] + */ + private function getSubtractSuffixList() + { + if ($this->subtractSuffixes === null) { + $this->subtractSuffixes = Strings::split(',', $this->getStringProperty('subtract-suffixes', '')); + } + + return $this->subtractSuffixes; + } +} diff --git a/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php new file mode 100644 index 000000000..85367eafd --- /dev/null +++ b/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php @@ -0,0 +1,132 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +namespace PHPMD\Rule\Naming; + +use PHPMD\AbstractTest; + +/** + * Test case for long class names. + * + * @covers PHPMD\Rule\Naming\LongClassName + */ +class LongClassNameTest extends AbstractTest +{ + /** + * Class name length: 43 + * Threshold: 44 + * + * @return void + */ + public function testRuleNotAppliesToClassNameBelowThreshold() + { + $rule = new LongClassName(); + $rule->addProperty('maximum', 44); + $rule->setReport($this->getReportWithNoViolation()); + $rule->apply($this->getClass()); + } + + /** + * Class name length: 40 + * Threshold: 40 + * + * @return void + */ + public function testRuleAppliesToClassNameAboveThreshold() + { + $rule = new LongClassName(); + $rule->addProperty('maximum', 40); + $rule->setReport($this->getReportWithOneViolation()); + $rule->apply($this->getClass()); + } + + /** + * Interface name length: 47 + * Threshold: 48 + * + * @return void + */ + public function testRuleNotAppliesToInterfaceNameBelowThreshold() + { + $rule = new LongClassName(); + $rule->addProperty('maximum', 48); + $rule->setReport($this->getReportWithNoViolation()); + $rule->apply($this->getInterface()); + } + + /** + * Interface name length: 44 + * Threshold: 44 + * + * @return void + */ + public function testRuleAppliesToInterfaceNameAboveThreshold() + { + $rule = new LongClassName(); + $rule->addProperty('maximum', 44); + $rule->setReport($this->getReportWithOneViolation()); + $rule->apply($this->getInterface()); + } + + /** + * Class name length: 69 + * Suffix length: 9 + * Threshold: 61 + * + * @return void + */ + public function testRuleNotAppliesToClassNameLengthWithSuffixSubtractedBelowThreshold() + { + $rule = new LongClassName(); + $rule->addProperty('maximum', 61); + $rule->addProperty('subtract-suffixes', 'Threshold'); + $rule->setReport($this->getReportWithNoViolation()); + $rule->apply($this->getClass()); + } + + /** + * Class name length: 66 + * Suffix length: 9 + * Threshold: 57 + * + * @return void + */ + public function testRuleAppliesToClassNameLengthWithSuffixSubtractedAboveThreshold() + { + $rule = new LongClassName(); + $rule->addProperty('maximum', 57); + $rule->addProperty('subtract-suffixes', 'Threshold'); + $rule->setReport($this->getReportWithOneViolation()); + $rule->apply($this->getClass()); + } + + /** + * Class name length: 55 + * Suffix length: 9 + * Threshold: 55 + * + * @return void + */ + public function testRuleAppliesToClassNameLengthWithoutSuffixSubtracted() + { + $rule = new LongClassName(); + $rule->addProperty('maximum', 55); + $rule->addProperty('subtract-suffixes', 'Threshold'); + $rule->setReport($this->getReportWithOneViolation()); + $rule->apply($this->getClass()); + } +} diff --git a/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameAboveThreshold.php b/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameAboveThreshold.php new file mode 100644 index 000000000..4b24b965d --- /dev/null +++ b/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameAboveThreshold.php @@ -0,0 +1,24 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +/** + * Class name length: 40 + */ +class testRuleAppliesToClassNameAboveThreshold +{ + +} diff --git a/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameLengthWithSuffixSubtractedAboveThreshold.php b/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameLengthWithSuffixSubtractedAboveThreshold.php new file mode 100644 index 000000000..0bb826ba6 --- /dev/null +++ b/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameLengthWithSuffixSubtractedAboveThreshold.php @@ -0,0 +1,24 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +/** + * Class name length: 66 + */ +class testRuleAppliesToClassNameLengthWithSuffixSubtractedAboveThreshold +{ + +} diff --git a/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameLengthWithoutSuffixSubtracted.php b/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameLengthWithoutSuffixSubtracted.php new file mode 100644 index 000000000..76a90d584 --- /dev/null +++ b/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToClassNameLengthWithoutSuffixSubtracted.php @@ -0,0 +1,24 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +/** + * Class name length: 55 + */ +class testRuleAppliesToClassNameLengthWithoutSuffixSubtracted +{ + +} diff --git a/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToInterfaceNameAboveThreshold.php b/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToInterfaceNameAboveThreshold.php new file mode 100644 index 000000000..28f9cd0b4 --- /dev/null +++ b/src/test/resources/files/Rule/Naming/LongClassName/testRuleAppliesToInterfaceNameAboveThreshold.php @@ -0,0 +1,24 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +/** + * Interface name length: 44 + */ +interface testRuleAppliesToInterfaceNameAboveThreshold +{ + +} diff --git a/src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToClassNameBelowThreshold.php b/src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToClassNameBelowThreshold.php new file mode 100644 index 000000000..1c8e1ece4 --- /dev/null +++ b/src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToClassNameBelowThreshold.php @@ -0,0 +1,24 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +/** + * Class name length: 43 + */ +class testRuleNotAppliesToClassNameBelowThreshold +{ + +} diff --git a/src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToClassNameLengthWithSuffixSubtractedBelowThreshold.php b/src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToClassNameLengthWithSuffixSubtractedBelowThreshold.php new file mode 100644 index 000000000..acb6838aa --- /dev/null +++ b/src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToClassNameLengthWithSuffixSubtractedBelowThreshold.php @@ -0,0 +1,24 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +/** + * Class name length: 69 + */ +class testRuleNotAppliesToClassNameLengthWithSuffixSubtractedBelowThreshold +{ + +} diff --git a/src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToInterfaceNameBelowThreshold.php b/src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToInterfaceNameBelowThreshold.php new file mode 100644 index 000000000..ec2d082fb --- /dev/null +++ b/src/test/resources/files/Rule/Naming/LongClassName/testRuleNotAppliesToInterfaceNameBelowThreshold.php @@ -0,0 +1,24 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +/** + * Class name length: 47 + */ +interface testRuleNotAppliesToInterfaceNameBelowThreshold +{ + +} From 00d7cbde9857863ed57d0ab975dc2852ad05eb08 Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Mon, 4 May 2020 23:27:25 +0200 Subject: [PATCH 005/218] Updated documentation --- src/bin/phpmd | 1 + src/main/resources/rulesets/naming.xml | 26 ++++++++++++++++++++++++++ src/site/rst/rules/index.rst | 1 + 3 files changed, 28 insertions(+) diff --git a/src/bin/phpmd b/src/bin/phpmd index 1a49de709..18e406e3e 100755 --- a/src/bin/phpmd +++ b/src/bin/phpmd @@ -112,6 +112,7 @@ class_alias('PHPMD\\Rule\\Design\\WeightedMethodCount', 'PHP_PMD_Rule_Design_Wei class_alias('PHPMD\\Rule\\Naming\\BooleanGetMethodName', 'PHP_PMD_Rule_Naming_BooleanGetMethodName'); class_alias('PHPMD\\Rule\\Naming\\ConstantNamingConventions', 'PHP_PMD_Rule_Naming_ConstantNamingConventions'); class_alias('PHPMD\\Rule\\Naming\\ConstructorWithNameAsEnclosingClass', 'PHP_PMD_Rule_Naming_ConstructorWithNameAsEnclosingClass'); +class_alias('PHPMD\\Rule\\Naming\\LongClassName', 'PHP_PMD_Rule_Naming_LongClassName'); class_alias('PHPMD\\Rule\\Naming\\LongVariable', 'PHP_PMD_Rule_Naming_LongVariable'); class_alias('PHPMD\\Rule\\Naming\\ShortMethodName', 'PHP_PMD_Rule_Naming_ShortMethodName'); class_alias('PHPMD\\Rule\\Naming\\ShortVariable', 'PHP_PMD_Rule_Naming_ShortVariable'); diff --git a/src/main/resources/rulesets/naming.xml b/src/main/resources/rulesets/naming.xml index fb4c245c2..53b5e2e09 100644 --- a/src/main/resources/rulesets/naming.xml +++ b/src/main/resources/rulesets/naming.xml @@ -8,6 +8,32 @@ The Naming Ruleset contains a collection of rules about names - too long, too short, and so forth. + + + Detects when classes or interfaces are declared with excessively long names. + + 3 + + + + + + + + + `_: Detects when classes or interfaces are declared with excessively long names. - `ShortVariable `_: Detects when a field, local, or parameter has a very short name. - `LongVariable `_: Detects when a field, formal or local variable is declared with a long name. - `ShortMethodName `_: Detects when very short method names are used. From 205973b67ad5ae62f0f79a2eaf144fc593792701 Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Mon, 4 May 2020 23:55:50 +0200 Subject: [PATCH 006/218] ShortClassName rule + testcases --- .../php/PHPMD/Rule/Naming/ShortClassName.php | 74 ++++++++++++ .../PHPMD/Rule/Naming/ShortClassNameTest.php | 114 ++++++++++++++++++ ...ClassNameAboveThresholdNotInExceptions.php | 21 ++++ ...stRuleAppliesToClassNameBelowThreshold.php | 21 ++++ ...leAppliesToInterfaceNameBelowThreshold.php | 21 ++++ ...uleNotAppliesToClassNameAboveThreshold.php | 21 ++++ ...sToClassNameAboveThresholdInExceptions.php | 21 ++++ ...otAppliesToInterfaceNameAboveThreshold.php | 21 ++++ 8 files changed, 314 insertions(+) create mode 100644 src/main/php/PHPMD/Rule/Naming/ShortClassName.php create mode 100644 src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php create mode 100644 src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameAboveThresholdNotInExceptions.php create mode 100644 src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameBelowThreshold.php create mode 100644 src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToInterfaceNameBelowThreshold.php create mode 100644 src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThreshold.php create mode 100644 src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThresholdInExceptions.php create mode 100644 src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToInterfaceNameAboveThreshold.php diff --git a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php new file mode 100644 index 000000000..0adf0a50f --- /dev/null +++ b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php @@ -0,0 +1,74 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +namespace PHPMD\Rule\Naming; + +use PHPMD\AbstractNode; +use PHPMD\AbstractRule; +use PHPMD\Rule\ClassAware; +use PHPMD\Rule\InterfaceAware; +use PHPMD\Support\Strings; + +/** + * This rule class will detect classes and interfaces with short names. + */ +class ShortClassName extends AbstractRule implements ClassAware, InterfaceAware +{ + /** + * Temporary cache of configured exceptions. Have name as key + * + * @var array|null + */ + private $exceptions; + + /** + * This method checks if a class or interface name is below the minimum configured length + * and emits a rule violation. + * + * @param \PHPMD\AbstractNode $node + * @return void + */ + public function apply(AbstractNode $node) + { + $threshold = $this->getIntProperty('minimum'); + + if ($threshold <= strlen($node->getName()) - 1) { + return; + } + + $exceptions = $this->getExceptionsList(); + if (isset($exceptions[$node->getName()])) { + return; + } + + $this->addViolation($node, array($node->getName(), $threshold)); + } + + /** + * Gets array of exceptions from property + * + * @return array + */ + private function getExceptionsList() + { + if ($this->exceptions === null) { + $this->exceptions = array_flip(Strings::split(',', $this->getStringProperty('exceptions', ''))); + } + + return $this->exceptions; + } +} diff --git a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php new file mode 100644 index 000000000..f3346c03f --- /dev/null +++ b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php @@ -0,0 +1,114 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +namespace PHPMD\Rule\Naming; + +use PHPMD\AbstractTest; + +/** + * Test case for short class names. + * + * @covers PHPMD\Rule\Naming\ShortClassName + */ +class ShortClassNameTest extends AbstractTest +{ + /** + * Class name length: 43 + * Threshold: 42 + * + * @return void + */ + public function testRuleNotAppliesToClassNameAboveThreshold() + { + $rule = new ShortClassName(); + $rule->addProperty('minimum', 42); + $rule->setReport($this->getReportWithNoViolation()); + $rule->apply($this->getClass()); + } + + /** + * Class name length: 40 + * Threshold: 40 + * + * @return void + */ + public function testRuleAppliesToClassNameBelowThreshold() + { + $rule = new ShortClassName(); + $rule->addProperty('minimum', 40); + $rule->setReport($this->getReportWithOneViolation()); + $rule->apply($this->getClass()); + } + + /** + * Interface name length: 47 + * Threshold: 46 + * + * @return void + */ + public function testRuleNotAppliesToInterfaceNameAboveThreshold() + { + $rule = new ShortClassName(); + $rule->addProperty('minimum', 46); + $rule->setReport($this->getReportWithNoViolation()); + $rule->apply($this->getInterface()); + } + + /** + * Interface name length: 44 + * Threshold: 44 + * + * @return void + */ + public function testRuleAppliesToInterfaceNameBelowThreshold() + { + $rule = new ShortClassName(); + $rule->addProperty('minimum', 44); + $rule->setReport($this->getReportWithOneViolation()); + $rule->apply($this->getInterface()); + } + + /** + * Class name length: 55 + * Threshold: 60 + * + * @return void + */ + public function testRuleNotAppliesToClassNameAboveThresholdInExceptions() + { + $rule = new ShortClassName(); + $rule->addProperty('minimum', 60); + $rule->addProperty('exceptions', 'testRuleNotAppliesToClassNameAboveThresholdInExceptions'); + $rule->setReport($this->getReportWithNoViolation()); + $rule->apply($this->getClass()); + } + + /** + * Class name length: 55 + * Threshold: 55 + * + * @return void + */ + public function testRuleAppliesToClassNameAboveThresholdNotInExceptions() + { + $rule = new ShortClassName(); + $rule->addProperty('minimum', 55); + $rule->addProperty('exceptions', 'RandomClassName'); + $rule->setReport($this->getReportWithOneViolation()); + $rule->apply($this->getClass()); + } +} diff --git a/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameAboveThresholdNotInExceptions.php b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameAboveThresholdNotInExceptions.php new file mode 100644 index 000000000..f188cc7ab --- /dev/null +++ b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameAboveThresholdNotInExceptions.php @@ -0,0 +1,21 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleAppliesToClassNameAboveThresholdNotInExceptions +{ + +} diff --git a/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameBelowThreshold.php b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameBelowThreshold.php new file mode 100644 index 000000000..8d4476941 --- /dev/null +++ b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameBelowThreshold.php @@ -0,0 +1,21 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleAppliesToClassNameBelowThreshold +{ + +} diff --git a/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToInterfaceNameBelowThreshold.php b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToInterfaceNameBelowThreshold.php new file mode 100644 index 000000000..6b4dc7b09 --- /dev/null +++ b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToInterfaceNameBelowThreshold.php @@ -0,0 +1,21 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +interface testRuleAppliesToInterfaceNameBelowThreshold +{ + +} diff --git a/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThreshold.php b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThreshold.php new file mode 100644 index 000000000..1b5634ac7 --- /dev/null +++ b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThreshold.php @@ -0,0 +1,21 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleNotAppliesToClassNameAboveThreshold +{ + +} diff --git a/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThresholdInExceptions.php b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThresholdInExceptions.php new file mode 100644 index 000000000..60ee25214 --- /dev/null +++ b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThresholdInExceptions.php @@ -0,0 +1,21 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleNotAppliesToClassNameAboveThresholdInExceptions +{ + +} diff --git a/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToInterfaceNameAboveThreshold.php b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToInterfaceNameAboveThreshold.php new file mode 100644 index 000000000..8e8483f71 --- /dev/null +++ b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToInterfaceNameAboveThreshold.php @@ -0,0 +1,21 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +interface testRuleNotAppliesToInterfaceNameAboveThreshold +{ + +} From 0a180dd5b642f0479c16702f1f7f315dddd71b91 Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Tue, 5 May 2020 00:03:13 +0200 Subject: [PATCH 007/218] Updated documentation for the short class name rule --- src/bin/phpmd | 1 + src/main/resources/rulesets/naming.xml | 26 ++++++++++++++++++++++++++ src/site/rst/rules/index.rst | 1 + 3 files changed, 28 insertions(+) diff --git a/src/bin/phpmd b/src/bin/phpmd index 18e406e3e..da6b362d6 100755 --- a/src/bin/phpmd +++ b/src/bin/phpmd @@ -113,6 +113,7 @@ class_alias('PHPMD\\Rule\\Naming\\BooleanGetMethodName', 'PHP_PMD_Rule_Naming_Bo class_alias('PHPMD\\Rule\\Naming\\ConstantNamingConventions', 'PHP_PMD_Rule_Naming_ConstantNamingConventions'); class_alias('PHPMD\\Rule\\Naming\\ConstructorWithNameAsEnclosingClass', 'PHP_PMD_Rule_Naming_ConstructorWithNameAsEnclosingClass'); class_alias('PHPMD\\Rule\\Naming\\LongClassName', 'PHP_PMD_Rule_Naming_LongClassName'); +class_alias('PHPMD\\Rule\\Naming\\ShortClassName', 'PHP_PMD_Rule_Naming_ShortClassName'); class_alias('PHPMD\\Rule\\Naming\\LongVariable', 'PHP_PMD_Rule_Naming_LongVariable'); class_alias('PHPMD\\Rule\\Naming\\ShortMethodName', 'PHP_PMD_Rule_Naming_ShortMethodName'); class_alias('PHPMD\\Rule\\Naming\\ShortVariable', 'PHP_PMD_Rule_Naming_ShortVariable'); diff --git a/src/main/resources/rulesets/naming.xml b/src/main/resources/rulesets/naming.xml index 53b5e2e09..d5ceaf23d 100644 --- a/src/main/resources/rulesets/naming.xml +++ b/src/main/resources/rulesets/naming.xml @@ -29,6 +29,32 @@ class AReallyLongClassName { interface AReallyLongInterfaceName { +} +]]> + + + + + + Detects when classes or interfaces have a very short name. + + 3 + + + + + + diff --git a/src/site/rst/rules/index.rst b/src/site/rst/rules/index.rst index 469cde50c..2af522c53 100644 --- a/src/site/rst/rules/index.rst +++ b/src/site/rst/rules/index.rst @@ -65,6 +65,7 @@ Naming Rules ============ - `LongClassName `_: Detects when classes or interfaces are declared with excessively long names. +- `ShortClassName `_: Detects when classes or interfaces have a very short name. - `ShortVariable `_: Detects when a field, local, or parameter has a very short name. - `LongVariable `_: Detects when a field, formal or local variable is declared with a long name. - `ShortMethodName `_: Detects when very short method names are used. From ad3ced978adc51ced014854d62e769d76b4d2d22 Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Tue, 5 May 2020 10:50:00 +0200 Subject: [PATCH 008/218] Added example to exceptions list --- src/main/resources/rulesets/naming.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/rulesets/naming.xml b/src/main/resources/rulesets/naming.xml index d5ceaf23d..84ae66611 100644 --- a/src/main/resources/rulesets/naming.xml +++ b/src/main/resources/rulesets/naming.xml @@ -45,7 +45,7 @@ interface AReallyLongInterfaceName { 3 - + Date: Tue, 5 May 2020 10:52:42 +0200 Subject: [PATCH 009/218] Updated docblock of StringsTest --- src/test/php/PHPMD/Support/StringsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/Support/StringsTest.php b/src/test/php/PHPMD/Support/StringsTest.php index e92cca064..0e817ecbf 100644 --- a/src/test/php/PHPMD/Support/StringsTest.php +++ b/src/test/php/PHPMD/Support/StringsTest.php @@ -20,7 +20,7 @@ use PHPMD\AbstractTest; /** - * Test case for the {@link \PHPMD\Support\Strings} class. + * Test case for the Strings utility class. * * @covers \PHPMD\Support\Strings */ From ac080200c630a5424219af6f8d163c034e536617 Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Tue, 5 May 2020 11:07:14 +0200 Subject: [PATCH 010/218] PHPUnit 4.8.3 expectException fix. --- src/test/php/PHPMD/Support/StringsTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/Support/StringsTest.php b/src/test/php/PHPMD/Support/StringsTest.php index 0e817ecbf..32c25dc79 100644 --- a/src/test/php/PHPMD/Support/StringsTest.php +++ b/src/test/php/PHPMD/Support/StringsTest.php @@ -75,11 +75,12 @@ public function testLengthStringWithPrefixMatchShouldNotSubtract() } /** + * @expectedException \InvalidArgumentException + * * @return void */ public function testSplitEmptySeparatorThrowsException() { - $this->expectException('\InvalidArgumentException'); Strings::split('', 'UnitTest'); } From 083628eb2f6c1025b351fd23404e230666bb5639 Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Tue, 5 May 2020 21:36:35 +0200 Subject: [PATCH 011/218] Fixed threshold calculation. --- .../php/PHPMD/Rule/Naming/LongClassName.php | 2 +- .../php/PHPMD/Rule/Naming/ShortClassName.php | 2 +- src/main/resources/rulesets/naming.xml | 2 +- .../PHPMD/Rule/Naming/LongClassNameTest.php | 26 +++++++++---------- .../PHPMD/Rule/Naming/ShortClassNameTest.php | 24 ++++++++--------- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php index f23018d08..9e6e0933b 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -47,7 +47,7 @@ public function apply(AbstractNode $node) { $threshold = $this->getIntProperty('maximum'); $length = Strings::length($node->getName(), $this->getSubtractSuffixList()); - if ($length >= $threshold) { + if ($length > $threshold) { $this->addViolation($node, array($node->getName(), $threshold)); } } diff --git a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php index 0adf0a50f..884af95ef 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php @@ -46,7 +46,7 @@ public function apply(AbstractNode $node) { $threshold = $this->getIntProperty('minimum'); - if ($threshold <= strlen($node->getName()) - 1) { + if ($threshold <= strlen($node->getName())) { return; } diff --git a/src/main/resources/rulesets/naming.xml b/src/main/resources/rulesets/naming.xml index 84ae66611..cc0eca106 100644 --- a/src/main/resources/rulesets/naming.xml +++ b/src/main/resources/rulesets/naming.xml @@ -44,7 +44,7 @@ interface AReallyLongInterfaceName { 3 - + diff --git a/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php index 85367eafd..ddf59bc69 100644 --- a/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php @@ -28,7 +28,7 @@ class LongClassNameTest extends AbstractTest { /** * Class name length: 43 - * Threshold: 44 + * Threshold: 43 * * @return void */ @@ -42,42 +42,42 @@ public function testRuleNotAppliesToClassNameBelowThreshold() /** * Class name length: 40 - * Threshold: 40 + * Threshold: 39 * * @return void */ public function testRuleAppliesToClassNameAboveThreshold() { $rule = new LongClassName(); - $rule->addProperty('maximum', 40); + $rule->addProperty('maximum', 39); $rule->setReport($this->getReportWithOneViolation()); $rule->apply($this->getClass()); } /** * Interface name length: 47 - * Threshold: 48 + * Threshold: 47 * * @return void */ public function testRuleNotAppliesToInterfaceNameBelowThreshold() { $rule = new LongClassName(); - $rule->addProperty('maximum', 48); + $rule->addProperty('maximum', 47); $rule->setReport($this->getReportWithNoViolation()); $rule->apply($this->getInterface()); } /** * Interface name length: 44 - * Threshold: 44 + * Threshold: 43 * * @return void */ public function testRuleAppliesToInterfaceNameAboveThreshold() { $rule = new LongClassName(); - $rule->addProperty('maximum', 44); + $rule->addProperty('maximum', 43); $rule->setReport($this->getReportWithOneViolation()); $rule->apply($this->getInterface()); } @@ -85,14 +85,14 @@ public function testRuleAppliesToInterfaceNameAboveThreshold() /** * Class name length: 69 * Suffix length: 9 - * Threshold: 61 + * Threshold: 60 * * @return void */ public function testRuleNotAppliesToClassNameLengthWithSuffixSubtractedBelowThreshold() { $rule = new LongClassName(); - $rule->addProperty('maximum', 61); + $rule->addProperty('maximum', 60); $rule->addProperty('subtract-suffixes', 'Threshold'); $rule->setReport($this->getReportWithNoViolation()); $rule->apply($this->getClass()); @@ -101,14 +101,14 @@ public function testRuleNotAppliesToClassNameLengthWithSuffixSubtractedBelowThre /** * Class name length: 66 * Suffix length: 9 - * Threshold: 57 + * Threshold: 56 * * @return void */ public function testRuleAppliesToClassNameLengthWithSuffixSubtractedAboveThreshold() { $rule = new LongClassName(); - $rule->addProperty('maximum', 57); + $rule->addProperty('maximum', 56); $rule->addProperty('subtract-suffixes', 'Threshold'); $rule->setReport($this->getReportWithOneViolation()); $rule->apply($this->getClass()); @@ -117,14 +117,14 @@ public function testRuleAppliesToClassNameLengthWithSuffixSubtractedAboveThresho /** * Class name length: 55 * Suffix length: 9 - * Threshold: 55 + * Threshold: 54 * * @return void */ public function testRuleAppliesToClassNameLengthWithoutSuffixSubtracted() { $rule = new LongClassName(); - $rule->addProperty('maximum', 55); + $rule->addProperty('maximum', 54); $rule->addProperty('subtract-suffixes', 'Threshold'); $rule->setReport($this->getReportWithOneViolation()); $rule->apply($this->getClass()); diff --git a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php index f3346c03f..17d5d08fe 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php @@ -28,70 +28,70 @@ class ShortClassNameTest extends AbstractTest { /** * Class name length: 43 - * Threshold: 42 + * Threshold: 43 * * @return void */ public function testRuleNotAppliesToClassNameAboveThreshold() { $rule = new ShortClassName(); - $rule->addProperty('minimum', 42); + $rule->addProperty('minimum', 43); $rule->setReport($this->getReportWithNoViolation()); $rule->apply($this->getClass()); } /** * Class name length: 40 - * Threshold: 40 + * Threshold: 41 * * @return void */ public function testRuleAppliesToClassNameBelowThreshold() { $rule = new ShortClassName(); - $rule->addProperty('minimum', 40); + $rule->addProperty('minimum', 41); $rule->setReport($this->getReportWithOneViolation()); $rule->apply($this->getClass()); } /** * Interface name length: 47 - * Threshold: 46 + * Threshold: 47 * * @return void */ public function testRuleNotAppliesToInterfaceNameAboveThreshold() { $rule = new ShortClassName(); - $rule->addProperty('minimum', 46); + $rule->addProperty('minimum', 47); $rule->setReport($this->getReportWithNoViolation()); $rule->apply($this->getInterface()); } /** * Interface name length: 44 - * Threshold: 44 + * Threshold: 45 * * @return void */ public function testRuleAppliesToInterfaceNameBelowThreshold() { $rule = new ShortClassName(); - $rule->addProperty('minimum', 44); + $rule->addProperty('minimum', 45); $rule->setReport($this->getReportWithOneViolation()); $rule->apply($this->getInterface()); } /** * Class name length: 55 - * Threshold: 60 + * Threshold: 61 * * @return void */ public function testRuleNotAppliesToClassNameAboveThresholdInExceptions() { $rule = new ShortClassName(); - $rule->addProperty('minimum', 60); + $rule->addProperty('minimum', 61); $rule->addProperty('exceptions', 'testRuleNotAppliesToClassNameAboveThresholdInExceptions'); $rule->setReport($this->getReportWithNoViolation()); $rule->apply($this->getClass()); @@ -99,14 +99,14 @@ public function testRuleNotAppliesToClassNameAboveThresholdInExceptions() /** * Class name length: 55 - * Threshold: 55 + * Threshold: 56 * * @return void */ public function testRuleAppliesToClassNameAboveThresholdNotInExceptions() { $rule = new ShortClassName(); - $rule->addProperty('minimum', 55); + $rule->addProperty('minimum', 56); $rule->addProperty('exceptions', 'RandomClassName'); $rule->setReport($this->getReportWithOneViolation()); $rule->apply($this->getClass()); From 0e56d783edb5af365370c6637c6a8a82f37dcc23 Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Tue, 5 May 2020 22:05:30 +0200 Subject: [PATCH 012/218] Move length calculation inside the if for consistency amongst rules Moved "threshold" to the right side so it's better understandable. Tightened the LongVariable length constraints in the test case. --- src/main/php/PHPMD/Rule/Naming/LongClassName.php | 6 +++--- src/main/php/PHPMD/Rule/Naming/LongVariable.php | 2 +- src/main/php/PHPMD/Rule/Naming/ShortClassName.php | 3 +-- src/test/php/PHPMD/Rule/Naming/LongVariableTest.php | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php index 9e6e0933b..90d676415 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -46,10 +46,10 @@ class LongClassName extends AbstractRule implements ClassAware, InterfaceAware public function apply(AbstractNode $node) { $threshold = $this->getIntProperty('maximum'); - $length = Strings::length($node->getName(), $this->getSubtractSuffixList()); - if ($length > $threshold) { - $this->addViolation($node, array($node->getName(), $threshold)); + if (Strings::length($node->getName(), $this->getSubtractSuffixList()) <= $threshold) { + return; } + $this->addViolation($node, array($node->getName(), $threshold)); } /** diff --git a/src/main/php/PHPMD/Rule/Naming/LongVariable.php b/src/main/php/PHPMD/Rule/Naming/LongVariable.php index 3e8f99a5e..2fc02d6ab 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/LongVariable.php @@ -106,7 +106,7 @@ protected function checkNodeImage(AbstractNode $node) protected function checkMaximumLength(AbstractNode $node) { $threshold = $this->getIntProperty('maximum'); - if ($threshold >= Strings::length($node->getImage(), $this->getSubtractSuffixList()) - 1) { + if (Strings::length($node->getImage(), $this->getSubtractSuffixList()) - 1 <= $threshold) { return; } if ($this->isNameAllowedInContext($node)) { diff --git a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php index 884af95ef..cc3d53e77 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php @@ -45,8 +45,7 @@ class ShortClassName extends AbstractRule implements ClassAware, InterfaceAware public function apply(AbstractNode $node) { $threshold = $this->getIntProperty('minimum'); - - if ($threshold <= strlen($node->getName())) { + if (strlen($node->getName()) >= $threshold) { return; } diff --git a/src/test/php/PHPMD/Rule/Naming/LongVariableTest.php b/src/test/php/PHPMD/Rule/Naming/LongVariableTest.php index c3b5587ce..8f2b339d8 100644 --- a/src/test/php/PHPMD/Rule/Naming/LongVariableTest.php +++ b/src/test/php/PHPMD/Rule/Naming/LongVariableTest.php @@ -34,7 +34,7 @@ class LongVariableTest extends AbstractTest public function testRuleAppliesToLocalVariableInFunctionWithNameLongerThanThreshold() { $rule = new LongVariable(); - $rule->addProperty('maximum', 17); + $rule->addProperty('maximum', 21); $rule->setReport($this->getReportWithOneViolation()); $rule->apply($this->getFunction()); } @@ -47,7 +47,7 @@ public function testRuleAppliesToLocalVariableInFunctionWithNameLongerThanThresh public function testRuleNotAppliesToLocalVariableInFunctionWithNameSmallerThanThreshold() { $rule = new LongVariable(); - $rule->addProperty('maximum', 17); + $rule->addProperty('maximum', 6); $rule->setReport($this->getReportWithNoViolation()); $rule->apply($this->getFunction()); } From 1692729a729b6f4b786b62fc662fe574642701e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 01:06:47 +0200 Subject: [PATCH 013/218] Remove superfluous class aliases As explained here: https://github.com/phpmd/phpmd/pull/768 --- src/bin/phpmd | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/bin/phpmd b/src/bin/phpmd index da6b362d6..1a49de709 100755 --- a/src/bin/phpmd +++ b/src/bin/phpmd @@ -112,8 +112,6 @@ class_alias('PHPMD\\Rule\\Design\\WeightedMethodCount', 'PHP_PMD_Rule_Design_Wei class_alias('PHPMD\\Rule\\Naming\\BooleanGetMethodName', 'PHP_PMD_Rule_Naming_BooleanGetMethodName'); class_alias('PHPMD\\Rule\\Naming\\ConstantNamingConventions', 'PHP_PMD_Rule_Naming_ConstantNamingConventions'); class_alias('PHPMD\\Rule\\Naming\\ConstructorWithNameAsEnclosingClass', 'PHP_PMD_Rule_Naming_ConstructorWithNameAsEnclosingClass'); -class_alias('PHPMD\\Rule\\Naming\\LongClassName', 'PHP_PMD_Rule_Naming_LongClassName'); -class_alias('PHPMD\\Rule\\Naming\\ShortClassName', 'PHP_PMD_Rule_Naming_ShortClassName'); class_alias('PHPMD\\Rule\\Naming\\LongVariable', 'PHP_PMD_Rule_Naming_LongVariable'); class_alias('PHPMD\\Rule\\Naming\\ShortMethodName', 'PHP_PMD_Rule_Naming_ShortMethodName'); class_alias('PHPMD\\Rule\\Naming\\ShortVariable', 'PHP_PMD_Rule_Naming_ShortVariable'); From 8ec7d4211525ce7b608866080b664b3b7afc5dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 01:42:08 +0200 Subject: [PATCH 014/218] Improve doc block wording --- src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php index 17d5d08fe..772ea44fc 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php @@ -20,7 +20,7 @@ use PHPMD\AbstractTest; /** - * Test case for short class names. + * Test case for ShortClassName rule * * @covers PHPMD\Rule\Naming\ShortClassName */ From cf4a9bb493a6a8600f4f77d35b4205f5a5bb7c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 01:42:43 +0200 Subject: [PATCH 015/218] Correct coverage annotation and FQCN --- src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php index 772ea44fc..d76410686 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php @@ -22,7 +22,7 @@ /** * Test case for ShortClassName rule * - * @covers PHPMD\Rule\Naming\ShortClassName + * @coversDefaultClass \PHPMD\Rule\Naming\ShortClassName */ class ShortClassNameTest extends AbstractTest { From a9b4caf03209a1f7a0d17a3ad73a1f7a189386b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 01:44:05 +0200 Subject: [PATCH 016/218] Improve test case doc blocks --- .../PHPMD/Rule/Naming/ShortClassNameTest.php | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php index d76410686..77a05a9b1 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php @@ -27,8 +27,7 @@ class ShortClassNameTest extends AbstractTest { /** - * Class name length: 43 - * Threshold: 43 + * Tests that rule does not apply to class name length (43) above threshold (43) * * @return void */ @@ -41,8 +40,7 @@ public function testRuleNotAppliesToClassNameAboveThreshold() } /** - * Class name length: 40 - * Threshold: 41 + * Tests that rule applies to class name length (40) below threshold (41) * * @return void */ @@ -55,8 +53,7 @@ public function testRuleAppliesToClassNameBelowThreshold() } /** - * Interface name length: 47 - * Threshold: 47 + * Tests that rule does not apply to interface name length (47) above threshold (47) * * @return void */ @@ -69,8 +66,7 @@ public function testRuleNotAppliesToInterfaceNameAboveThreshold() } /** - * Interface name length: 44 - * Threshold: 45 + * Tests that rule applies for interface name length (44) below threshold (45) * * @return void */ @@ -83,8 +79,7 @@ public function testRuleAppliesToInterfaceNameBelowThreshold() } /** - * Class name length: 55 - * Threshold: 61 + * Tests that rule does not apply for class name length (55) below threshold (61) when set in exceptions * * @return void */ @@ -98,8 +93,7 @@ public function testRuleNotAppliesToClassNameAboveThresholdInExceptions() } /** - * Class name length: 55 - * Threshold: 56 + * Tests that rule applies to class name length (55) below threshold (56) when not set in exceptions * * @return void */ From bb6c341a4052dd72ae45ff4ed276a96ac4a8752d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 01:45:46 +0200 Subject: [PATCH 017/218] Correct test case name & test file --- src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php | 4 ++-- ...stRuleNotAppliesToClassNameBelowThresholdInExceptions.php} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/test/resources/files/Rule/Naming/ShortClassName/{testRuleNotAppliesToClassNameAboveThresholdInExceptions.php => testRuleNotAppliesToClassNameBelowThresholdInExceptions.php} (89%) diff --git a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php index 77a05a9b1..00671b985 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php @@ -83,11 +83,11 @@ public function testRuleAppliesToInterfaceNameBelowThreshold() * * @return void */ - public function testRuleNotAppliesToClassNameAboveThresholdInExceptions() + public function testRuleNotAppliesToClassNameBelowThresholdInExceptions() { $rule = new ShortClassName(); $rule->addProperty('minimum', 61); - $rule->addProperty('exceptions', 'testRuleNotAppliesToClassNameAboveThresholdInExceptions'); + $rule->addProperty('exceptions', 'testRuleNotAppliesToClassNameBelowThresholdInExceptions'); $rule->setReport($this->getReportWithNoViolation()); $rule->apply($this->getClass()); } diff --git a/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThresholdInExceptions.php b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameBelowThresholdInExceptions.php similarity index 89% rename from src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThresholdInExceptions.php rename to src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameBelowThresholdInExceptions.php index 60ee25214..67d2cc3f6 100644 --- a/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameAboveThresholdInExceptions.php +++ b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleNotAppliesToClassNameBelowThresholdInExceptions.php @@ -15,7 +15,7 @@ * @link http://phpmd.org/ */ -class testRuleNotAppliesToClassNameAboveThresholdInExceptions +class testRuleNotAppliesToClassNameBelowThresholdInExceptions { } From a5b6b4324420de357e36c65a3aaf421ca3cad3fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 01:46:58 +0200 Subject: [PATCH 018/218] Correct test case name & test file --- src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php | 2 +- ...testRuleAppliesToClassNameBelowThresholdNotInExceptions.php} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/test/resources/files/Rule/Naming/ShortClassName/{testRuleAppliesToClassNameAboveThresholdNotInExceptions.php => testRuleAppliesToClassNameBelowThresholdNotInExceptions.php} (89%) diff --git a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php index 00671b985..1e6829f61 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php @@ -97,7 +97,7 @@ public function testRuleNotAppliesToClassNameBelowThresholdInExceptions() * * @return void */ - public function testRuleAppliesToClassNameAboveThresholdNotInExceptions() + public function testRuleAppliesToClassNameBelowThresholdNotInExceptions() { $rule = new ShortClassName(); $rule->addProperty('minimum', 56); diff --git a/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameAboveThresholdNotInExceptions.php b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameBelowThresholdNotInExceptions.php similarity index 89% rename from src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameAboveThresholdNotInExceptions.php rename to src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameBelowThresholdNotInExceptions.php index f188cc7ab..d6146248b 100644 --- a/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameAboveThresholdNotInExceptions.php +++ b/src/test/resources/files/Rule/Naming/ShortClassName/testRuleAppliesToClassNameBelowThresholdNotInExceptions.php @@ -15,7 +15,7 @@ * @link http://phpmd.org/ */ -class testRuleAppliesToClassNameAboveThresholdNotInExceptions +class testRuleAppliesToClassNameBelowThresholdNotInExceptions { } From 43d0d5d5a231a99ecff38c76307351e7496075ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 01:57:13 +0200 Subject: [PATCH 019/218] Rename Strings::length() to lengthWithoutSuffixes() - Make list of suffixes to exclude from the calculated length parameter mandatory - Update doc block - Talk about strings, not variables in particular --- src/main/php/PHPMD/Rule/Naming/LongClassName.php | 2 +- src/main/php/PHPMD/Rule/Naming/LongVariable.php | 2 +- src/main/php/PHPMD/Support/Strings.php | 16 ++++++++-------- src/test/php/PHPMD/Support/StringsTest.php | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php index 90d676415..c3b4cff15 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -46,7 +46,7 @@ class LongClassName extends AbstractRule implements ClassAware, InterfaceAware public function apply(AbstractNode $node) { $threshold = $this->getIntProperty('maximum'); - if (Strings::length($node->getName(), $this->getSubtractSuffixList()) <= $threshold) { + if (Strings::lengthWithoutSuffixes($node->getName(), $this->getSubtractSuffixList()) <= $threshold) { return; } $this->addViolation($node, array($node->getName(), $threshold)); diff --git a/src/main/php/PHPMD/Rule/Naming/LongVariable.php b/src/main/php/PHPMD/Rule/Naming/LongVariable.php index 2fc02d6ab..fd8ace630 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/LongVariable.php @@ -106,7 +106,7 @@ protected function checkNodeImage(AbstractNode $node) protected function checkMaximumLength(AbstractNode $node) { $threshold = $this->getIntProperty('maximum'); - if (Strings::length($node->getImage(), $this->getSubtractSuffixList()) - 1 <= $threshold) { + if (Strings::lengthWithoutSuffixes($node->getImage(), $this->getSubtractSuffixList()) - 1 <= $threshold) { return; } if ($this->isNameAllowedInContext($node)) { diff --git a/src/main/php/PHPMD/Support/Strings.php b/src/main/php/PHPMD/Support/Strings.php index 732d1e3ba..8f869535a 100644 --- a/src/main/php/PHPMD/Support/Strings.php +++ b/src/main/php/PHPMD/Support/Strings.php @@ -25,25 +25,25 @@ class Strings { /** - * Returns the length of the variable name, excluding at most one suffix. + * Returns the length of the given string, excluding at most one suffix. * - * @param string $variableName Variable name to calculate the length for. - * @param array $subtractSuffixes Optional list of suffixes to exclude from the calculated length. + * @param string $stringName String to calculate the length for. + * @param array $subtractSuffixes List of suffixes to exclude from the calculated length. * @return int The length of the string, without suffix, if applicable. */ - public static function length($variableName, array $subtractSuffixes = array()) + public static function lengthWithoutSuffixes($stringName, array $subtractSuffixes) { - $variableNameLength = strlen($variableName); + $stringLength = strlen($stringName); foreach ($subtractSuffixes as $suffix) { $suffixLength = strlen($suffix); - if (substr($variableName, -$suffixLength) === $suffix) { - $variableNameLength -= $suffixLength; + if (substr($stringName, -$suffixLength) === $suffix) { + $stringLength -= $suffixLength; break; } } - return $variableNameLength; + return $stringLength; } /** diff --git a/src/test/php/PHPMD/Support/StringsTest.php b/src/test/php/PHPMD/Support/StringsTest.php index 32c25dc79..418aa5941 100644 --- a/src/test/php/PHPMD/Support/StringsTest.php +++ b/src/test/php/PHPMD/Support/StringsTest.php @@ -31,7 +31,7 @@ class StringsTest extends AbstractTest */ public function testLengthEmptyString() { - static::assertSame(0, Strings::length('')); + static::assertSame(0, Strings::lengthWithoutSuffixes('', array())); } /** @@ -39,7 +39,7 @@ public function testLengthEmptyString() */ public function testLengthEmptyStringWithConfiguredSubtractSuffix() { - static::assertSame(0, Strings::length('', array('Foo', 'Bar'))); + static::assertSame(0, Strings::lengthWithoutSuffixes('', array('Foo', 'Bar'))); } /** @@ -47,7 +47,7 @@ public function testLengthEmptyStringWithConfiguredSubtractSuffix() */ public function testLengthStringWithoutSubtractSuffixMatch() { - static::assertSame(8, Strings::length('UnitTest', array('Foo', 'Bar'))); + static::assertSame(8, Strings::lengthWithoutSuffixes('UnitTest', array('Foo', 'Bar'))); } /** @@ -55,7 +55,7 @@ public function testLengthStringWithoutSubtractSuffixMatch() */ public function testLengthStringWithSubtractSuffixMatch() { - static::assertSame(4, Strings::length('UnitBar', array('Foo', 'Bar'))); + static::assertSame(4, Strings::lengthWithoutSuffixes('UnitBar', array('Foo', 'Bar'))); } /** @@ -63,7 +63,7 @@ public function testLengthStringWithSubtractSuffixMatch() */ public function testLengthStringWithDoubleSuffixMatchSubtractOnce() { - static::assertSame(7, Strings::length('UnitFooBar', array('Foo', 'Bar'))); + static::assertSame(7, Strings::lengthWithoutSuffixes('UnitFooBar', array('Foo', 'Bar'))); } /** @@ -71,7 +71,7 @@ public function testLengthStringWithDoubleSuffixMatchSubtractOnce() */ public function testLengthStringWithPrefixMatchShouldNotSubtract() { - static::assertSame(11, Strings::length('FooUnitTest', array('Foo', 'Bar'))); + static::assertSame(11, Strings::lengthWithoutSuffixes('FooUnitTest', array('Foo', 'Bar'))); } /** From 26309d77eda766a7c8980fd8949c6d9384604463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:00:12 +0200 Subject: [PATCH 020/218] Use double quotes --- src/main/php/PHPMD/Support/Strings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Support/Strings.php b/src/main/php/PHPMD/Support/Strings.php index 8f869535a..6626f8430 100644 --- a/src/main/php/PHPMD/Support/Strings.php +++ b/src/main/php/PHPMD/Support/Strings.php @@ -57,7 +57,7 @@ public static function lengthWithoutSuffixes($stringName, array $subtractSuffixe public static function split($separator, $string) { if ($separator === '') { - throw new InvalidArgumentException('Separator can\'t be empty string'); + throw new InvalidArgumentException("Separator can't be empty string"); } return array_filter( From 426e0347ff04587f07f3c50f5079ac22e8ccee6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:02:24 +0200 Subject: [PATCH 021/218] Rename Strings::split() to splitToList() - Flip parameters in sense of "Split string using separator to get a list of it" - Update doc block - Rename $string parameter to $listAsString --- src/main/php/PHPMD/Rule/Naming/LongClassName.php | 2 +- src/main/php/PHPMD/Rule/Naming/LongVariable.php | 2 +- src/main/php/PHPMD/Rule/Naming/ShortClassName.php | 2 +- src/main/php/PHPMD/Support/Strings.php | 14 +++++++------- src/test/php/PHPMD/Support/StringsTest.php | 14 +++++++------- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php index c3b4cff15..42bbaaa0a 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -60,7 +60,7 @@ public function apply(AbstractNode $node) private function getSubtractSuffixList() { if ($this->subtractSuffixes === null) { - $this->subtractSuffixes = Strings::split(',', $this->getStringProperty('subtract-suffixes', '')); + $this->subtractSuffixes = Strings::splitToList($this->getStringProperty('subtract-suffixes', ''), ','); } return $this->subtractSuffixes; diff --git a/src/main/php/PHPMD/Rule/Naming/LongVariable.php b/src/main/php/PHPMD/Rule/Naming/LongVariable.php index fd8ace630..5d361e00f 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/LongVariable.php @@ -188,7 +188,7 @@ protected function isNotProcessed(AbstractNode $node) private function getSubtractSuffixList() { if ($this->subtractSuffixes === null) { - $this->subtractSuffixes = Strings::split(',', $this->getStringProperty('subtract-suffixes', '')); + $this->subtractSuffixes = Strings::splitToList($this->getStringProperty('subtract-suffixes', ''), ','); } return $this->subtractSuffixes; diff --git a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php index cc3d53e77..819d005e3 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php @@ -65,7 +65,7 @@ public function apply(AbstractNode $node) private function getExceptionsList() { if ($this->exceptions === null) { - $this->exceptions = array_flip(Strings::split(',', $this->getStringProperty('exceptions', ''))); + $this->exceptions = array_flip(Strings::splitToList($this->getStringProperty('exceptions', ''), ',')); } return $this->exceptions; diff --git a/src/main/php/PHPMD/Support/Strings.php b/src/main/php/PHPMD/Support/Strings.php index 6626f8430..c69b30972 100644 --- a/src/main/php/PHPMD/Support/Strings.php +++ b/src/main/php/PHPMD/Support/Strings.php @@ -25,7 +25,7 @@ class Strings { /** - * Returns the length of the given string, excluding at most one suffix. + * Returns the length of the given string, excluding at most one suffix * * @param string $stringName String to calculate the length for. * @param array $subtractSuffixes List of suffixes to exclude from the calculated length. @@ -49,19 +49,19 @@ public static function lengthWithoutSuffixes($stringName, array $subtractSuffixe /** * Split a string with the given separator, trim whitespaces around the parts and remove any empty strings * - * @param string $separator The separator to split the string with, similar to explode - * @param string $string The string to split - * @return array The trimmed and filtered parts of the string - * @throws InvalidArgumentException When the separator is an empty string + * @param string $listAsString The string to split. + * @param string $separator The separator to split the string with, similar to explode. + * @return array The list of trimmed and filtered parts of the string. + * @throws InvalidArgumentException When the separator is an empty string. */ - public static function split($separator, $string) + public static function splitToList($listAsString, $separator) { if ($separator === '') { throw new InvalidArgumentException("Separator can't be empty string"); } return array_filter( - array_map('trim', explode($separator, $string)), + array_map('trim', explode($separator, $listAsString)), function ($value) { return $value !== ''; } diff --git a/src/test/php/PHPMD/Support/StringsTest.php b/src/test/php/PHPMD/Support/StringsTest.php index 418aa5941..e25273ff0 100644 --- a/src/test/php/PHPMD/Support/StringsTest.php +++ b/src/test/php/PHPMD/Support/StringsTest.php @@ -81,7 +81,7 @@ public function testLengthStringWithPrefixMatchShouldNotSubtract() */ public function testSplitEmptySeparatorThrowsException() { - Strings::split('', 'UnitTest'); + Strings::splitToList('UnitTest', ''); } /** @@ -89,7 +89,7 @@ public function testSplitEmptySeparatorThrowsException() */ public function testSplitEmptyString() { - static::assertSame(array(), Strings::split(',', '')); + static::assertSame(array(), Strings::splitToList('', ',')); } /** @@ -97,7 +97,7 @@ public function testSplitEmptyString() */ public function testSplitStringWithoutMatchingSeparator() { - static::assertSame(array('UnitTest'), Strings::split(',', 'UnitTest')); + static::assertSame(array('UnitTest'), Strings::splitToList('UnitTest', ',')); } /** @@ -105,7 +105,7 @@ public function testSplitStringWithoutMatchingSeparator() */ public function testSplitStringWithMatchingSeparator() { - static::assertSame(array('Unit', 'Test'), Strings::split(',', 'Unit,Test')); + static::assertSame(array('Unit', 'Test'), Strings::splitToList('Unit,Test', ',')); } /** @@ -113,7 +113,7 @@ public function testSplitStringWithMatchingSeparator() */ public function testSplitStringTrimsLeadingAndTrailingWhitespace() { - static::assertSame(array('Unit', 'Test'), Strings::split(',', 'Unit , Test')); + static::assertSame(array('Unit', 'Test'), Strings::splitToList('Unit , Test', ',')); } /** @@ -121,7 +121,7 @@ public function testSplitStringTrimsLeadingAndTrailingWhitespace() */ public function testSplitStringRemoveEmptyStringValues() { - static::assertSame(array('Foo'), Strings::split(',', 'Foo,,,')); + static::assertSame(array('Foo'), Strings::splitToList('Foo,,,', ',')); } /** @@ -129,6 +129,6 @@ public function testSplitStringRemoveEmptyStringValues() */ public function testSplitStringShouldNotRemoveAZeroValue() { - static::assertSame(array('0', '1', '2'), Strings::split(',', '0,1,2')); + static::assertSame(array('0', '1', '2'), Strings::splitToList('0,1,2', ',')); } } From 0dff3ca9af6bfbdc48b4a10fb7daf28d02e0fe66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:17:53 +0200 Subject: [PATCH 022/218] Use correct coverage annotation --- src/test/php/PHPMD/Support/StringsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/Support/StringsTest.php b/src/test/php/PHPMD/Support/StringsTest.php index e25273ff0..fc8bdee06 100644 --- a/src/test/php/PHPMD/Support/StringsTest.php +++ b/src/test/php/PHPMD/Support/StringsTest.php @@ -22,7 +22,7 @@ /** * Test case for the Strings utility class. * - * @covers \PHPMD\Support\Strings + * @coversDefaultClass \PHPMD\Support\Strings */ class StringsTest extends AbstractTest { From a2d0939ff66c239dda5e8b5762a249706575b230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:19:07 +0200 Subject: [PATCH 023/218] Correct doc block statement --- src/test/php/PHPMD/Support/StringsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/Support/StringsTest.php b/src/test/php/PHPMD/Support/StringsTest.php index fc8bdee06..28498eff1 100644 --- a/src/test/php/PHPMD/Support/StringsTest.php +++ b/src/test/php/PHPMD/Support/StringsTest.php @@ -20,7 +20,7 @@ use PHPMD\AbstractTest; /** - * Test case for the Strings utility class. + * Test cases for the Strings utility class. * * @coversDefaultClass \PHPMD\Support\Strings */ From 251d02c96a1385ddb55b4b8d2626932efae28b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:20:45 +0200 Subject: [PATCH 024/218] Update test case names to changed method names --- src/test/php/PHPMD/Support/StringsTest.php | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/test/php/PHPMD/Support/StringsTest.php b/src/test/php/PHPMD/Support/StringsTest.php index 28498eff1..c10922eb6 100644 --- a/src/test/php/PHPMD/Support/StringsTest.php +++ b/src/test/php/PHPMD/Support/StringsTest.php @@ -29,7 +29,7 @@ class StringsTest extends AbstractTest /** * @return void */ - public function testLengthEmptyString() + public function testLengthWithoutSuffixesEmptyString() { static::assertSame(0, Strings::lengthWithoutSuffixes('', array())); } @@ -37,7 +37,7 @@ public function testLengthEmptyString() /** * @return void */ - public function testLengthEmptyStringWithConfiguredSubtractSuffix() + public function testLengthWithoutSuffixesEmptyStringWithConfiguredSubtractSuffix() { static::assertSame(0, Strings::lengthWithoutSuffixes('', array('Foo', 'Bar'))); } @@ -45,7 +45,7 @@ public function testLengthEmptyStringWithConfiguredSubtractSuffix() /** * @return void */ - public function testLengthStringWithoutSubtractSuffixMatch() + public function testLengthWithoutSuffixesStringWithoutSubtractSuffixMatch() { static::assertSame(8, Strings::lengthWithoutSuffixes('UnitTest', array('Foo', 'Bar'))); } @@ -53,7 +53,7 @@ public function testLengthStringWithoutSubtractSuffixMatch() /** * @return void */ - public function testLengthStringWithSubtractSuffixMatch() + public function testLengthWithoutSuffixesStringWithSubtractSuffixMatch() { static::assertSame(4, Strings::lengthWithoutSuffixes('UnitBar', array('Foo', 'Bar'))); } @@ -61,7 +61,7 @@ public function testLengthStringWithSubtractSuffixMatch() /** * @return void */ - public function testLengthStringWithDoubleSuffixMatchSubtractOnce() + public function testLengthWithoutSuffixesStringWithDoubleSuffixMatchSubtractOnce() { static::assertSame(7, Strings::lengthWithoutSuffixes('UnitFooBar', array('Foo', 'Bar'))); } @@ -69,7 +69,7 @@ public function testLengthStringWithDoubleSuffixMatchSubtractOnce() /** * @return void */ - public function testLengthStringWithPrefixMatchShouldNotSubtract() + public function testLengthWithoutSuffixesStringWithPrefixMatchShouldNotSubtract() { static::assertSame(11, Strings::lengthWithoutSuffixes('FooUnitTest', array('Foo', 'Bar'))); } @@ -79,7 +79,7 @@ public function testLengthStringWithPrefixMatchShouldNotSubtract() * * @return void */ - public function testSplitEmptySeparatorThrowsException() + public function testSplitToListEmptySeparatorThrowsException() { Strings::splitToList('UnitTest', ''); } @@ -87,7 +87,7 @@ public function testSplitEmptySeparatorThrowsException() /** * @return void */ - public function testSplitEmptyString() + public function testSplitToListEmptyString() { static::assertSame(array(), Strings::splitToList('', ',')); } @@ -95,7 +95,7 @@ public function testSplitEmptyString() /** * @return void */ - public function testSplitStringWithoutMatchingSeparator() + public function testSplitToListStringWithoutMatchingSeparator() { static::assertSame(array('UnitTest'), Strings::splitToList('UnitTest', ',')); } @@ -103,7 +103,7 @@ public function testSplitStringWithoutMatchingSeparator() /** * @return void */ - public function testSplitStringWithMatchingSeparator() + public function testSplitToListStringWithMatchingSeparator() { static::assertSame(array('Unit', 'Test'), Strings::splitToList('Unit,Test', ',')); } @@ -111,7 +111,7 @@ public function testSplitStringWithMatchingSeparator() /** * @return void */ - public function testSplitStringTrimsLeadingAndTrailingWhitespace() + public function testSplitToListStringTrimsLeadingAndTrailingWhitespace() { static::assertSame(array('Unit', 'Test'), Strings::splitToList('Unit , Test', ',')); } @@ -119,7 +119,7 @@ public function testSplitStringTrimsLeadingAndTrailingWhitespace() /** * @return void */ - public function testSplitStringRemoveEmptyStringValues() + public function testSplitToListStringRemoveEmptyStringValues() { static::assertSame(array('Foo'), Strings::splitToList('Foo,,,', ',')); } @@ -127,7 +127,7 @@ public function testSplitStringRemoveEmptyStringValues() /** * @return void */ - public function testSplitStringShouldNotRemoveAZeroValue() + public function testSplitToListStringShouldNotRemoveAZeroValue() { static::assertSame(array('0', '1', '2'), Strings::splitToList('0,1,2', ',')); } From f1a4fd5165951bf869bc0572d0f28377aa32e744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:28:49 +0200 Subject: [PATCH 025/218] Improve test doc blocks --- src/test/php/PHPMD/Support/StringsTest.php | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/test/php/PHPMD/Support/StringsTest.php b/src/test/php/PHPMD/Support/StringsTest.php index c10922eb6..66432958a 100644 --- a/src/test/php/PHPMD/Support/StringsTest.php +++ b/src/test/php/PHPMD/Support/StringsTest.php @@ -27,6 +27,8 @@ class StringsTest extends AbstractTest { /** + * Tests the lengthWithoutSuffixes() method with an empty string + * * @return void */ public function testLengthWithoutSuffixesEmptyString() @@ -35,6 +37,8 @@ public function testLengthWithoutSuffixesEmptyString() } /** + * Tests the lengthWithoutSuffixes() method with an empty string with list of suffixes + * * @return void */ public function testLengthWithoutSuffixesEmptyStringWithConfiguredSubtractSuffix() @@ -43,6 +47,8 @@ public function testLengthWithoutSuffixesEmptyStringWithConfiguredSubtractSuffix } /** + * Tests the lengthWithoutSuffixes() method with a string not in the list of suffixes + * * @return void */ public function testLengthWithoutSuffixesStringWithoutSubtractSuffixMatch() @@ -51,6 +57,8 @@ public function testLengthWithoutSuffixesStringWithoutSubtractSuffixMatch() } /** + * Tests the lengthWithoutSuffixes() method with a string in the list of suffixes + * * @return void */ public function testLengthWithoutSuffixesStringWithSubtractSuffixMatch() @@ -59,6 +67,8 @@ public function testLengthWithoutSuffixesStringWithSubtractSuffixMatch() } /** + * Tests the lengthWithoutSuffixes() method with a string that should match only once for two potential matches + * * @return void */ public function testLengthWithoutSuffixesStringWithDoubleSuffixMatchSubtractOnce() @@ -67,6 +77,8 @@ public function testLengthWithoutSuffixesStringWithDoubleSuffixMatchSubtractOnce } /** + * Tests the lengthWithoutSuffixes() method that a Prefix should not be matched + * * @return void */ public function testLengthWithoutSuffixesStringWithPrefixMatchShouldNotSubtract() @@ -75,6 +87,8 @@ public function testLengthWithoutSuffixesStringWithPrefixMatchShouldNotSubtract( } /** + * Tests the splitToList() method with an empty separator + * * @expectedException \InvalidArgumentException * * @return void @@ -85,6 +99,8 @@ public function testSplitToListEmptySeparatorThrowsException() } /** + * Tests the splitToList() method with an empty string + * * @return void */ public function testSplitToListEmptyString() @@ -93,6 +109,8 @@ public function testSplitToListEmptyString() } /** + * Tests the splitToList() method with a non-matching separator + * * @return void */ public function testSplitToListStringWithoutMatchingSeparator() @@ -101,6 +119,8 @@ public function testSplitToListStringWithoutMatchingSeparator() } /** + * Tests the splitToList() method with a matching separator + * * @return void */ public function testSplitToListStringWithMatchingSeparator() @@ -109,6 +129,8 @@ public function testSplitToListStringWithMatchingSeparator() } /** + * Tests the splitToList() method with trailing whitespace + * * @return void */ public function testSplitToListStringTrimsLeadingAndTrailingWhitespace() @@ -117,6 +139,8 @@ public function testSplitToListStringTrimsLeadingAndTrailingWhitespace() } /** + * Tests the splitToList() method that it removes empty strings from list + * * @return void */ public function testSplitToListStringRemoveEmptyStringValues() @@ -125,6 +149,8 @@ public function testSplitToListStringRemoveEmptyStringValues() } /** + * Tests the splitToList() method that it does not remove zero values from list + * * @return void */ public function testSplitToListStringShouldNotRemoveAZeroValue() From 93f3ec99c06356c36f1edae7f5d5269ff18f1b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:44:02 +0200 Subject: [PATCH 026/218] Rename Support namespace to Utility It is a "Utility class to provide string checks and manipulations" after all. --- src/main/php/PHPMD/Rule/Naming/LongClassName.php | 2 +- src/main/php/PHPMD/Rule/Naming/LongVariable.php | 2 +- src/main/php/PHPMD/Rule/Naming/ShortClassName.php | 2 +- src/main/php/PHPMD/{Support => Utility}/Strings.php | 2 +- src/test/php/PHPMD/{Support => Utility}/StringsTest.php | 5 +++-- 5 files changed, 7 insertions(+), 6 deletions(-) rename src/main/php/PHPMD/{Support => Utility}/Strings.php (98%) rename src/test/php/PHPMD/{Support => Utility}/StringsTest.php (97%) diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php index 42bbaaa0a..5d171b211 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -21,7 +21,7 @@ use PHPMD\AbstractRule; use PHPMD\Rule\ClassAware; use PHPMD\Rule\InterfaceAware; -use PHPMD\Support\Strings; +use PHPMD\Utility\Strings; /** * This rule class will check if a class name doesn't exceed the configured length excluding diff --git a/src/main/php/PHPMD/Rule/Naming/LongVariable.php b/src/main/php/PHPMD/Rule/Naming/LongVariable.php index 5d361e00f..e1b584403 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/LongVariable.php @@ -22,7 +22,7 @@ use PHPMD\Rule\ClassAware; use PHPMD\Rule\FunctionAware; use PHPMD\Rule\MethodAware; -use PHPMD\Support\Strings; +use PHPMD\Utility\Strings; /** * This rule class will detect variables, parameters and properties with really diff --git a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php index 819d005e3..2e65e3685 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php @@ -21,7 +21,7 @@ use PHPMD\AbstractRule; use PHPMD\Rule\ClassAware; use PHPMD\Rule\InterfaceAware; -use PHPMD\Support\Strings; +use PHPMD\Utility\Strings; /** * This rule class will detect classes and interfaces with short names. diff --git a/src/main/php/PHPMD/Support/Strings.php b/src/main/php/PHPMD/Utility/Strings.php similarity index 98% rename from src/main/php/PHPMD/Support/Strings.php rename to src/main/php/PHPMD/Utility/Strings.php index c69b30972..181ad10c5 100644 --- a/src/main/php/PHPMD/Support/Strings.php +++ b/src/main/php/PHPMD/Utility/Strings.php @@ -15,7 +15,7 @@ * @link http://phpmd.org/ */ -namespace PHPMD\Support; +namespace PHPMD\Utility; use InvalidArgumentException; diff --git a/src/test/php/PHPMD/Support/StringsTest.php b/src/test/php/PHPMD/Utility/StringsTest.php similarity index 97% rename from src/test/php/PHPMD/Support/StringsTest.php rename to src/test/php/PHPMD/Utility/StringsTest.php index 66432958a..26cb0c54e 100644 --- a/src/test/php/PHPMD/Support/StringsTest.php +++ b/src/test/php/PHPMD/Utility/StringsTest.php @@ -15,14 +15,15 @@ * @link http://phpmd.org/ */ -namespace PHPMD\Support; +namespace PHPMD\Utility; use PHPMD\AbstractTest; +use PHPMD\Utility\Strings; /** * Test cases for the Strings utility class. * - * @coversDefaultClass \PHPMD\Support\Strings + * @coversDefaultClass \PHPMD\Utility\Strings */ class StringsTest extends AbstractTest { From 99dfd2f02f5b5e1f9983b9d5578adf0b40745d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:45:47 +0200 Subject: [PATCH 027/218] Improve wording --- src/main/php/PHPMD/Rule/Naming/ShortClassName.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php index 2e65e3685..10e50c84c 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php @@ -24,7 +24,7 @@ use PHPMD\Utility\Strings; /** - * This rule class will detect classes and interfaces with short names. + * This rule will detect classes and interfaces with names that are too short. */ class ShortClassName extends AbstractRule implements ClassAware, InterfaceAware { From ecb1b9fba922295ce8bed29b96e6159bed83a054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:48:55 +0200 Subject: [PATCH 028/218] Improve wording --- src/main/php/PHPMD/Rule/Naming/ShortClassName.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php index 10e50c84c..865df0d96 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php @@ -36,8 +36,7 @@ class ShortClassName extends AbstractRule implements ClassAware, InterfaceAware private $exceptions; /** - * This method checks if a class or interface name is below the minimum configured length - * and emits a rule violation. + * Check if a class or interface name is below the minimum configured length and emit a rule violation * * @param \PHPMD\AbstractNode $node * @return void From a2e825551053bba8c3474e5e22b0154f03ec0356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:50:09 +0200 Subject: [PATCH 029/218] Get class or interface name only once --- src/main/php/PHPMD/Rule/Naming/ShortClassName.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php index 865df0d96..314c88a16 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php @@ -44,16 +44,17 @@ class ShortClassName extends AbstractRule implements ClassAware, InterfaceAware public function apply(AbstractNode $node) { $threshold = $this->getIntProperty('minimum'); - if (strlen($node->getName()) >= $threshold) { + $classOrInterfaceName = $node->getName(); + if (strlen($classOrInterfaceName) >= $threshold) { return; } $exceptions = $this->getExceptionsList(); - if (isset($exceptions[$node->getName()])) { + if (isset($exceptions[$classOrInterfaceName])) { return; } - $this->addViolation($node, array($node->getName(), $threshold)); + $this->addViolation($node, array($classOrInterfaceName, $threshold)); } /** From feb6f15742da3a244afd7b129a4583289252cc0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:52:21 +0200 Subject: [PATCH 030/218] CS --- src/main/php/PHPMD/Rule/Naming/ShortClassName.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php index 314c88a16..8a41fcd64 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php @@ -65,7 +65,9 @@ public function apply(AbstractNode $node) private function getExceptionsList() { if ($this->exceptions === null) { - $this->exceptions = array_flip(Strings::splitToList($this->getStringProperty('exceptions', ''), ',')); + $this->exceptions = array_flip( + Strings::splitToList($this->getStringProperty('exceptions', ''), ',') + ); } return $this->exceptions; From c382d7124d78a5dd86736cc48cf5218a650b4907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:54:14 +0200 Subject: [PATCH 031/218] CS --- src/main/php/PHPMD/Rule/Naming/LongClassName.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php index 5d171b211..e0a660ce4 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -60,7 +60,10 @@ public function apply(AbstractNode $node) private function getSubtractSuffixList() { if ($this->subtractSuffixes === null) { - $this->subtractSuffixes = Strings::splitToList($this->getStringProperty('subtract-suffixes', ''), ','); + $this->subtractSuffixes = Strings::splitToList( + $this->getStringProperty('subtract-suffixes', ''), + ',' + ); } return $this->subtractSuffixes; From fb0bb333aa62b6eed2f65153a243bf7036265491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:54:57 +0200 Subject: [PATCH 032/218] Improve wording --- src/main/php/PHPMD/Rule/Naming/LongClassName.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php index e0a660ce4..e544c273b 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -37,8 +37,7 @@ class LongClassName extends AbstractRule implements ClassAware, InterfaceAware private $subtractSuffixes; /** - * This method checks if a class name exceeds the configured maximum length - * and emits a rule violation. + * Check if a class name exceeds the configured maximum length and emit a rule violation * * @param \PHPMD\AbstractNode $node * @return void From 243de223d311672117e38b486e340902e143bc85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:56:01 +0200 Subject: [PATCH 033/218] Improve wording --- src/main/php/PHPMD/Rule/Naming/LongClassName.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php index e544c273b..69bebd031 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -24,8 +24,7 @@ use PHPMD\Utility\Strings; /** - * This rule class will check if a class name doesn't exceed the configured length excluding - * certain configured suffixes. + * This rule checks if an interface or class name exceeds the configured length excluding certain configured suffixes */ class LongClassName extends AbstractRule implements ClassAware, InterfaceAware { From ad1fcb466706c7cc37b55b1d6a18fd6039f5a24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:57:01 +0200 Subject: [PATCH 034/218] Get class or interface name only once --- src/main/php/PHPMD/Rule/Naming/LongClassName.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php index 69bebd031..504d28d07 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -44,10 +44,11 @@ class LongClassName extends AbstractRule implements ClassAware, InterfaceAware public function apply(AbstractNode $node) { $threshold = $this->getIntProperty('maximum'); - if (Strings::lengthWithoutSuffixes($node->getName(), $this->getSubtractSuffixList()) <= $threshold) { + $classOrInterfaceName = $node->getName(); + if (Strings::lengthWithoutSuffixes($classOrInterfaceName, $this->getSubtractSuffixList()) <= $threshold) { return; } - $this->addViolation($node, array($node->getName(), $threshold)); + $this->addViolation($node, array($classOrInterfaceName, $threshold)); } /** From 878a438a2b478452135f51c7fb62bebe2be57ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 02:58:00 +0200 Subject: [PATCH 035/218] Correct coverage annotation and FQCN --- src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php index ddf59bc69..15738e4a8 100644 --- a/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php @@ -22,7 +22,7 @@ /** * Test case for long class names. * - * @covers PHPMD\Rule\Naming\LongClassName + * @coversDefaultClass \PHPMD\Rule\Naming\LongClassName */ class LongClassNameTest extends AbstractTest { From 7d8212cafedf967093167154ba6d75a287dd1c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 03:12:45 +0200 Subject: [PATCH 036/218] Clarify code through intermediate variables --- src/main/php/PHPMD/Rule/Naming/LongVariable.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/LongVariable.php b/src/main/php/PHPMD/Rule/Naming/LongVariable.php index e1b584403..36a97a26c 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/LongVariable.php @@ -106,13 +106,15 @@ protected function checkNodeImage(AbstractNode $node) protected function checkMaximumLength(AbstractNode $node) { $threshold = $this->getIntProperty('maximum'); - if (Strings::lengthWithoutSuffixes($node->getImage(), $this->getSubtractSuffixList()) - 1 <= $threshold) { + $variableName = $node->getImage(); + $lengthWithoutDollarSign = Strings::lengthWithoutSuffixes($variableName, $this->getSubtractSuffixList()) - 1; + if ($lengthWithoutDollarSign <= $threshold) { return; } if ($this->isNameAllowedInContext($node)) { return; } - $this->addViolation($node, array($node->getImage(), $threshold)); + $this->addViolation($node, array($variableName, $threshold)); } /** From f29310d33b57a34fda939c9bd12876f8f9914753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 03:29:03 +0200 Subject: [PATCH 037/218] Improve wording --- src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php | 2 +- src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php index 15738e4a8..86241409a 100644 --- a/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php @@ -20,7 +20,7 @@ use PHPMD\AbstractTest; /** - * Test case for long class names. + * Test cases for LongClassName. * * @coversDefaultClass \PHPMD\Rule\Naming\LongClassName */ diff --git a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php index 1e6829f61..67dc746f8 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortClassNameTest.php @@ -20,7 +20,7 @@ use PHPMD\AbstractTest; /** - * Test case for ShortClassName rule + * Test cases for ShortClassName rule * * @coversDefaultClass \PHPMD\Rule\Naming\ShortClassName */ From 00c808b797245ed143d722b5079a58ef102386b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 03:38:28 +0200 Subject: [PATCH 038/218] Improve test case doc blocks --- .../PHPMD/Rule/Naming/LongClassNameTest.php | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php b/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php index 86241409a..612e6d591 100644 --- a/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php +++ b/src/test/php/PHPMD/Rule/Naming/LongClassNameTest.php @@ -27,8 +27,7 @@ class LongClassNameTest extends AbstractTest { /** - * Class name length: 43 - * Threshold: 43 + * Tests that the rule does not apply to class name length (43) below threshold (44) * * @return void */ @@ -41,8 +40,7 @@ public function testRuleNotAppliesToClassNameBelowThreshold() } /** - * Class name length: 40 - * Threshold: 39 + * Tests that the rule applies to class name length (40) below threshold (39) * * @return void */ @@ -55,8 +53,7 @@ public function testRuleAppliesToClassNameAboveThreshold() } /** - * Interface name length: 47 - * Threshold: 47 + * Tests that the rule does not apply to interface name length (47) below threshold (47) * * @return void */ @@ -69,8 +66,7 @@ public function testRuleNotAppliesToInterfaceNameBelowThreshold() } /** - * Interface name length: 44 - * Threshold: 43 + * Tests that the rule applies to class name length (44) above threshold (43) * * @return void */ @@ -83,9 +79,8 @@ public function testRuleAppliesToInterfaceNameAboveThreshold() } /** - * Class name length: 69 - * Suffix length: 9 - * Threshold: 60 + * Tests that the rule does not apply to class name length (69) below threshold (60) + * with configured suffix length (9) * * @return void */ @@ -99,9 +94,7 @@ public function testRuleNotAppliesToClassNameLengthWithSuffixSubtractedBelowThre } /** - * Class name length: 66 - * Suffix length: 9 - * Threshold: 56 + * Tests that the rule applies to class name length (66) above threshold (56) with configured suffix length (9) * * @return void */ @@ -115,9 +108,8 @@ public function testRuleAppliesToClassNameLengthWithSuffixSubtractedAboveThresho } /** - * Class name length: 55 - * Suffix length: 9 - * Threshold: 54 + * Tests that the rule does not apply to class name length (55) below threshold (54) + * not matching configured suffix length (9) * * @return void */ From b8e3cf7019303335b354982e95365edeb44e371a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 03:48:23 +0200 Subject: [PATCH 039/218] Bump maximum threshold of LongClassName That not only silences violations in PHPMD's own code but also reflects a more sane default. --- src/main/resources/rulesets/naming.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/rulesets/naming.xml b/src/main/resources/rulesets/naming.xml index cc0eca106..1bbb67397 100644 --- a/src/main/resources/rulesets/naming.xml +++ b/src/main/resources/rulesets/naming.xml @@ -18,16 +18,16 @@ The Naming Ruleset contains a collection of rules about names - too long, too sh 3 - + From 1487ff1c3e9c2c9f204af0e7be61f8a3259a2ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 04:01:48 +0200 Subject: [PATCH 040/218] Suppress violation for long variable name --- src/main/php/PHPMD/Rule/Naming/LongVariable.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/php/PHPMD/Rule/Naming/LongVariable.php b/src/main/php/PHPMD/Rule/Naming/LongVariable.php index 36a97a26c..9de30ee52 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/LongVariable.php @@ -102,6 +102,7 @@ protected function checkNodeImage(AbstractNode $node) * * @param \PHPMD\AbstractNode $node * @return void + * @SuppressWarnings(PHPMD.LongVariable) */ protected function checkMaximumLength(AbstractNode $node) { From ff6d92883feb75fc83e604131818e3dab8599ca0 Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Wed, 6 May 2020 17:02:18 +0200 Subject: [PATCH 041/218] Changed Short Class name example from `Id` to `Fo` --- src/main/resources/rulesets/naming.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/rulesets/naming.xml b/src/main/resources/rulesets/naming.xml index 1bbb67397..15d16818b 100644 --- a/src/main/resources/rulesets/naming.xml +++ b/src/main/resources/rulesets/naming.xml @@ -49,11 +49,11 @@ interface ATooLongLongInterfaceNameThatHintsAtADesignProblem { From b34aba2e23e1f40498b5476e8293b926e20a72c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Wed, 6 May 2020 17:26:27 +0200 Subject: [PATCH 042/218] Remove doubly "long" in example class name --- src/main/resources/rulesets/naming.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/rulesets/naming.xml b/src/main/resources/rulesets/naming.xml index 15d16818b..c3c82d8a0 100644 --- a/src/main/resources/rulesets/naming.xml +++ b/src/main/resources/rulesets/naming.xml @@ -23,11 +23,11 @@ The Naming Ruleset contains a collection of rules about names - too long, too sh From d383bd39e4ceb42dea38cee70ed9eacd8dcb1af4 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Thu, 7 May 2020 22:04:59 +0200 Subject: [PATCH 043/218] Rename setIgnorePattern to addIgnorePatterns and getIgnorePattern to getIgnorePatterns so they are less confusion. --- src/main/php/PHPMD/PHPMD.php | 33 ++++++++++++++++++++++++++- src/main/php/PHPMD/TextUI/Command.php | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/PHPMD.php b/src/main/php/PHPMD/PHPMD.php index ff2722143..b260610a9 100644 --- a/src/main/php/PHPMD/PHPMD.php +++ b/src/main/php/PHPMD/PHPMD.php @@ -114,8 +114,23 @@ public function setFileExtensions(array $fileExtensions) * * @return string[] * @since 0.2.0 + * + * @deprecated + * @see getIgnorePatterns */ public function getIgnorePattern() + { + return $this->getIgnorePatterns(); + } + + + /** + * Returns an array with string patterns that mark a file path as invalid. + * + * @return string[] + * @since 0.2.0 + */ + public function getIgnorePatterns() { return $this->ignorePatterns; } @@ -126,8 +141,24 @@ public function getIgnorePattern() * * @param array $ignorePatterns List of ignore patterns. * @return void + * + * @deprecated + * @see addIgnorePatterns */ public function setIgnorePattern(array $ignorePatterns) + { + $this->addIgnorePatterns($ignorePatterns); + } + + + /** + * Add a list of ignore patterns that is used to exclude directories from + * the source analysis. + * + * @param array $ignorePatterns List of ignore patterns. + * @return void + */ + public function addIgnorePatterns(array $ignorePatterns) { $this->ignorePatterns = array_merge( $this->ignorePatterns, @@ -175,7 +206,7 @@ public function processFiles( ) { // Merge parsed excludes - $this->setIgnorePattern($ruleSetFactory->getIgnorePattern($ruleSets)); + $this->addIgnorePatterns($ruleSetFactory->getIgnorePattern($ruleSets)); $this->input = $inputPath; diff --git a/src/main/php/PHPMD/TextUI/Command.php b/src/main/php/PHPMD/TextUI/Command.php index 09a5e6b95..df5c384f6 100644 --- a/src/main/php/PHPMD/TextUI/Command.php +++ b/src/main/php/PHPMD/TextUI/Command.php @@ -95,7 +95,7 @@ public function run(CommandLineOptions $opts, RuleSetFactory $ruleSetFactory) $ignore = $opts->getIgnore(); if ($ignore !== null) { - $phpmd->setIgnorePattern(explode(',', $ignore)); + $phpmd->addIgnorePatterns(explode(',', $ignore)); } $phpmd->processFiles( From 4f1586c227171c5d428c5dbd681aa9387552d491 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Thu, 7 May 2020 22:19:05 +0200 Subject: [PATCH 044/218] Update the use of the deprecated functions from PHPMD in the ParserFactory. --- src/main/php/PHPMD/ParserFactory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/ParserFactory.php b/src/main/php/PHPMD/ParserFactory.php index 65669edd4..630d41907 100644 --- a/src/main/php/PHPMD/ParserFactory.php +++ b/src/main/php/PHPMD/ParserFactory.php @@ -120,9 +120,9 @@ private function initInput(Engine $pdepend, PHPMD $phpmd) */ private function initIgnores(Engine $pdepend, PHPMD $phpmd) { - if (count($phpmd->getIgnorePattern()) > 0) { + if (count($phpmd->getIgnorePatterns()) > 0) { $pdepend->addFileFilter( - new ExcludePathFilter($phpmd->getIgnorePattern()) + new ExcludePathFilter($phpmd->getIgnorePatterns()) ); } } From d801efd8c7862f2182297360e7331849ea37cdcf Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Wed, 13 May 2020 21:00:24 +0200 Subject: [PATCH 045/218] Update docblocks with feedback from @ravage84 --- src/main/php/PHPMD/PHPMD.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/php/PHPMD/PHPMD.php b/src/main/php/PHPMD/PHPMD.php index b260610a9..c3e8ee485 100644 --- a/src/main/php/PHPMD/PHPMD.php +++ b/src/main/php/PHPMD/PHPMD.php @@ -114,9 +114,7 @@ public function setFileExtensions(array $fileExtensions) * * @return string[] * @since 0.2.0 - * - * @deprecated - * @see getIgnorePatterns + * @deprecated 3.0.0 Use getIgnorePatterns() instead, you always get a list of patterns. */ public function getIgnorePattern() { @@ -125,10 +123,10 @@ public function getIgnorePattern() /** - * Returns an array with string patterns that mark a file path as invalid. + * Returns an array with string patterns that mark a file path invalid. * * @return string[] - * @since 0.2.0 + * @since 2.9.0 */ public function getIgnorePatterns() { @@ -141,9 +139,7 @@ public function getIgnorePatterns() * * @param array $ignorePatterns List of ignore patterns. * @return void - * - * @deprecated - * @see addIgnorePatterns + * @deprecated 3.0.0 Use addIgnorePatterns() instead, both will add an not set the patterns. */ public function setIgnorePattern(array $ignorePatterns) { @@ -152,11 +148,12 @@ public function setIgnorePattern(array $ignorePatterns) /** - * Add a list of ignore patterns that is used to exclude directories from + * Add a list of ignore patterns which is used to exclude directories from * the source analysis. * * @param array $ignorePatterns List of ignore patterns. - * @return void + * @return self + * @since 2.9.0 */ public function addIgnorePatterns(array $ignorePatterns) { @@ -164,6 +161,7 @@ public function addIgnorePatterns(array $ignorePatterns) $this->ignorePatterns, $ignorePatterns ); + return $this; } /** From 7ec1d8dc347e4b001ea345bcf1e61eeeea405898 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Wed, 13 May 2020 21:01:58 +0200 Subject: [PATCH 046/218] Fix the mocking in the ParserFactoryTest after using the new functions --- src/test/php/PHPMD/ParserFactoryTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/php/PHPMD/ParserFactoryTest.php b/src/test/php/PHPMD/ParserFactoryTest.php index 2de4b2ddb..2ec7a5b80 100644 --- a/src/test/php/PHPMD/ParserFactoryTest.php +++ b/src/test/php/PHPMD/ParserFactoryTest.php @@ -140,10 +140,10 @@ public function testFactoryConfiguresIgnorePattern() $phpmd = $this->getMockFromBuilder( $this->getMockBuilder('PHPMD\\PHPMD') - ->setMethods(array('getIgnorePattern', 'getInput')) + ->setMethods(array('getIgnorePatterns', 'getInput')) ); $phpmd->expects($this->exactly(2)) - ->method('getIgnorePattern') + ->method('getIgnorePatterns') ->will($this->returnValue(array('Test'))); $phpmd->expects($this->once()) ->method('getInput') From 754b06b03b789613483add6ce77215268ef61420 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Wed, 13 May 2020 21:03:41 +0200 Subject: [PATCH 047/218] Remove unwanted empty lines --- src/main/php/PHPMD/PHPMD.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/php/PHPMD/PHPMD.php b/src/main/php/PHPMD/PHPMD.php index c3e8ee485..accd91ab3 100644 --- a/src/main/php/PHPMD/PHPMD.php +++ b/src/main/php/PHPMD/PHPMD.php @@ -121,7 +121,6 @@ public function getIgnorePattern() return $this->getIgnorePatterns(); } - /** * Returns an array with string patterns that mark a file path invalid. * @@ -146,7 +145,6 @@ public function setIgnorePattern(array $ignorePatterns) $this->addIgnorePatterns($ignorePatterns); } - /** * Add a list of ignore patterns which is used to exclude directories from * the source analysis. From 0bed148d3fe720a040e8f5ca5eb82252971a6f86 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Wed, 13 May 2020 21:18:51 +0200 Subject: [PATCH 048/218] Update the docblock with @this and add an empty line. Feedback from @kylekatarnls --- src/main/php/PHPMD/PHPMD.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/PHPMD.php b/src/main/php/PHPMD/PHPMD.php index accd91ab3..5884f1752 100644 --- a/src/main/php/PHPMD/PHPMD.php +++ b/src/main/php/PHPMD/PHPMD.php @@ -150,7 +150,7 @@ public function setIgnorePattern(array $ignorePatterns) * the source analysis. * * @param array $ignorePatterns List of ignore patterns. - * @return self + * @return $this * @since 2.9.0 */ public function addIgnorePatterns(array $ignorePatterns) @@ -159,6 +159,7 @@ public function addIgnorePatterns(array $ignorePatterns) $this->ignorePatterns, $ignorePatterns ); + return $this; } From 554a474ccbe86bcef3e1a3a4331afa46ec971bb4 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Sat, 16 May 2020 23:59:35 +0200 Subject: [PATCH 049/218] Fix #673 Ignore dynamic class name from missing imports --- .../PHPMD/Rule/CleanCode/MissingImport.php | 6 ++-- .../Rule/CleanCode/MissingImportTest.php | 14 ++++++++++ .../testRuleNotAppliesToDynamicClassName.php | 28 +++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToDynamicClassName.php diff --git a/src/main/php/PHPMD/Rule/CleanCode/MissingImport.php b/src/main/php/PHPMD/Rule/CleanCode/MissingImport.php index 315f06bcd..3e8a709ef 100644 --- a/src/main/php/PHPMD/Rule/CleanCode/MissingImport.php +++ b/src/main/php/PHPMD/Rule/CleanCode/MissingImport.php @@ -55,8 +55,10 @@ public function apply(AbstractNode $node) } $classNameLength = $classNode->getEndColumn() - $classNode->getStartColumn() + 1; - $fqcnLength = strlen($classNode->getImage()); - if ($classNameLength === $fqcnLength) { + $className = $classNode->getImage(); + $fqcnLength = strlen($className); + + if ($classNameLength === $fqcnLength && substr($className, 0, 1) !== '$') { $this->addViolation($classNode, array($classNode->getBeginLine(), $classNode->getStartColumn())); } } diff --git a/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php b/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php index ca60b7f94..1705546a0 100644 --- a/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php +++ b/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php @@ -67,6 +67,20 @@ public function testRuleAppliesToClassWithNotImportedDependencies() $rule->apply($this->getMethod()); } + /** + * Tests that it does not apply to a class that uses self references + * + * @return void + * @covers ::apply + * @covers ::isSelfReference + */ + public function testRuleNotAppliesToDynamicClassName() + { + $rule = new MissingImport(); + $rule->setReport($this->getReportWithNoViolation()); + $rule->apply($this->getMethod()); + } + /** * Tests that it does not apply to a class that uses self references * diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToDynamicClassName.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToDynamicClassName.php new file mode 100644 index 000000000..61b0589e5 --- /dev/null +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToDynamicClassName.php @@ -0,0 +1,28 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +namespace PHPMDTest; + +class testRuleNotAppliesToDynamicClassName +{ + public function testRuleNotAppliesToDynamicClassName() + { + $className = 'DateTime'; + + return (new $className)->format('Y'); + } +} From f6b6f1b68f8a44403058740e044e2e7047bc7557 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Sun, 17 May 2020 00:15:52 +0200 Subject: [PATCH 050/218] Migrate MissingImport to the new testing system --- src/test/php/PHPMD/AbstractTest.php | 27 ++++-- .../Rule/CleanCode/MissingImportTest.php | 96 ++++--------------- ...iceToClassWithNotImportedDependencies.php} | 2 +- ...lyToClassWithOnlyImportedDependencies.php} | 2 +- ...NotApplyToClassWithSelfAndStaticCalls.php} | 2 +- ...NotApplyToClassWithoutAnyDependencies.php} | 2 +- ...estRuleDoesNotApplyToDynamicClassName.php} | 4 +- ...oFunctionWithOnlyImportedDependencies.php} | 2 +- ...ApplyToFunctionWithoutAnyDependencies.php} | 2 +- 9 files changed, 43 insertions(+), 96 deletions(-) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleAppliesToClassWithNotImportedDependencies.php => testRuleAppliesTwiceToClassWithNotImportedDependencies.php} (89%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToClassWithOnlyImportedDependencies.php => testRuleDoesNotApplyToClassWithOnlyImportedDependencies.php} (88%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToClassWithSelfAndStaticCalls.php => testRuleDoesNotApplyToClassWithSelfAndStaticCalls.php} (89%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToClassWithoutAnyDependencies.php => testRuleDoesNotApplyToClassWithoutAnyDependencies.php} (88%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToDynamicClassName.php => testRuleDoesNotApplyToDynamicClassName.php} (85%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToFunctionWithOnlyImportedDependencies.php => testRuleDoesNotApplyToFunctionWithOnlyImportedDependencies.php} (89%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToFunctionWithoutAnyDependencies.php => testRuleDoesNotApplyToFunctionWithoutAnyDependencies.php} (89%) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 014ea609a..53f6094f5 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -187,20 +187,29 @@ protected function getFunction() * Returns the first method as a MethodNode for a given test file. * * @param string $file - * @return MethodNode + * @return MethodNode|FunctionNode * @since 2.8.3 */ protected function getMethodNodeForTestFile($file) { - return new MethodNode( - $this->getNodeByName( - $this->parseSource($file) - ->getTypes() - ->current() - ->getMethods(), - pathinfo($file, PATHINFO_FILENAME) + $source = $this->parseSource($file); + $class = $source + ->getTypes() + ->current(); + + return $class + ? new MethodNode( + $this->getNodeByName( + $class->getMethods(), + pathinfo($file, PATHINFO_FILENAME) + ) ) - ); + : new FunctionNode( + $this->getNodeByName( + $source->getFunctions(), + pathinfo($file, PATHINFO_FILENAME) + ) + ); } /** diff --git a/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php b/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php index 1705546a0..2aca7b62c 100644 --- a/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php +++ b/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php @@ -27,112 +27,50 @@ class MissingImportTest extends AbstractTest { /** - * Tests that it does not apply to a class without any class dependencies + * Get the rule under test. * - * @return void - * @covers ::apply - */ - public function testRuleNotAppliesToClassWithoutAnyDependencies() - { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); - $rule->apply($this->getMethod()); - } - - /** - * Tests that it does not apply to a class with only imported classes - * - * @return void - * @covers ::apply - * @covers ::isSelfReference + * @return MissingImport */ - public function testRuleNotAppliesToClassWithOnlyImportedDependencies() + public function getRule() { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); - $rule->apply($this->getMethod()); + return new MissingImport(); } /** - * Tests that it applies to a class that has fully qualified class names + * Tests the rule for cases where it should apply. * + * @param string $file The test file to test against. * @return void - * @covers ::apply - * @covers ::isSelfReference + * @dataProvider getApplyingCases */ - public function testRuleAppliesToClassWithNotImportedDependencies() + public function testRuleAppliesTo($file) { - $rule = new MissingImport(); - $rule->setReport($this->getReportMock(2)); - $rule->apply($this->getMethod()); + $this->expectRuleHasViolationsForFile($this->getRule(), static::ONE_VIOLATION, $file); } /** - * Tests that it does not apply to a class that uses self references + * Tests the rule for cases where it should not apply. * + * @param string $file The test file to test against. * @return void - * @covers ::apply - * @covers ::isSelfReference + * @dataProvider getNotApplyingCases */ - public function testRuleNotAppliesToDynamicClassName() + public function testRuleDoesNotApplyTo($file) { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); - $rule->apply($this->getMethod()); + $this->expectRuleHasViolationsForFile($this->getRule(), static::NO_VIOLATION, $file); } /** - * Tests that it does not apply to a class that uses self references + * Tests that it applies to a class that has fully qualified class names * * @return void * @covers ::apply * @covers ::isSelfReference */ - public function testRuleNotAppliesToClassWithSelfAndStaticCalls() + public function testRuleAppliesTwiceToClassWithNotImportedDependencies() { $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); + $rule->setReport($this->getReportMock(2)); $rule->apply($this->getMethod()); } - - /** - * Tests that it does not apply to a function without any class dependencies - * - * @return void - * @covers ::apply - */ - public function testRuleNotAppliesToFunctionWithoutAnyDependencies() - { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); - $rule->apply($this->getFunction()); - } - - /** - * Tests that it does not apply to a function with only imported classes - * - * @return void - * @covers ::apply - * @covers ::isSelfReference - */ - public function testRuleNotAppliesToFunctionWithOnlyImportedDependencies() - { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); - $rule->apply($this->getFunction()); - } - - /** - * Tests that it applies to a function that has fully qualified class names - * - * @return void - * @covers ::apply - * @covers ::isSelfReference - */ - public function testRuleAppliesToFunctionWithNotImportedDependencies() - { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithOneViolation()); - $rule->apply($this->getFunction()); - } } diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesToClassWithNotImportedDependencies.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesTwiceToClassWithNotImportedDependencies.php similarity index 89% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesToClassWithNotImportedDependencies.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesTwiceToClassWithNotImportedDependencies.php index 34d2aca7a..8eef4bd5c 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesToClassWithNotImportedDependencies.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesTwiceToClassWithNotImportedDependencies.php @@ -19,7 +19,7 @@ class Foo { - public function testRuleAppliesToClassWithNotImportedDependencies() + public function testRuleAppliesTwiceToClassWithNotImportedDependencies() { $object = new \stdClass(); new \DateTime('2019-02-02 00:00:00'); diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithOnlyImportedDependencies.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithOnlyImportedDependencies.php similarity index 88% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithOnlyImportedDependencies.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithOnlyImportedDependencies.php index 68978974d..58b4db219 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithOnlyImportedDependencies.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithOnlyImportedDependencies.php @@ -21,7 +21,7 @@ class Foo { - public function testRuleNotAppliesToClassWithOnlyImportedDependencies() + public function testRuleDoesNotApplyToClassWithOnlyImportedDependencies() { $object = new stdClass(); } diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithSelfAndStaticCalls.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithSelfAndStaticCalls.php similarity index 89% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithSelfAndStaticCalls.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithSelfAndStaticCalls.php index 07cd5a5dc..e043088e4 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithSelfAndStaticCalls.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithSelfAndStaticCalls.php @@ -19,7 +19,7 @@ class Foo { - public function testRuleNotAppliesToClassWithSelfAndStaticCalls() + public function testRuleDoesNotApplyToClassWithSelfAndStaticCalls() { $self = new self(); new static(); diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithoutAnyDependencies.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithoutAnyDependencies.php similarity index 88% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithoutAnyDependencies.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithoutAnyDependencies.php index f3c58864c..2c9a3fd5c 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithoutAnyDependencies.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithoutAnyDependencies.php @@ -19,7 +19,7 @@ class Foo { - public function testRuleNotAppliesToClassWithoutAnyDependencies() + public function testRuleDoesNotApplyToClassWithoutAnyDependencies() { } diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToDynamicClassName.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToDynamicClassName.php similarity index 85% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToDynamicClassName.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToDynamicClassName.php index 61b0589e5..ace0d86e0 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToDynamicClassName.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToDynamicClassName.php @@ -17,9 +17,9 @@ namespace PHPMDTest; -class testRuleNotAppliesToDynamicClassName +class testRuleDoesNotApplyToDynamicClassName { - public function testRuleNotAppliesToDynamicClassName() + public function testRuleDoesNotApplyToDynamicClassName() { $className = 'DateTime'; diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithOnlyImportedDependencies.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithOnlyImportedDependencies.php similarity index 89% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithOnlyImportedDependencies.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithOnlyImportedDependencies.php index 0b67f0667..44a5d89c9 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithOnlyImportedDependencies.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithOnlyImportedDependencies.php @@ -19,7 +19,7 @@ use stdClass; -function testRuleNotAppliesToFunctionWithOnlyImportedDependencies() +function testRuleDoesNotApplyToFunctionWithOnlyImportedDependencies() { $a = new stdClass(); } diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithoutAnyDependencies.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithoutAnyDependencies.php similarity index 89% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithoutAnyDependencies.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithoutAnyDependencies.php index 8dc8c9873..d44b28ea0 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithoutAnyDependencies.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithoutAnyDependencies.php @@ -17,7 +17,7 @@ namespace PHPMDTest; -function testRuleNotAppliesToFunctionWithoutAnyDependencies() +function testRuleDoesNotApplyToFunctionWithoutAnyDependencies() { $a = null; } From 2462123a054ddc0e710406d167d155e72833d164 Mon Sep 17 00:00:00 2001 From: kylekatarnls Date: Tue, 19 May 2020 10:05:36 +0200 Subject: [PATCH 051/218] Make getMethodNodeForTestFile return the testable FunctionNode if MethodNode is not available --- src/test/php/PHPMD/AbstractTest.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 014ea609a..28dde98a6 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -187,17 +187,27 @@ protected function getFunction() * Returns the first method as a MethodNode for a given test file. * * @param string $file - * @return MethodNode + * @return MethodNode|FunctionNode * @since 2.8.3 */ protected function getMethodNodeForTestFile($file) { - return new MethodNode( + $source = $this->parseSource($file); + $class = $source + ->getTypes() + ->current(); + $nodeClassName = 'PHPMD\\Node\\FunctionNode'; + $getter = 'getFunctions'; + + if ($class) { + $source = $class; + $nodeClassName = 'PHPMD\\Node\\MethodNode'; + $getter = 'getMethods'; + } + + return new $nodeClassName( $this->getNodeByName( - $this->parseSource($file) - ->getTypes() - ->current() - ->getMethods(), + $source->$getter(), pathinfo($file, PATHINFO_FILENAME) ) ); From 531562ca6bdff174fe2ba069ed4955d827750a36 Mon Sep 17 00:00:00 2001 From: kylekatarnls Date: Tue, 19 May 2020 10:11:20 +0200 Subject: [PATCH 052/218] Provide getClassNodeForTestFile in AbstractTest and rename getMethodNodeForTestFile into getNodeForTestFile --- src/test/php/PHPMD/AbstractTest.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 28dde98a6..16d373b7c 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -183,6 +183,20 @@ protected function getFunction() ); } + /** + * Returns the first class found for a given test file. + * + * @return FunctionNode + */ + protected function getClassNodeForTestFile($file) + { + return new ClassNode( + $this->parseSource($file) + ->getTypes() + ->current() + ); + } + /** * Returns the first method as a MethodNode for a given test file. * @@ -190,7 +204,7 @@ protected function getFunction() * @return MethodNode|FunctionNode * @since 2.8.3 */ - protected function getMethodNodeForTestFile($file) + protected function getNodeForTestFile($file) { $source = $this->parseSource($file); $class = $source @@ -223,7 +237,7 @@ protected function getMethodNodeForTestFile($file) protected function expectRuleHasViolationsForFile(Rule $rule, $expectedInvokes, $file) { $rule->setReport($this->getReportMock($expectedInvokes)); - $rule->apply($this->getMethodNodeForTestFile($file)); + $rule->apply($this->getNodeForTestFile($file)); } /** From 013e27ee62ad43a0130fb05f2bf0db07f1fa8a59 Mon Sep 17 00:00:00 2001 From: kylekatarnls Date: Tue, 19 May 2020 10:13:11 +0200 Subject: [PATCH 053/218] Prefix dynamic file rule violation test exception with the file base name. --- src/test/php/PHPMD/AbstractTest.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 16d373b7c..6ce97d09f 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -237,7 +237,17 @@ protected function getNodeForTestFile($file) protected function expectRuleHasViolationsForFile(Rule $rule, $expectedInvokes, $file) { $rule->setReport($this->getReportMock($expectedInvokes)); - $rule->apply($this->getNodeForTestFile($file)); + + try { + $rule->apply($this->getNodeForTestFile($file)); + } catch (PHPUnit_Framework_ExpectationFailedException $failedException) { + throw new PHPUnit_Framework_ExpectationFailedException( + basename($file)."\n". + $failedException->getMessage(), + $failedException->getComparisonFailure(), + $failedException->getPrevious() + ); + } } /** From 5504a929f9593cab4ec9ef12bd613dd1b0e6439a Mon Sep 17 00:00:00 2001 From: kylekatarnls Date: Tue, 19 May 2020 10:15:53 +0200 Subject: [PATCH 054/218] Fix typehint --- src/test/php/PHPMD/AbstractTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 6ce97d09f..9228faed2 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -186,7 +186,7 @@ protected function getFunction() /** * Returns the first class found for a given test file. * - * @return FunctionNode + * @return ClassNode */ protected function getClassNodeForTestFile($file) { From aa555249b780821a6573eb046f0f71c703a47521 Mon Sep 17 00:00:00 2001 From: kylekatarnls Date: Tue, 19 May 2020 12:21:33 +0200 Subject: [PATCH 055/218] #739 Add unit test to demonstrate the class begin line issue --- .../Rule/Design/TooManyPublicMethods.php | 23 ++++++++++-- .../Rule/Design/TooManyPublicMethodsTest.php | 17 +++++++++ .../testRuleApplyToBasicClass.php | 36 +++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/files/Rule/Design/TooManyPublicMethods/testRuleApplyToBasicClass.php diff --git a/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php b/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php index 454148045..2a6d6a5df 100644 --- a/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php +++ b/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php @@ -46,14 +46,19 @@ public function apply(AbstractNode $node) $this->ignoreRegexp = $this->getStringProperty('ignorepattern'); $threshold = $this->getIntProperty('maxmethods'); - if ($node->getMetric('npm') <= $threshold) { + $numberOfPublicMethods = $node->getMetric('npm'); + + if ($numberOfPublicMethods !== null && $numberOfPublicMethods <= $threshold) { return; } + /** @var AbstractTypeNode $node */ $nom = $this->countMethods($node); + if ($nom <= $threshold) { return; } + $this->addViolation( $node, array( @@ -75,11 +80,25 @@ private function countMethods(AbstractTypeNode $node) { $count = 0; foreach ($node->getMethods() as $method) { - if ($method->getNode()->isPublic() && preg_match($this->ignoreRegexp, $method->getName()) === 0) { + if ($method->getNode()->isPublic() && !$this->isIgnoredMethodName($method->getName())) { ++$count; } } return $count; } + + /** + * Return true if the method name is ignored by the current ignoreRegexp pattern. + * + * ignoreRegexp is given to the rule using ignorepattern option. + * + * @param string $methodName + * @return bool + */ + private function isIgnoredMethodName($methodName) + { + return !empty($this->ignoreRegexp) && + preg_match($this->ignoreRegexp, $methodName) === 1; + } } diff --git a/src/test/php/PHPMD/Rule/Design/TooManyPublicMethodsTest.php b/src/test/php/PHPMD/Rule/Design/TooManyPublicMethodsTest.php index dc0183a78..91025ea86 100644 --- a/src/test/php/PHPMD/Rule/Design/TooManyPublicMethodsTest.php +++ b/src/test/php/PHPMD/Rule/Design/TooManyPublicMethodsTest.php @@ -21,6 +21,7 @@ use PDepend\Source\AST\State; use PHPMD\AbstractTest; use PHPMD\Node\MethodNode; +use PHPMD\Report; /** * Test case for the too many public methods rule. @@ -161,6 +162,22 @@ public function testRuleIgnoresWithers() $rule->apply($this->createClassMock(2, array('invoke', 'withClass'))); } + public function testRuleApplyToBasicClass() + { + $class = $this->getClass(); + $rule = new TooManyPublicMethods(); + $report = new Report(); + $rule->setReport($report); + $rule->addProperty('maxmethods', '5'); + $rule->addProperty('ignorepattern', ''); + $rule->apply($class); + $violations = $report->getRuleViolations(); + + $this->assertCount(1, $violations); + + $this->assertSame(6, $violations[0]->getBeginLine()); + } + /** * Creates a prepared class node mock * diff --git a/src/test/resources/files/Rule/Design/TooManyPublicMethods/testRuleApplyToBasicClass.php b/src/test/resources/files/Rule/Design/TooManyPublicMethods/testRuleApplyToBasicClass.php new file mode 100644 index 000000000..c25a71677 --- /dev/null +++ b/src/test/resources/files/Rule/Design/TooManyPublicMethods/testRuleApplyToBasicClass.php @@ -0,0 +1,36 @@ + Date: Tue, 19 May 2020 19:53:44 +0200 Subject: [PATCH 056/218] Correct statement in method doc block --- src/test/php/PHPMD/AbstractTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 9228faed2..9272a143f 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -198,7 +198,7 @@ protected function getClassNodeForTestFile($file) } /** - * Returns the first method as a MethodNode for a given test file. + * Returns the first method or function as a MethodNode for a given test file. * * @param string $file * @return MethodNode|FunctionNode From 6fe6d1f82d28f1ab5842d2287928a31407987112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Tue, 19 May 2020 19:58:49 +0200 Subject: [PATCH 057/218] Improve doc bock --- src/test/php/PHPMD/AbstractTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 9272a143f..befdfdae1 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -228,7 +228,10 @@ protected function getNodeForTestFile($file) } /** - * Test that a given file trigger N times the given rule. + * Assert that a given file trigger N times the given rule. + * + * Rethrows the PHPUnit ExpectationFailedException with the base name + * of the file for better readability. * * @param Rule $rule Rule to test. * @param int $expectedInvokes Count of expected invocations. From 0dca58515f4c80f731e385cf1d9a9c9311435dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Tue, 19 May 2020 23:20:58 +0200 Subject: [PATCH 058/218] Improve wording Co-authored-by: Kyle --- src/test/php/PHPMD/AbstractTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index befdfdae1..c339dfc7f 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -198,7 +198,7 @@ protected function getClassNodeForTestFile($file) } /** - * Returns the first method or function as a MethodNode for a given test file. + * Returns the first method or function node for a given test file. * * @param string $file * @return MethodNode|FunctionNode From 5fbf01449175e31a079e894962e483ccc9b30675 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Wed, 20 May 2020 11:26:32 +0200 Subject: [PATCH 059/218] Update CONTRIBUTING to point out to the correct coding standard --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0921f53b4..aff339ba9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,7 @@ if you have found a bug or have an idea for a feature There are a few guidelines that we need contributors to follow, so that we have a chance of keeping on top of things. -* The code must follow the [PSR-2 coding standard](http://www.php-fig.org/psr/psr-2/). +* The code must follow the [coding standard](https://github.com/phpmd/phpmd/blob/master/phpcs.xml.dist), that is based on [PSR-2 coding standard](http://www.php-fig.org/psr/psr-2/) with additional rules. * All code changes should be covered by unit tests Issues @@ -26,15 +26,15 @@ Issues Coding Standard --------------- -Make sure your code changes comply with the PSR-2 coding standard by +Make sure your code changes comply with the [coding standard](https://github.com/phpmd/phpmd/blob/master/phpcs.xml.dist) by using [PHP Codesniffer](https://github.com/squizlabs/PHP_CodeSniffer) from within your PHPMD folder: - vendor/bin/phpcs -p --extensions=php --standard=PSR2 src > phpcs.txt + vendor/bin/phpcs -p --extensions=php src > phpcs.txt Linux / OS X users may extend this command to exclude files, that are not part of a commit: - vendor/bin/phpcs -p --extensions=php --standard=PSR2 --ignore=src/tests/resources $(git ls-files -om --exclude-standard | grep '\.php$') > phpcs.txt + vendor/bin/phpcs -p --extensions=php --ignore=src/tests/resources $(git ls-files -om --exclude-standard | grep '\.php$') > phpcs.txt Check the ``phpcs.txt`` once it finished. From c7268f2df64e6b0f70e4f4af726919e926b2b2a2 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Wed, 20 May 2020 21:59:38 +0200 Subject: [PATCH 060/218] Add file basename for both apply and notApply --- src/test/php/PHPMD/AbstractTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index c339dfc7f..6dd2184ab 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -34,6 +34,7 @@ use PHPMD\Node\TraitNode; use PHPMD\Rule\Design\TooManyFields; use PHPMD\Stubs\RuleStub; +use PHPUnit_Framework_ExpectationFailedException; use PHPUnit_Framework_MockObject_MockBuilder; use PHPUnit_Framework_MockObject_MockObject; @@ -239,10 +240,12 @@ protected function getNodeForTestFile($file) */ protected function expectRuleHasViolationsForFile(Rule $rule, $expectedInvokes, $file) { - $rule->setReport($this->getReportMock($expectedInvokes)); + $reportMock = $this->getReportMock($expectedInvokes); + $rule->setReport($reportMock); try { $rule->apply($this->getNodeForTestFile($file)); + $reportMock->__phpunit_verify(); } catch (PHPUnit_Framework_ExpectationFailedException $failedException) { throw new PHPUnit_Framework_ExpectationFailedException( basename($file)."\n". From b074c2675388b5450c911da0c4435d8b19392dde Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Wed, 20 May 2020 23:35:12 +0200 Subject: [PATCH 061/218] Improve error message for apply and notApply tests --- src/test/php/PHPMD/AbstractTest.php | 42 ++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 6dd2184ab..70a061541 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -37,6 +37,7 @@ use PHPUnit_Framework_ExpectationFailedException; use PHPUnit_Framework_MockObject_MockBuilder; use PHPUnit_Framework_MockObject_MockObject; +use ReflectionProperty; /** * Abstract base class for PHPMD test cases. @@ -240,20 +241,41 @@ protected function getNodeForTestFile($file) */ protected function expectRuleHasViolationsForFile(Rule $rule, $expectedInvokes, $file) { - $reportMock = $this->getReportMock($expectedInvokes); - $rule->setReport($reportMock); + $report = new Report(); + $rule->setReport($report); + $rule->apply($this->getNodeForTestFile($file)); + $violations = $report->getRuleViolations(); + $actualInvokes = count($violations); + $assertion = $expectedInvokes === self::AL_LEAST_ONE_VIOLATION + ? $actualInvokes > 0 + : $actualInvokes === $expectedInvokes; - try { - $rule->apply($this->getNodeForTestFile($file)); - $reportMock->__phpunit_verify(); - } catch (PHPUnit_Framework_ExpectationFailedException $failedException) { + if (!$assertion) { throw new PHPUnit_Framework_ExpectationFailedException( - basename($file)."\n". - $failedException->getMessage(), - $failedException->getComparisonFailure(), - $failedException->getPrevious() + basename($file)." failed:\n". + "Expected $expectedInvokes violation".($expectedInvokes !== 1 ? 's' : '')."\n". + "But $actualInvokes violation".($actualInvokes !== 1 ? 's' : '')." raised". + ($actualInvokes > 0 + ? ":\n".implode("\n", array_map(function (RuleViolation $violation) { + $nodeExtractor = new ReflectionProperty('PHPMD\\RuleViolation', 'node'); + $nodeExtractor->setAccessible(true); + $node = $nodeExtractor->getValue($violation); + $node = $node ? $node->getNode() : null; + $message = ' - line '.$violation->getBeginLine(); + + if ($node) { + $type = preg_replace('/^PDepend\\\\Source\\\\AST\\\\AST/', '', get_class($node)); + $message .= ' on '.$type.' '.$node->getImage(); + } + + return $message; + }, iterator_to_array($violations))) + : '.' + ) ); } + + $this->assertTrue($assertion); } /** From b12565917582269b939af898272d8c6b3e122f81 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 21 May 2020 00:57:51 +0200 Subject: [PATCH 062/218] Cleanup merge changes --- src/test/php/PHPMD/AbstractTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index ec62f26bc..c339dfc7f 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -210,7 +210,6 @@ protected function getNodeForTestFile($file) $class = $source ->getTypes() ->current(); - $nodeClassName = 'PHPMD\\Node\\FunctionNode'; $getter = 'getFunctions'; From 757491b0e55f8abd652c48bc1c62979df1f43319 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Thu, 21 May 2020 01:02:36 +0200 Subject: [PATCH 063/218] Migrate MissingImport tests on the apply/notApply standard --- .../Rule/CleanCode/MissingImportTest.php | 82 ++++--------------- ...iceToClassWithNotImportedDependencies.php} | 2 +- ...lyToClassWithOnlyImportedDependencies.php} | 2 +- ...NotApplyToClassWithSelfAndStaticCalls.php} | 2 +- ...NotApplyToClassWithoutAnyDependencies.php} | 2 +- ...oFunctionWithOnlyImportedDependencies.php} | 2 +- ...ApplyToFunctionWithoutAnyDependencies.php} | 2 +- 7 files changed, 23 insertions(+), 71 deletions(-) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleAppliesToClassWithNotImportedDependencies.php => testRuleAppliesTwiceToClassWithNotImportedDependencies.php} (89%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToClassWithOnlyImportedDependencies.php => testRuleDoesNotApplyToClassWithOnlyImportedDependencies.php} (88%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToClassWithSelfAndStaticCalls.php => testRuleDoesNotApplyToClassWithSelfAndStaticCalls.php} (89%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToClassWithoutAnyDependencies.php => testRuleDoesNotApplyToClassWithoutAnyDependencies.php} (88%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToFunctionWithOnlyImportedDependencies.php => testRuleDoesNotApplyToFunctionWithOnlyImportedDependencies.php} (89%) rename src/test/resources/files/Rule/CleanCode/MissingImport/{testRuleNotAppliesToFunctionWithoutAnyDependencies.php => testRuleDoesNotApplyToFunctionWithoutAnyDependencies.php} (89%) diff --git a/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php b/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php index ca60b7f94..2aca7b62c 100644 --- a/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php +++ b/src/test/php/PHPMD/Rule/CleanCode/MissingImportTest.php @@ -27,98 +27,50 @@ class MissingImportTest extends AbstractTest { /** - * Tests that it does not apply to a class without any class dependencies + * Get the rule under test. * - * @return void - * @covers ::apply + * @return MissingImport */ - public function testRuleNotAppliesToClassWithoutAnyDependencies() + public function getRule() { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); - $rule->apply($this->getMethod()); + return new MissingImport(); } /** - * Tests that it does not apply to a class with only imported classes + * Tests the rule for cases where it should apply. * + * @param string $file The test file to test against. * @return void - * @covers ::apply - * @covers ::isSelfReference + * @dataProvider getApplyingCases */ - public function testRuleNotAppliesToClassWithOnlyImportedDependencies() + public function testRuleAppliesTo($file) { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); - $rule->apply($this->getMethod()); + $this->expectRuleHasViolationsForFile($this->getRule(), static::ONE_VIOLATION, $file); } /** - * Tests that it applies to a class that has fully qualified class names + * Tests the rule for cases where it should not apply. * + * @param string $file The test file to test against. * @return void - * @covers ::apply - * @covers ::isSelfReference + * @dataProvider getNotApplyingCases */ - public function testRuleAppliesToClassWithNotImportedDependencies() + public function testRuleDoesNotApplyTo($file) { - $rule = new MissingImport(); - $rule->setReport($this->getReportMock(2)); - $rule->apply($this->getMethod()); + $this->expectRuleHasViolationsForFile($this->getRule(), static::NO_VIOLATION, $file); } /** - * Tests that it does not apply to a class that uses self references + * Tests that it applies to a class that has fully qualified class names * * @return void * @covers ::apply * @covers ::isSelfReference */ - public function testRuleNotAppliesToClassWithSelfAndStaticCalls() + public function testRuleAppliesTwiceToClassWithNotImportedDependencies() { $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); + $rule->setReport($this->getReportMock(2)); $rule->apply($this->getMethod()); } - - /** - * Tests that it does not apply to a function without any class dependencies - * - * @return void - * @covers ::apply - */ - public function testRuleNotAppliesToFunctionWithoutAnyDependencies() - { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); - $rule->apply($this->getFunction()); - } - - /** - * Tests that it does not apply to a function with only imported classes - * - * @return void - * @covers ::apply - * @covers ::isSelfReference - */ - public function testRuleNotAppliesToFunctionWithOnlyImportedDependencies() - { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithNoViolation()); - $rule->apply($this->getFunction()); - } - - /** - * Tests that it applies to a function that has fully qualified class names - * - * @return void - * @covers ::apply - * @covers ::isSelfReference - */ - public function testRuleAppliesToFunctionWithNotImportedDependencies() - { - $rule = new MissingImport(); - $rule->setReport($this->getReportWithOneViolation()); - $rule->apply($this->getFunction()); - } } diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesToClassWithNotImportedDependencies.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesTwiceToClassWithNotImportedDependencies.php similarity index 89% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesToClassWithNotImportedDependencies.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesTwiceToClassWithNotImportedDependencies.php index 34d2aca7a..8eef4bd5c 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesToClassWithNotImportedDependencies.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleAppliesTwiceToClassWithNotImportedDependencies.php @@ -19,7 +19,7 @@ class Foo { - public function testRuleAppliesToClassWithNotImportedDependencies() + public function testRuleAppliesTwiceToClassWithNotImportedDependencies() { $object = new \stdClass(); new \DateTime('2019-02-02 00:00:00'); diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithOnlyImportedDependencies.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithOnlyImportedDependencies.php similarity index 88% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithOnlyImportedDependencies.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithOnlyImportedDependencies.php index 68978974d..58b4db219 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithOnlyImportedDependencies.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithOnlyImportedDependencies.php @@ -21,7 +21,7 @@ class Foo { - public function testRuleNotAppliesToClassWithOnlyImportedDependencies() + public function testRuleDoesNotApplyToClassWithOnlyImportedDependencies() { $object = new stdClass(); } diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithSelfAndStaticCalls.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithSelfAndStaticCalls.php similarity index 89% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithSelfAndStaticCalls.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithSelfAndStaticCalls.php index 07cd5a5dc..e043088e4 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithSelfAndStaticCalls.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithSelfAndStaticCalls.php @@ -19,7 +19,7 @@ class Foo { - public function testRuleNotAppliesToClassWithSelfAndStaticCalls() + public function testRuleDoesNotApplyToClassWithSelfAndStaticCalls() { $self = new self(); new static(); diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithoutAnyDependencies.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithoutAnyDependencies.php similarity index 88% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithoutAnyDependencies.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithoutAnyDependencies.php index f3c58864c..2c9a3fd5c 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToClassWithoutAnyDependencies.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToClassWithoutAnyDependencies.php @@ -19,7 +19,7 @@ class Foo { - public function testRuleNotAppliesToClassWithoutAnyDependencies() + public function testRuleDoesNotApplyToClassWithoutAnyDependencies() { } diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithOnlyImportedDependencies.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithOnlyImportedDependencies.php similarity index 89% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithOnlyImportedDependencies.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithOnlyImportedDependencies.php index 0b67f0667..44a5d89c9 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithOnlyImportedDependencies.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithOnlyImportedDependencies.php @@ -19,7 +19,7 @@ use stdClass; -function testRuleNotAppliesToFunctionWithOnlyImportedDependencies() +function testRuleDoesNotApplyToFunctionWithOnlyImportedDependencies() { $a = new stdClass(); } diff --git a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithoutAnyDependencies.php b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithoutAnyDependencies.php similarity index 89% rename from src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithoutAnyDependencies.php rename to src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithoutAnyDependencies.php index 8dc8c9873..d44b28ea0 100644 --- a/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleNotAppliesToFunctionWithoutAnyDependencies.php +++ b/src/test/resources/files/Rule/CleanCode/MissingImport/testRuleDoesNotApplyToFunctionWithoutAnyDependencies.php @@ -17,7 +17,7 @@ namespace PHPMDTest; -function testRuleNotAppliesToFunctionWithoutAnyDependencies() +function testRuleDoesNotApplyToFunctionWithoutAnyDependencies() { $a = null; } From d999b5cb572384af65438d42438e67e6e41b329c Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Thu, 21 May 2020 22:23:49 +0200 Subject: [PATCH 064/218] #580 Add unit tests to demonstrate the rule mismatch --- .../PHPMD/Rule/UnusedFormalParameterTest.php | 12 +++++++++ .../PHPMD/Rule/UnusedLocalVariableTest.php | 13 ++++++++++ ...eAppliesToClosureUnusedFormalParameter.php | 26 +++++++++++++++++++ ...testRuleDoesNotApplyToClosureParameter.php | 26 +++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 src/test/resources/files/Rule/UnusedFormalParameter/testRuleAppliesToClosureUnusedFormalParameter.php create mode 100644 src/test/resources/files/Rule/UnusedLocalVariable/testRuleDoesNotApplyToClosureParameter.php diff --git a/src/test/php/PHPMD/Rule/UnusedFormalParameterTest.php b/src/test/php/PHPMD/Rule/UnusedFormalParameterTest.php index 732ccb936..07588c433 100644 --- a/src/test/php/PHPMD/Rule/UnusedFormalParameterTest.php +++ b/src/test/php/PHPMD/Rule/UnusedFormalParameterTest.php @@ -63,6 +63,18 @@ public function testRuleAppliesToMethodUnusedFormalParameter() $rule->apply($this->getMethod()); } + /** + * testRuleAppliesToClosureUnusedFormalParameter + * + * @return void + */ + public function testRuleAppliesToClosureUnusedFormalParameter() + { + $rule = new UnusedFormalParameter(); + $rule->setReport($this->getReportWithOneViolation()); + $rule->apply($this->getMethod()); + } + /** * testRuleAppliesToMultipleMethodUnusedFormalParameter * diff --git a/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php b/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php index 576362a1e..d30c0fee3 100644 --- a/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php +++ b/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php @@ -297,6 +297,19 @@ public function testRuleDoesNotApplyToCookieSuperGlobal() $rule->apply($this->getMethod()); } + /** + * testRuleDoesNotApplyToClosureParameter + * + * @return void + */ + public function testRuleDoesNotApplyToClosureParameter() + { + $rule = new UnusedLocalVariable(); + $rule->addProperty('allow-unused-foreach-variables', 'false'); + $rule->setReport($this->getReportWithNoViolation()); + $rule->apply($this->getMethod()); + } + /** * testRuleDoesNotApplyToEnvSuperGlobal * diff --git a/src/test/resources/files/Rule/UnusedFormalParameter/testRuleAppliesToClosureUnusedFormalParameter.php b/src/test/resources/files/Rule/UnusedFormalParameter/testRuleAppliesToClosureUnusedFormalParameter.php new file mode 100644 index 000000000..05bc3e449 --- /dev/null +++ b/src/test/resources/files/Rule/UnusedFormalParameter/testRuleAppliesToClosureUnusedFormalParameter.php @@ -0,0 +1,26 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleAppliesToClosureUnusedFormalParameter +{ + public function testRuleAppliesToClosureUnusedFormalParameter() + { + return function ($blah) { + + }; + } +} diff --git a/src/test/resources/files/Rule/UnusedLocalVariable/testRuleDoesNotApplyToClosureParameter.php b/src/test/resources/files/Rule/UnusedLocalVariable/testRuleDoesNotApplyToClosureParameter.php new file mode 100644 index 000000000..2a1c9e29a --- /dev/null +++ b/src/test/resources/files/Rule/UnusedLocalVariable/testRuleDoesNotApplyToClosureParameter.php @@ -0,0 +1,26 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleDoesNotApplyToClosureParameter +{ + function testRuleDoesNotApplyToClosureParameter() + { + return function ($blah) { + + }; + } +} From 4f754d719a6d7656c5ba6e29ed5b4e4f08d58a67 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Thu, 21 May 2020 22:26:02 +0200 Subject: [PATCH 065/218] #580 Ignore ASTFormalParameter in UnusedLocalVariable rule --- src/main/php/PHPMD/Rule/UnusedLocalVariable.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/Rule/UnusedLocalVariable.php b/src/main/php/PHPMD/Rule/UnusedLocalVariable.php index 2a2be3fea..175761eb3 100644 --- a/src/main/php/PHPMD/Rule/UnusedLocalVariable.php +++ b/src/main/php/PHPMD/Rule/UnusedLocalVariable.php @@ -17,6 +17,7 @@ namespace PHPMD\Rule; +use PDepend\Source\AST\ASTFormalParameter; use PHPMD\AbstractNode; use PHPMD\Node\AbstractCallableNode; use PHPMD\Node\ASTNode; @@ -102,6 +103,7 @@ private function collectVariables(AbstractCallableNode $node) foreach ($node->findChildrenOfType('VariableDeclarator') as $variable) { $this->collectVariable($variable); } + foreach ($node->findChildrenOfType('FunctionPostfix') as $func) { if ($this->isFunctionNameEndingWith($func, 'compact')) { foreach ($func->findChildrenOfType('Literal') as $literal) { @@ -188,13 +190,20 @@ protected function doCheckNodeImage(ASTNode $node) if ($this->isNameAllowedInContext($node)) { return; } + if ($this->isUnusedForeachVariableAllowed($node)) { return; } - $exceptions = $this->getExceptionsList(); - if (in_array(substr($node->getImage(), 1), $exceptions)) { + + if (in_array(substr($node->getImage(), 1), $this->getExceptionsList())) { return; } + + // ASTFormalParameter should be handled by the UnusedFormalParameter rule + if ($this->getNode($node->getParent()) instanceof ASTFormalParameter) { + return; + } + $this->addViolation($node, array($node->getImage())); } From 715fa98dbf66090262c42c3596de3c5e69364be6 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Thu, 21 May 2020 22:29:06 +0200 Subject: [PATCH 066/218] #580 Loop over every ASTFormalParameter in UnusedFormalParameter --- src/main/php/PHPMD/Rule/UnusedFormalParameter.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/php/PHPMD/Rule/UnusedFormalParameter.php b/src/main/php/PHPMD/Rule/UnusedFormalParameter.php index fcf17cb37..a9e227eac 100644 --- a/src/main/php/PHPMD/Rule/UnusedFormalParameter.php +++ b/src/main/php/PHPMD/Rule/UnusedFormalParameter.php @@ -156,14 +156,14 @@ private function isNotDeclaration(AbstractNode $node) */ private function collectParameters(AbstractNode $node) { - // First collect the formal parameters container - $parameters = $node->getFirstChildOfType('FormalParameters'); + // First collect the formal parameters containers + foreach ($node->findChildrenOfType('FormalParameters') as $parameters) { + // Now get all declarators in the formal parameters container + $declarators = $parameters->findChildrenOfType('VariableDeclarator'); - // Now get all declarators in the formal parameters container - $declarators = $parameters->findChildrenOfType('VariableDeclarator'); - - foreach ($declarators as $declarator) { - $this->nodes[$declarator->getImage()] = $declarator; + foreach ($declarators as $declarator) { + $this->nodes[$declarator->getImage()] = $declarator; + } } } From 06f33936fbda3e3b02bdba4cca14dc9c82305a3f Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Thu, 21 May 2020 23:52:04 +0200 Subject: [PATCH 067/218] #540 Add a unit test to demonstrate the double-assignation issue --- .../PHPMD/Rule/UnusedLocalVariableTest.php | 13 ++++++++++ ...liesToUnusedLocalVariableDeclaredTwice.php | 25 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/test/resources/files/Rule/UnusedLocalVariable/testRuleAppliesToUnusedLocalVariableDeclaredTwice.php diff --git a/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php b/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php index 576362a1e..d07a677c6 100644 --- a/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php +++ b/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php @@ -40,6 +40,19 @@ public function testRuleAppliesToUnusedLocalVariable() $rule->apply($this->getMethod()); } + /** + * testRuleAppliesToUnusedLocalVariable + * + * @return void + */ + public function testRuleAppliesToUnusedLocalVariableDeclaredTwice() + { + $rule = new UnusedLocalVariable(); + $rule->addProperty('allow-unused-foreach-variables', 'false'); + $rule->setReport($this->getReportWithOneViolation()); + $rule->apply($this->getMethod()); + } + /** * testInnerFunctionParametersDoNotHideUnusedVariables * diff --git a/src/test/resources/files/Rule/UnusedLocalVariable/testRuleAppliesToUnusedLocalVariableDeclaredTwice.php b/src/test/resources/files/Rule/UnusedLocalVariable/testRuleAppliesToUnusedLocalVariableDeclaredTwice.php new file mode 100644 index 000000000..2249a2d46 --- /dev/null +++ b/src/test/resources/files/Rule/UnusedLocalVariable/testRuleAppliesToUnusedLocalVariableDeclaredTwice.php @@ -0,0 +1,25 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleAppliesToUnusedLocalVariableDeclaredTwice +{ + function testRuleAppliesToUnusedLocalVariableDeclaredTwice() + { + $x = 42; + $x = 42; + } +} From 114880fb34dcf751b861835660f043c415cacc84 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Fri, 22 May 2020 00:11:52 +0200 Subject: [PATCH 068/218] Fix #540 Detect unused variable declared multiple times --- src/main/php/PHPMD/AbstractRule.php | 1 + .../php/PHPMD/Rule/UnusedLocalVariable.php | 35 ++++++++++++++----- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/main/php/PHPMD/AbstractRule.php b/src/main/php/PHPMD/AbstractRule.php index a748f0e84..bcfd0d46f 100644 --- a/src/main/php/PHPMD/AbstractRule.php +++ b/src/main/php/PHPMD/AbstractRule.php @@ -314,6 +314,7 @@ protected function getProperty($name, $default = null) if (isset($this->properties[$name])) { return $this->properties[$name]; } + if ($default !== null) { return $default; } diff --git a/src/main/php/PHPMD/Rule/UnusedLocalVariable.php b/src/main/php/PHPMD/Rule/UnusedLocalVariable.php index 2a2be3fea..7a1302344 100644 --- a/src/main/php/PHPMD/Rule/UnusedLocalVariable.php +++ b/src/main/php/PHPMD/Rule/UnusedLocalVariable.php @@ -50,12 +50,33 @@ public function apply(AbstractNode $node) $this->removeParameters($node); foreach ($this->images as $nodes) { - if (count($nodes) === 1) { + if (!$this->containsUsages($nodes)) { $this->doCheckNodeImage($nodes[0]); } } } + private function containsUsages(array $nodes) + { + if (count($nodes) === 1) { + return false; + } + + foreach ($nodes as $node) { + $parent = $node->getParent(); + + if (!$parent->isInstanceOf('AssignmentExpression')) { + return true; + } + + if (in_array($this->getNode($node), array_slice($parent->getChildren(), 1))) { + return true; + } + } + + return false; + } + /** * This method removes all variables from the $_images property that * are also found in the formal parameters of the given method or/and @@ -159,6 +180,7 @@ private function storeImage($imageName, ASTNode $node) if (!isset($this->images[$imageName])) { $this->images[$imageName] = array(); } + $this->images[$imageName][] = $node; } @@ -171,9 +193,11 @@ private function storeImage($imageName, ASTNode $node) private function collectLiteral(ASTNode $node) { $variable = '$' . trim($node->getImage(), '\''); + if (!isset($this->images[$variable])) { $this->images[$variable] = array(); } + $this->images[$variable][] = $node; } @@ -222,6 +246,7 @@ private function isNameAllowedInContext(AbstractNode $node) private function isUnusedForeachVariableAllowed(ASTNode $variable) { $isForeachVariable = $this->isChildOf($variable, 'ForeachStatement'); + if (!$isForeachVariable) { return false; } @@ -251,12 +276,6 @@ private function isChildOf(AbstractNode $node, $type) */ private function getExceptionsList() { - try { - $exceptions = $this->getStringProperty('exceptions'); - } catch (\OutOfBoundsException $e) { - $exceptions = ''; - } - - return explode(',', $exceptions); + return explode(',', $this->getStringProperty('exceptions', '')); } } From 86464a6de895b6e58dc49a12e6efacb74a2a180c Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Fri, 22 May 2020 00:14:00 +0200 Subject: [PATCH 069/218] #580 Use ->isInstanceOf instead of instanceof --- src/main/php/PHPMD/Rule/UnusedLocalVariable.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/Rule/UnusedLocalVariable.php b/src/main/php/PHPMD/Rule/UnusedLocalVariable.php index 175761eb3..bf431ed09 100644 --- a/src/main/php/PHPMD/Rule/UnusedLocalVariable.php +++ b/src/main/php/PHPMD/Rule/UnusedLocalVariable.php @@ -17,7 +17,6 @@ namespace PHPMD\Rule; -use PDepend\Source\AST\ASTFormalParameter; use PHPMD\AbstractNode; use PHPMD\Node\AbstractCallableNode; use PHPMD\Node\ASTNode; @@ -199,8 +198,10 @@ protected function doCheckNodeImage(ASTNode $node) return; } + $parent = $node->getParent(); + // ASTFormalParameter should be handled by the UnusedFormalParameter rule - if ($this->getNode($node->getParent()) instanceof ASTFormalParameter) { + if ($parent && $parent->isInstanceOf('FormalParameter')) { return; } From 1219a0e1091d05255aa6dd62cef30c86e43da23d Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Fri, 22 May 2020 17:13:58 +0200 Subject: [PATCH 070/218] Prepare a changelog for version 2.9.0 --- CHANGELOG | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 6a10a8458..a75bd01a3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,29 @@ +phpmd-2.9.0 (2020/05/25) +======================== + +- Added #496: Add rule for PHP's @ operator +- Added #737: Allowing custom exclusion for StaticAccess by extending the class +- Added #749: Add allow-underscore option for CamelCaseParameterName & CamelCaseVariableName +- Added #747: Long variable subtract suffix +- Fixed #743: Output for version +- Fixed #754: Fix #720 undefined variable in foreach when passed by reference +- Fixed #764: Fix #718 Handle anonymous class in "undefined variable" rule +- Fixed #770: Fix #769 Handle deconstruction assignation for undefined variable +- Fixed #781: Fix #714 static:: and self:: properties access +- Fixed #784: Fix #672 Handle passing-by-reference in native PHP functions +- Updated different parts of the documentation. #717 #736 #748 +- Changed: #529 : Replaced HTML renderer with new "pretty HTML" renderer +- Changed: Internal code improvement #750 #752 #756 #757 #758 #759 #768 #773 #775 #785 #787 +- Deprecated all the PHPMD exceptions that aren't part of the PHPMD\Exceptions namespace. See #775 + +### A potential BC change: +With the clean-up in #768 we have a potential BC break in an unsupported part that we want to give attention for. +> The class aliases ``PHP_PMD_*`` used for PHPMD 1.x backwards PEAR compatibility were removed. If you happen to still depend on these, please adjust your code like so: +> +> From ``PHP_PMD_[Component]_[Class]'`` to ``PHPMD\[Component]\[Class]``, +> as in ``PHP_PMD_Renderer_HTMLRenderer'`` to ``PHPMD\Renderer\HTMLRenderer``. +See #768 + phpmd-2.8.2 (2020/02/24) ======================== From 1f21bc0901ae6d2f0c34cc4c7550d815b5cd1e1d Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Sat, 23 May 2020 12:13:43 +0200 Subject: [PATCH 071/218] Chunk the composition of violation failure messages --- src/test/php/PHPMD/AbstractTest.php | 71 +++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 70a061541..b2ba7f698 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -38,6 +38,7 @@ use PHPUnit_Framework_MockObject_MockBuilder; use PHPUnit_Framework_MockObject_MockObject; use ReflectionProperty; +use Traversable; /** * Abstract base class for PHPMD test cases. @@ -252,32 +253,62 @@ protected function expectRuleHasViolationsForFile(Rule $rule, $expectedInvokes, if (!$assertion) { throw new PHPUnit_Framework_ExpectationFailedException( - basename($file)." failed:\n". - "Expected $expectedInvokes violation".($expectedInvokes !== 1 ? 's' : '')."\n". - "But $actualInvokes violation".($actualInvokes !== 1 ? 's' : '')." raised". - ($actualInvokes > 0 - ? ":\n".implode("\n", array_map(function (RuleViolation $violation) { - $nodeExtractor = new ReflectionProperty('PHPMD\\RuleViolation', 'node'); - $nodeExtractor->setAccessible(true); - $node = $nodeExtractor->getValue($violation); - $node = $node ? $node->getNode() : null; - $message = ' - line '.$violation->getBeginLine(); - - if ($node) { - $type = preg_replace('/^PDepend\\\\Source\\\\AST\\\\AST/', '', get_class($node)); - $message .= ' on '.$type.' '.$node->getImage(); - } - - return $message; - }, iterator_to_array($violations))) - : '.' - ) + $this->getViolationFailureMessage($file, $actualInvokes, $expectedInvokes, $violations) ); } $this->assertTrue($assertion); } + /** + * Return a human-friendly failure message for a given list of violations and the actual/expected counts. + * + * @param string $file + * @param int $actualInvokes + * @param int $expectedInvokes + * @param array|iterable|Traversable $violations + * + * @return string + */ + protected function getViolationFailureMessage($file, $actualInvokes, $expectedInvokes, $violations) + { + return basename($file)." failed:\n". + "Expected $expectedInvokes violation".($expectedInvokes !== 1 ? 's' : '')."\n". + "But $actualInvokes violation".($actualInvokes !== 1 ? 's' : '')." raised". + ($actualInvokes > 0 + ? ":\n".$this->getViolationsSummary($violations) + : '.' + ); + } + + /** + * Return a human-friendly summary for a list of violations. + * + * @param array|iterable|Traversable $violations + * @return string + */ + protected function getViolationsSummary($violations) + { + if (!is_array($violations)) { + $violations = iterator_to_array($violations); + } + + return implode("\n", array_map(function (RuleViolation $violation) { + $nodeExtractor = new ReflectionProperty('PHPMD\\RuleViolation', 'node'); + $nodeExtractor->setAccessible(true); + $node = $nodeExtractor->getValue($violation); + $node = $node ? $node->getNode() : null; + $message = ' - line '.$violation->getBeginLine(); + + if ($node) { + $type = preg_replace('/^PDepend\\\\Source\\\\AST\\\\AST/', '', get_class($node)); + $message .= ' on '.$type.' '.$node->getImage(); + } + + return $message; + }, $violations)); + } + /** * Returns the absolute path for a test resource for the current test. * From 03bce0a05487219516aed75f7508523af5e9b374 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Sat, 23 May 2020 12:18:25 +0200 Subject: [PATCH 072/218] Reorder getViolationFailureMessage parameters --- src/test/php/PHPMD/AbstractTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index b2ba7f698..9d5ebaa1a 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -264,13 +264,13 @@ protected function expectRuleHasViolationsForFile(Rule $rule, $expectedInvokes, * Return a human-friendly failure message for a given list of violations and the actual/expected counts. * * @param string $file - * @param int $actualInvokes * @param int $expectedInvokes + * @param int $actualInvokes * @param array|iterable|Traversable $violations * * @return string */ - protected function getViolationFailureMessage($file, $actualInvokes, $expectedInvokes, $violations) + protected function getViolationFailureMessage($file, $expectedInvokes, $actualInvokes, $violations) { return basename($file)." failed:\n". "Expected $expectedInvokes violation".($expectedInvokes !== 1 ? 's' : '')."\n". From b3fae3ba7642bd479673aede7d3479bff7ecbd38 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Sat, 23 May 2020 19:57:26 +0200 Subject: [PATCH 073/218] Fix -> Fixed --- CHANGELOG | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a75bd01a3..682525d1c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,11 +6,11 @@ phpmd-2.9.0 (2020/05/25) - Added #749: Add allow-underscore option for CamelCaseParameterName & CamelCaseVariableName - Added #747: Long variable subtract suffix - Fixed #743: Output for version -- Fixed #754: Fix #720 undefined variable in foreach when passed by reference -- Fixed #764: Fix #718 Handle anonymous class in "undefined variable" rule -- Fixed #770: Fix #769 Handle deconstruction assignation for undefined variable -- Fixed #781: Fix #714 static:: and self:: properties access -- Fixed #784: Fix #672 Handle passing-by-reference in native PHP functions +- Fixed #754: Fixed #720 undefined variable in foreach when passed by reference +- Fixed #764: Fixed #718 Handle anonymous class in "undefined variable" rule +- Fixed #770: Fixed #769 Handle deconstruction assignation for undefined variable +- Fixed #781: Fixed #714 static:: and self:: properties access +- Fixed #784: Fixed #672 Handle passing-by-reference in native PHP functions - Updated different parts of the documentation. #717 #736 #748 - Changed: #529 : Replaced HTML renderer with new "pretty HTML" renderer - Changed: Internal code improvement #750 #752 #756 #757 #758 #759 #768 #773 #775 #785 #787 From 6dc024f59dea92f6e5fc45706f8a7a67bc2e550a Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 11 Jun 2020 13:11:10 +0200 Subject: [PATCH 074/218] Remove UnusedLocalVariable property customization Don't set the allow-unused-foreach-variables for the declared-twice test which does not need it. Co-authored-by: Mathias STRASSER --- src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php b/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php index d07a677c6..54e79a0ab 100644 --- a/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php +++ b/src/test/php/PHPMD/Rule/UnusedLocalVariableTest.php @@ -48,7 +48,6 @@ public function testRuleAppliesToUnusedLocalVariable() public function testRuleAppliesToUnusedLocalVariableDeclaredTwice() { $rule = new UnusedLocalVariable(); - $rule->addProperty('allow-unused-foreach-variables', 'false'); $rule->setReport($this->getReportWithOneViolation()); $rule->apply($this->getMethod()); } From 4849c8ed08847ca0e8d1e4bdba803eba08c97809 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Thu, 11 Jun 2020 19:34:16 +0200 Subject: [PATCH 075/218] #540 Add PHPDoc for containsUsages() method --- src/main/php/PHPMD/Rule/UnusedLocalVariable.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/php/PHPMD/Rule/UnusedLocalVariable.php b/src/main/php/PHPMD/Rule/UnusedLocalVariable.php index 7a1302344..194236e4a 100644 --- a/src/main/php/PHPMD/Rule/UnusedLocalVariable.php +++ b/src/main/php/PHPMD/Rule/UnusedLocalVariable.php @@ -56,6 +56,13 @@ public function apply(AbstractNode $node) } } + /** + * Return true if one of the passed nodes contains variables usages. + * + * @param array $nodes + * + * @return bool + */ private function containsUsages(array $nodes) { if (count($nodes) === 1) { From fc816ad5903cab3a294de339057f291bcdcfc5d0 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Sat, 20 Jun 2020 14:35:03 +0200 Subject: [PATCH 076/218] #739 Upgrade minimum version of PDepend --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3d9e796f6..557fd87f6 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "minimum-stability": "stable", "require": { "php": ">=5.3.9", - "pdepend/pdepend": "^2.7.1", + "pdepend/pdepend": "^2.8.0", "ext-xml": "*", "composer/xdebug-handler": "^1.0" }, From 0b1d9b60f9b8290d02d80dfb6bc7a77171a141dd Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Sat, 20 Jun 2020 15:01:24 +0200 Subject: [PATCH 077/218] #739 Shorten variable name numberOfPublicMethods > publicMethodsCount --- src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php b/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php index 2a6d6a5df..1f43f70c4 100644 --- a/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php +++ b/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php @@ -46,9 +46,9 @@ public function apply(AbstractNode $node) $this->ignoreRegexp = $this->getStringProperty('ignorepattern'); $threshold = $this->getIntProperty('maxmethods'); - $numberOfPublicMethods = $node->getMetric('npm'); + $publicMethodsCount = $node->getMetric('npm'); // NPM stands for Number of Public Methods - if ($numberOfPublicMethods !== null && $numberOfPublicMethods <= $threshold) { + if ($publicMethodsCount !== null && $publicMethodsCount <= $threshold) { return; } From 1fcf0464c741844ccd37d44b630758bb9eecb86f Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Tue, 21 Jul 2020 22:35:28 +0200 Subject: [PATCH 078/218] Add a test to show the error in https://github.com/phpmd/phpmd/issues/802 --- .../testRuleDoesNotApplyToNestedArrays.php | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToNestedArrays.php diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToNestedArrays.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToNestedArrays.php new file mode 100644 index 000000000..7d68f426b --- /dev/null +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToNestedArrays.php @@ -0,0 +1,26 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleDoesNotApplyToNestedArrays +{ + function testRuleDoesNotApplyToNestedArrays() + { + $foo = 'foo'; + $arr = array(); + $arr[$foo]['bar']['baz'] = 'yes'; + } +} From 1a83f26f5f5c99071304b9bbddd0a35f2df6032f Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Tue, 21 Jul 2020 22:44:22 +0200 Subject: [PATCH 079/218] Check if the base is an instance of ASTNode before calling the getNode function --- src/main/php/PHPMD/Rule/AbstractLocalVariable.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php index 1544e534b..428e14970 100644 --- a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php +++ b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php @@ -211,7 +211,11 @@ protected function getVariableImage($variable) $base = $variable; $parent = $this->getNode($variable->getParent()); - while ($parent && $parent instanceof ASTArrayIndexExpression && $parent->getChild(0) === $base->getNode()) { + while ($parent && + $parent instanceof ASTArrayIndexExpression && + $base instanceof ASTNode && + $parent->getChild(0) === $base->getNode() + ) { $base = $parent; $parent = $this->getNode($base->getParent()); } From 814b51b3bd69cf08ddbe3495df017e1f8c319967 Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 22 Jul 2020 08:13:30 +0200 Subject: [PATCH 080/218] Mention #765 in the changelog --- CHANGELOG | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 682525d1c..c81883e1f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,11 @@ -phpmd-2.9.0 (2020/05/25) +phpmd-2.9.0 (2020/07/23) ======================== -- Added #496: Add rule for PHP's @ operator -- Added #737: Allowing custom exclusion for StaticAccess by extending the class -- Added #749: Add allow-underscore option for CamelCaseParameterName & CamelCaseVariableName +- Added #496: Added rule for PHP's @ operator +- Added #737: Allowed custom exclusion for StaticAccess by extending the class +- Added #749: Added allow-underscore option for CamelCaseParameterName & CamelCaseVariableName - Added #747: Long variable subtract suffix +- Added #763 via #765: Added rules LongClassName and ShortClassName - Fixed #743: Output for version - Fixed #754: Fixed #720 undefined variable in foreach when passed by reference - Fixed #764: Fixed #718 Handle anonymous class in "undefined variable" rule From 1b950d78c0c8f74dffb9fec6cdcf6bfa9ad8163e Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Wed, 22 Jul 2020 14:15:14 +0300 Subject: [PATCH 081/218] Private methods are changed to protected in basic rules --- .../php/PHPMD/Rule/UnusedFormalParameter.php | 24 +++++++++---------- .../php/PHPMD/Rule/UnusedLocalVariable.php | 24 +++++++++---------- .../php/PHPMD/Rule/UnusedPrivateField.php | 12 +++++----- .../php/PHPMD/Rule/UnusedPrivateMethod.php | 10 ++++---- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/main/php/PHPMD/Rule/UnusedFormalParameter.php b/src/main/php/PHPMD/Rule/UnusedFormalParameter.php index a9e227eac..655eb5acf 100644 --- a/src/main/php/PHPMD/Rule/UnusedFormalParameter.php +++ b/src/main/php/PHPMD/Rule/UnusedFormalParameter.php @@ -32,7 +32,7 @@ class UnusedFormalParameter extends AbstractLocalVariable implements FunctionAwa * * @var \PHPMD\Node\ASTNode[] */ - private $nodes = array(); + protected $nodes = []; /** * This method checks that all parameters of a given function or method are @@ -60,7 +60,7 @@ public function apply(AbstractNode $node) return; } - $this->nodes = array(); + $this->nodes = []; $this->collectParameters($node); $this->removeUsedParameters($node); @@ -76,7 +76,7 @@ public function apply(AbstractNode $node) * @param \PHPMD\AbstractNode $node * @return boolean */ - private function isAbstractMethod(AbstractNode $node) + protected function isAbstractMethod(AbstractNode $node) { if ($node instanceof MethodNode) { return $node->isAbstract(); @@ -92,7 +92,7 @@ private function isAbstractMethod(AbstractNode $node) * @param \PHPMD\AbstractNode $node * @return boolean */ - private function isInheritedSignature(AbstractNode $node) + protected function isInheritedSignature(AbstractNode $node) { if ($node instanceof MethodNode) { return preg_match('/@inheritdoc/i', $node->getDocComment()) === 1; @@ -107,7 +107,7 @@ private function isInheritedSignature(AbstractNode $node) * @param AbstractNode $node * @return boolean */ - private function isMagicMethod(AbstractNode $node) + protected function isMagicMethod(AbstractNode $node) { if (!($node instanceof MethodNode)) { return false; @@ -138,7 +138,7 @@ private function isMagicMethod(AbstractNode $node) * @return boolean * @since 1.2.1 */ - private function isNotDeclaration(AbstractNode $node) + protected function isNotDeclaration(AbstractNode $node) { if ($node instanceof MethodNode) { return !$node->isDeclaration(); @@ -154,7 +154,7 @@ private function isNotDeclaration(AbstractNode $node) * @param \PHPMD\AbstractNode $node * @return void */ - private function collectParameters(AbstractNode $node) + protected function collectParameters(AbstractNode $node) { // First collect the formal parameters containers foreach ($node->findChildrenOfType('FormalParameters') as $parameters) { @@ -175,7 +175,7 @@ private function collectParameters(AbstractNode $node) * @param \PHPMD\AbstractNode $node * @return void */ - private function removeUsedParameters(AbstractNode $node) + protected function removeUsedParameters(AbstractNode $node) { $this->removeRegularVariables($node); $this->removeCompoundVariables($node); @@ -188,7 +188,7 @@ private function removeUsedParameters(AbstractNode $node) * @param \PHPMD\AbstractNode $node The node to remove the regular variables from. * @return void */ - private function removeRegularVariables(AbstractNode $node) + protected function removeRegularVariables(AbstractNode $node) { $variables = $node->findChildrenOfType('Variable'); @@ -218,7 +218,7 @@ private function removeRegularVariables(AbstractNode $node) * @param \PHPMD\AbstractNode $node The node to remove the compound variables from. * @return void */ - private function removeCompoundVariables(AbstractNode $node) + protected function removeCompoundVariables(AbstractNode $node) { $compoundVariables = $node->findChildrenOfType('CompoundVariable'); @@ -243,13 +243,13 @@ private function removeCompoundVariables(AbstractNode $node) * @param \PHPMD\AbstractNode $node The node to remove the referneced variables from. * @return void */ - private function removeVariablesUsedByFuncGetArgs(AbstractNode $node) + protected function removeVariablesUsedByFuncGetArgs(AbstractNode $node) { $functionCalls = $node->findChildrenOfType('FunctionPostfix'); foreach ($functionCalls as $functionCall) { if ($this->isFunctionNameEqual($functionCall, 'func_get_args')) { - $this->nodes = array(); + $this->nodes = []; } if ($this->isFunctionNameEndingWith($functionCall, 'compact')) { diff --git a/src/main/php/PHPMD/Rule/UnusedLocalVariable.php b/src/main/php/PHPMD/Rule/UnusedLocalVariable.php index a6569ebfc..491474dd0 100644 --- a/src/main/php/PHPMD/Rule/UnusedLocalVariable.php +++ b/src/main/php/PHPMD/Rule/UnusedLocalVariable.php @@ -32,7 +32,7 @@ class UnusedLocalVariable extends AbstractLocalVariable implements FunctionAware * * @var array(string) */ - private $images = array(); + protected $images = array(); /** * This method checks that all local variables within the given function or @@ -63,7 +63,7 @@ public function apply(AbstractNode $node) * * @return bool */ - private function containsUsages(array $nodes) + protected function containsUsages(array $nodes) { if (count($nodes) === 1) { return false; @@ -92,7 +92,7 @@ private function containsUsages(array $nodes) * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ - private function removeParameters(AbstractCallableNode $node) + protected function removeParameters(AbstractCallableNode $node) { // Get formal parameter container $parameters = $node->getFirstChildOfType('FormalParameters'); @@ -114,7 +114,7 @@ private function removeParameters(AbstractCallableNode $node) * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ - private function collectVariables(AbstractCallableNode $node) + protected function collectVariables(AbstractCallableNode $node) { foreach ($node->findChildrenOfType('Variable') as $variable) { /** @var $variable ASTNode */ @@ -147,7 +147,7 @@ private function collectVariables(AbstractCallableNode $node) * @param \PHPMD\Node\ASTNode $node * @return void */ - private function collectCompoundVariableInString(ASTNode $node) + protected function collectCompoundVariableInString(ASTNode $node) { $parentNode = $node->getParent()->getNode(); $candidateParentNodes = $node->getParentsOfType('PDepend\Source\AST\ASTString'); @@ -170,7 +170,7 @@ private function collectCompoundVariableInString(ASTNode $node) * @param \PHPMD\Node\ASTNode $node * @return void */ - private function collectVariable(ASTNode $node) + protected function collectVariable(ASTNode $node) { $imageName = $node->getImage(); $this->storeImage($imageName, $node); @@ -183,7 +183,7 @@ private function collectVariable(ASTNode $node) * @param \PHPMD\Node\ASTNode $node the node being stored * @return void */ - private function storeImage($imageName, ASTNode $node) + protected function storeImage($imageName, ASTNode $node) { if (!isset($this->images[$imageName])) { $this->images[$imageName] = array(); @@ -198,7 +198,7 @@ private function storeImage($imageName, ASTNode $node) * @param \PHPMD\Node\ASTNode $node * @return void */ - private function collectLiteral(ASTNode $node) + protected function collectLiteral(ASTNode $node) { $variable = '$' . trim($node->getImage(), '\''); @@ -247,7 +247,7 @@ protected function doCheckNodeImage(ASTNode $node) * @param \PHPMD\AbstractNode $node * @return boolean */ - private function isNameAllowedInContext(AbstractNode $node) + protected function isNameAllowedInContext(AbstractNode $node) { return $this->isChildOf($node, 'CatchStatement'); } @@ -260,7 +260,7 @@ private function isNameAllowedInContext(AbstractNode $node) * @param \PHPMD\Node\ASTNode $variable The variable to check. * @return bool True if allowed, else false. */ - private function isUnusedForeachVariableAllowed(ASTNode $variable) + protected function isUnusedForeachVariableAllowed(ASTNode $variable) { $isForeachVariable = $this->isChildOf($variable, 'ForeachStatement'); @@ -279,7 +279,7 @@ private function isUnusedForeachVariableAllowed(ASTNode $variable) * @param string $type * @return boolean */ - private function isChildOf(AbstractNode $node, $type) + protected function isChildOf(AbstractNode $node, $type) { $parent = $node->getParent(); @@ -291,7 +291,7 @@ private function isChildOf(AbstractNode $node, $type) * * @return array */ - private function getExceptionsList() + protected function getExceptionsList() { return explode(',', $this->getStringProperty('exceptions', '')); } diff --git a/src/main/php/PHPMD/Rule/UnusedPrivateField.php b/src/main/php/PHPMD/Rule/UnusedPrivateField.php index a530f5d18..8f591fae9 100644 --- a/src/main/php/PHPMD/Rule/UnusedPrivateField.php +++ b/src/main/php/PHPMD/Rule/UnusedPrivateField.php @@ -34,7 +34,7 @@ class UnusedPrivateField extends AbstractRule implements ClassAware * * @var \PHPMD\Node\ASTNode[] */ - private $fields = array(); + protected $fields = array(); /** * This method checks that all private class properties are at least accessed @@ -58,7 +58,7 @@ public function apply(AbstractNode $node) * @param \PHPMD\Node\ClassNode $class * @return \PHPMD\AbstractNode[] */ - private function collectUnusedPrivateFields(ClassNode $class) + protected function collectUnusedPrivateFields(ClassNode $class) { $this->fields = array(); @@ -75,7 +75,7 @@ private function collectUnusedPrivateFields(ClassNode $class) * @param \PHPMD\Node\ClassNode $class * @return void */ - private function collectPrivateFields(ClassNode $class) + protected function collectPrivateFields(ClassNode $class) { foreach ($class->findChildrenOfType('FieldDeclaration') as $declaration) { /** @var ASTNode $declaration */ @@ -92,7 +92,7 @@ private function collectPrivateFields(ClassNode $class) * @param \PHPMD\Node\ASTNode $declaration * @return void */ - private function collectPrivateField(ASTNode $declaration) + protected function collectPrivateField(ASTNode $declaration) { $fields = $declaration->findChildrenOfType('VariableDeclarator'); foreach ($fields as $field) { @@ -108,7 +108,7 @@ private function collectPrivateField(ASTNode $declaration) * @param \PHPMD\Node\ClassNode $class * @return void */ - private function removeUsedFields(ClassNode $class) + protected function removeUsedFields(ClassNode $class) { foreach ($class->findChildrenOfType('PropertyPostfix') as $postfix) { /** @var $postfix ASTNode */ @@ -125,7 +125,7 @@ private function removeUsedFields(ClassNode $class) * @param \PHPMD\Node\ASTNode $postfix * @return void */ - private function removeUsedField(ASTNode $postfix) + protected function removeUsedField(ASTNode $postfix) { $image = '$'; $child = $postfix->getFirstChildOfType('Identifier'); diff --git a/src/main/php/PHPMD/Rule/UnusedPrivateMethod.php b/src/main/php/PHPMD/Rule/UnusedPrivateMethod.php index 673531e12..f257e8a2a 100644 --- a/src/main/php/PHPMD/Rule/UnusedPrivateMethod.php +++ b/src/main/php/PHPMD/Rule/UnusedPrivateMethod.php @@ -52,7 +52,7 @@ public function apply(AbstractNode $class) * @param ClassNode $class * @return ASTMethodPostfix[] */ - private function collectUnusedPrivateMethods(ClassNode $class) + protected function collectUnusedPrivateMethods(ClassNode $class) { $methods = $this->collectPrivateMethods($class); @@ -65,7 +65,7 @@ private function collectUnusedPrivateMethods(ClassNode $class) * @param ClassNode $class * @return AbstractNode[] */ - private function collectPrivateMethods(ClassNode $class) + protected function collectPrivateMethods(ClassNode $class) { $methods = array(); @@ -86,7 +86,7 @@ private function collectPrivateMethods(ClassNode $class) * @param MethodNode $method * @return boolean */ - private function acceptMethod(ClassNode $class, MethodNode $method) + protected function acceptMethod(ClassNode $class, MethodNode $method) { return ( $method->isPrivate() && @@ -105,7 +105,7 @@ private function acceptMethod(ClassNode $class, MethodNode $method) * @param MethodNode[] $methods * @return ASTMethodPostfix[] */ - private function removeUsedMethods(ClassNode $class, array $methods) + protected function removeUsedMethods(ClassNode $class, array $methods) { foreach ($class->findChildrenOfType('MethodPostfix') as $postfix) { /** @var $postfix ASTNode */ @@ -125,7 +125,7 @@ private function removeUsedMethods(ClassNode $class, array $methods) * @param ASTNode $postfix * @return boolean */ - private function isClassScope(ClassNode $class, ASTNode $postfix) + protected function isClassScope(ClassNode $class, ASTNode $postfix) { $owner = $postfix->getParent()->getChild(0); From d0c022e141ee63c2bb808d5908270392ba57da47 Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Wed, 22 Jul 2020 14:18:24 +0300 Subject: [PATCH 082/218] Private methods are switched to protected in CleanCode rules --- .../Rule/CleanCode/BooleanArgumentFlag.php | 2 +- .../Rule/CleanCode/DuplicatedArrayKey.php | 6 ++-- .../PHPMD/Rule/CleanCode/ElseExpression.php | 4 +-- .../Rule/CleanCode/IfStatementAssignment.php | 8 +++--- .../php/PHPMD/Rule/CleanCode/StaticAccess.php | 8 +++--- .../Rule/CleanCode/UndefinedVariable.php | 28 +++++++++---------- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/main/php/PHPMD/Rule/CleanCode/BooleanArgumentFlag.php b/src/main/php/PHPMD/Rule/CleanCode/BooleanArgumentFlag.php index cc4d475c8..3bb15eb67 100644 --- a/src/main/php/PHPMD/Rule/CleanCode/BooleanArgumentFlag.php +++ b/src/main/php/PHPMD/Rule/CleanCode/BooleanArgumentFlag.php @@ -50,7 +50,7 @@ public function apply(AbstractNode $node) } } - private function isBooleanValue(ASTValue $value = null) + protected function isBooleanValue(ASTValue $value = null) { return $value && $value->isValueAvailable() && ($value->getValue() === true || $value->getValue() === false); } diff --git a/src/main/php/PHPMD/Rule/CleanCode/DuplicatedArrayKey.php b/src/main/php/PHPMD/Rule/CleanCode/DuplicatedArrayKey.php index ee3d26da0..ba01bb2dc 100644 --- a/src/main/php/PHPMD/Rule/CleanCode/DuplicatedArrayKey.php +++ b/src/main/php/PHPMD/Rule/CleanCode/DuplicatedArrayKey.php @@ -57,7 +57,7 @@ public function apply(AbstractNode $node) * @param ASTNode $node Array node. * @return void */ - private function checkForDuplicatedArrayKeys(ASTNode $node) + protected function checkForDuplicatedArrayKeys(ASTNode $node) { $keys = array(); /** @var ASTArrayElement $arrayElement */ @@ -90,7 +90,7 @@ private function checkForDuplicatedArrayKeys(ASTNode $node) * @param int $index Fallback in case of non-associative arrays * @return AbstractASTNode Key name */ - private function normalizeKey(AbstractASTNode $node, $index) + protected function normalizeKey(AbstractASTNode $node, $index) { $childCount = count($node->getChildren()); // Skip, if there is no array key, just an array value @@ -120,7 +120,7 @@ private function normalizeKey(AbstractASTNode $node, $index) * @param PDependASTNode $key * @return string */ - private function castStringFromLiteral(PDependASTNode $key) + protected function castStringFromLiteral(PDependASTNode $key) { $value = $key->getImage(); switch ($value) { diff --git a/src/main/php/PHPMD/Rule/CleanCode/ElseExpression.php b/src/main/php/PHPMD/Rule/CleanCode/ElseExpression.php index 6ec6ac7ee..0ec65781e 100644 --- a/src/main/php/PHPMD/Rule/CleanCode/ElseExpression.php +++ b/src/main/php/PHPMD/Rule/CleanCode/ElseExpression.php @@ -62,7 +62,7 @@ public function apply(AbstractNode $node) * @param ASTNode $parent * @return bool */ - private function isElseScope(AbstractNode $scope, ASTNode $parent) + protected function isElseScope(AbstractNode $scope, ASTNode $parent) { return ( count($parent->getChildren()) === 3 && @@ -76,7 +76,7 @@ private function isElseScope(AbstractNode $scope, ASTNode $parent) * @param ASTNode $parent * @return bool */ - private function isIfOrElseIfStatement(ASTNode $parent) + protected function isIfOrElseIfStatement(ASTNode $parent) { return ($parent->getName() === "if" || $parent->getName() === "elseif"); } diff --git a/src/main/php/PHPMD/Rule/CleanCode/IfStatementAssignment.php b/src/main/php/PHPMD/Rule/CleanCode/IfStatementAssignment.php index 3b88d950a..1f0f98978 100644 --- a/src/main/php/PHPMD/Rule/CleanCode/IfStatementAssignment.php +++ b/src/main/php/PHPMD/Rule/CleanCode/IfStatementAssignment.php @@ -67,7 +67,7 @@ public function apply(AbstractNode $node) * @param AbstractNode $node An instance of MethodNode or FunctionNode class * @return ASTNode[] */ - private function getStatements(AbstractNode $node) + protected function getStatements(AbstractNode $node) { return call_user_func_array('array_merge', array_map(function ($type) use ($node) { return $node->findChildrenOfType($type); @@ -80,7 +80,7 @@ private function getStatements(AbstractNode $node) * @param ASTNode[] $statements Array of if and elseif clauses * @return ASTExpression[] */ - private function getExpressions(array $statements) + protected function getExpressions(array $statements) { return array_map(function (ASTNode $statement) { return $statement->getFirstChildOfType('Expression'); @@ -93,7 +93,7 @@ private function getExpressions(array $statements) * @param ASTExpression[] $expressions Array of expressions * @return ASTAssignmentExpression[] */ - private function getAssignments(array $expressions) + protected function getAssignments(array $expressions) { $assignments = array(); /** @var ASTNode $expression */ @@ -110,7 +110,7 @@ private function getAssignments(array $expressions) * @param AbstractNode $node An instance of MethodNode or FunctionNode class * @param ASTAssignmentExpression[] $assignments Array of assignments */ - private function addViolations(AbstractNode $node, array $assignments) + protected function addViolations(AbstractNode $node, array $assignments) { $processesViolations = array(); /** @var \PDepend\Source\AST\AbstractASTNode $assignment */ diff --git a/src/main/php/PHPMD/Rule/CleanCode/StaticAccess.php b/src/main/php/PHPMD/Rule/CleanCode/StaticAccess.php index 98460f75a..154e4fe1f 100644 --- a/src/main/php/PHPMD/Rule/CleanCode/StaticAccess.php +++ b/src/main/php/PHPMD/Rule/CleanCode/StaticAccess.php @@ -64,7 +64,7 @@ protected function isExcludedFromAnalysis($className, $exceptions) return in_array(trim($className, " \t\n\r\0\x0B\\"), $exceptions); } - private function isStaticMethodCall(AbstractNode $methodCall) + protected function isStaticMethodCall(AbstractNode $methodCall) { return $methodCall->getChild(0)->getNode() instanceof ASTClassOrInterfaceReference && $methodCall->getChild(1)->getNode() instanceof ASTMethodPostfix && @@ -72,12 +72,12 @@ private function isStaticMethodCall(AbstractNode $methodCall) !$this->isCallingSelf($methodCall); } - private function isCallingParent(AbstractNode $methodCall) + protected function isCallingParent(AbstractNode $methodCall) { return $methodCall->getChild(0)->getNode() instanceof ASTParentReference; } - private function isCallingSelf(AbstractNode $methodCall) + protected function isCallingSelf(AbstractNode $methodCall) { return $methodCall->getChild(0)->getNode() instanceof ASTSelfReference; } @@ -87,7 +87,7 @@ private function isCallingSelf(AbstractNode $methodCall) * * @return array */ - private function getExceptionsList() + protected function getExceptionsList() { try { $exceptions = $this->getStringProperty('exceptions'); diff --git a/src/main/php/PHPMD/Rule/CleanCode/UndefinedVariable.php b/src/main/php/PHPMD/Rule/CleanCode/UndefinedVariable.php index c108c4e96..510e0c2df 100644 --- a/src/main/php/PHPMD/Rule/CleanCode/UndefinedVariable.php +++ b/src/main/php/PHPMD/Rule/CleanCode/UndefinedVariable.php @@ -43,7 +43,7 @@ class UndefinedVariable extends AbstractLocalVariable implements FunctionAware, * * @var array(string) */ - private $images = array(); + protected $images = array(); /** * This method checks that all local variables within the given function or @@ -88,7 +88,7 @@ public function apply(AbstractNode $node) * * @param AbstractNode $node */ - private function collect(AbstractNode $node) + protected function collect(AbstractNode $node) { $this->collectPropertyPostfix($node); $this->collectClosureParameters($node); @@ -100,7 +100,7 @@ private function collect(AbstractNode $node) $this->collectGlobalStatements($node); } - private function collectProperties($node) + protected function collectProperties($node) { if (!($node instanceof ASTClass)) { return; @@ -119,7 +119,7 @@ private function collectProperties($node) * @param \PHPMD\Node\AbstractNode $node * @return void */ - private function collectGlobalStatements(AbstractNode $node) + protected function collectGlobalStatements(AbstractNode $node) { $globalStatements = $node->findChildrenOfType('GlobalStatement'); @@ -136,7 +136,7 @@ private function collectGlobalStatements(AbstractNode $node) * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ - private function collectExceptionCatches(AbstractCallableNode $node) + protected function collectExceptionCatches(AbstractCallableNode $node) { $catchStatements = $node->findChildrenOfType('CatchStatement'); @@ -155,7 +155,7 @@ private function collectExceptionCatches(AbstractCallableNode $node) * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ - private function collectListExpressions(AbstractCallableNode $node) + protected function collectListExpressions(AbstractCallableNode $node) { $lists = $node->findChildrenOfType('ListExpression'); @@ -172,7 +172,7 @@ private function collectListExpressions(AbstractCallableNode $node) * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ - private function collectForeachStatements(AbstractCallableNode $node) + protected function collectForeachStatements(AbstractCallableNode $node) { $foreachStatements = $node->findChildrenOfType('ForeachStatement'); @@ -197,7 +197,7 @@ private function collectForeachStatements(AbstractCallableNode $node) * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ - private function collectClosureParameters(AbstractCallableNode $node) + protected function collectClosureParameters(AbstractCallableNode $node) { $closures = $node->findChildrenOfType('Closure'); @@ -213,7 +213,7 @@ private function collectClosureParameters(AbstractCallableNode $node) * @param \PHPMD\Node\AbstractCallableNode $parentNode * @return bool */ - private function checkVariableDefined(ASTNode $variable, AbstractCallableNode $parentNode) + protected function checkVariableDefined(ASTNode $variable, AbstractCallableNode $parentNode) { $image = $this->getVariableImage($variable); @@ -226,7 +226,7 @@ private function checkVariableDefined(ASTNode $variable, AbstractCallableNode $p * @param \PHPMD\Node\AbstractNode $node * @return void */ - private function collectParameters(AbstractNode $node) + protected function collectParameters(AbstractNode $node) { // Get formal parameter container $parameters = $node->getFirstChildOfType('FormalParameters'); @@ -245,7 +245,7 @@ private function collectParameters(AbstractNode $node) * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ - private function collectAssignments(AbstractCallableNode $node) + protected function collectAssignments(AbstractCallableNode $node) { foreach ($node->findChildrenOfType('AssignmentExpression') as $assignment) { $variable = $assignment->getChild(0); @@ -268,7 +268,7 @@ private function collectAssignments(AbstractCallableNode $node) * @param \PHPMD\Node\AbstractNode $node * @return void */ - private function collectPropertyPostfix(AbstractNode $node) + protected function collectPropertyPostfix(AbstractNode $node) { $properties = $node->findChildrenOfType('PropertyPostfix'); @@ -287,7 +287,7 @@ private function collectPropertyPostfix(AbstractNode $node) * @param ASTVariable|ASTPropertyPostfix|ASTVariableDeclarator $variable * @return void */ - private function addVariableDefinition($variable) + protected function addVariableDefinition($variable) { $image = $this->getVariableImage($variable); @@ -304,7 +304,7 @@ private function addVariableDefinition($variable) * * @return boolean */ - private function isNameAllowedInContext(AbstractCallableNode $node, ASTNode $variable) + protected function isNameAllowedInContext(AbstractCallableNode $node, ASTNode $variable) { return ( $node instanceof MethodNode && From f57e0d17ad941fa93b5882e75d4a2781b5674a13 Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Wed, 22 Jul 2020 16:38:49 +0300 Subject: [PATCH 083/218] Private methods are switched to protected in Controversial rules --- src/main/php/PHPMD/Rule/AbstractLocalVariable.php | 2 +- src/main/php/PHPMD/Rule/Controversial/CamelCaseMethodName.php | 2 +- .../php/PHPMD/Rule/Controversial/CamelCaseParameterName.php | 2 +- .../php/PHPMD/Rule/Controversial/CamelCaseVariableName.php | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php index 1544e534b..5620cca2c 100644 --- a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php +++ b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php @@ -48,7 +48,7 @@ abstract class AbstractLocalVariable extends AbstractRule * @var array(string=>boolean) * @link http://php.net/manual/en/reserved.variables.php */ - private static $superGlobals = array( + protected static $superGlobals = array( '$argc' => true, '$argv' => true, '$_COOKIE' => true, diff --git a/src/main/php/PHPMD/Rule/Controversial/CamelCaseMethodName.php b/src/main/php/PHPMD/Rule/Controversial/CamelCaseMethodName.php index 5ddc1ee6d..9ea6cf67e 100644 --- a/src/main/php/PHPMD/Rule/Controversial/CamelCaseMethodName.php +++ b/src/main/php/PHPMD/Rule/Controversial/CamelCaseMethodName.php @@ -71,7 +71,7 @@ public function apply(AbstractNode $node) } } - private function isValid($methodName) + protected function isValid($methodName) { if ($this->getBooleanProperty('allow-underscore-test') && strpos($methodName, 'test') === 0) { return preg_match('/^test[a-zA-Z0-9]*([_][a-z][a-zA-Z0-9]*)?$/', $methodName); diff --git a/src/main/php/PHPMD/Rule/Controversial/CamelCaseParameterName.php b/src/main/php/PHPMD/Rule/Controversial/CamelCaseParameterName.php index ca9fe3a7b..20b64060f 100644 --- a/src/main/php/PHPMD/Rule/Controversial/CamelCaseParameterName.php +++ b/src/main/php/PHPMD/Rule/Controversial/CamelCaseParameterName.php @@ -51,7 +51,7 @@ public function apply(AbstractNode $node) } } - private function isValid($parameterName) + protected function isValid($parameterName) { if ($this->getBooleanProperty('allow-underscore')) { return preg_match('/^\$[_]?[a-z][a-zA-Z0-9]*$/', $parameterName); diff --git a/src/main/php/PHPMD/Rule/Controversial/CamelCaseVariableName.php b/src/main/php/PHPMD/Rule/Controversial/CamelCaseVariableName.php index 8cc972aef..620711f0b 100644 --- a/src/main/php/PHPMD/Rule/Controversial/CamelCaseVariableName.php +++ b/src/main/php/PHPMD/Rule/Controversial/CamelCaseVariableName.php @@ -33,7 +33,7 @@ class CamelCaseVariableName extends AbstractRule implements MethodAware, Functio /** * @var array */ - private $exceptions = array( + protected $exceptions = array( '$php_errormsg', '$http_response_header', '$GLOBALS', @@ -68,7 +68,7 @@ public function apply(AbstractNode $node) } } - private function isValid($variable) + protected function isValid($variable) { $image = $variable->getImage(); From b94ae6946e05a2b26f889e50d7b0ed893f08be0c Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Wed, 22 Jul 2020 16:40:47 +0300 Subject: [PATCH 084/218] Private methods are switched to protected in Design rules --- src/main/php/PHPMD/Rule/Design/CountInLoopExpression.php | 2 +- src/main/php/PHPMD/Rule/Design/DevelopmentCodeFragment.php | 2 +- src/main/php/PHPMD/Rule/Design/TooManyMethods.php | 4 ++-- src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Design/CountInLoopExpression.php b/src/main/php/PHPMD/Rule/Design/CountInLoopExpression.php index 5a2744c6c..2c6fdc705 100644 --- a/src/main/php/PHPMD/Rule/Design/CountInLoopExpression.php +++ b/src/main/php/PHPMD/Rule/Design/CountInLoopExpression.php @@ -44,7 +44,7 @@ class CountInLoopExpression extends AbstractRule implements ClassAware * * @var array */ - private $unwantedFunctions = array('count', 'sizeof'); + protected $unwantedFunctions = array('count', 'sizeof'); /** * List of already processed functions diff --git a/src/main/php/PHPMD/Rule/Design/DevelopmentCodeFragment.php b/src/main/php/PHPMD/Rule/Design/DevelopmentCodeFragment.php index 0c183f4ab..b0dc507d5 100644 --- a/src/main/php/PHPMD/Rule/Design/DevelopmentCodeFragment.php +++ b/src/main/php/PHPMD/Rule/Design/DevelopmentCodeFragment.php @@ -68,7 +68,7 @@ public function apply(AbstractNode $node) * * @return array */ - private function getSuspectImages() + protected function getSuspectImages() { return array_map( 'strtolower', diff --git a/src/main/php/PHPMD/Rule/Design/TooManyMethods.php b/src/main/php/PHPMD/Rule/Design/TooManyMethods.php index 7a4c8d4f7..e33d32986 100644 --- a/src/main/php/PHPMD/Rule/Design/TooManyMethods.php +++ b/src/main/php/PHPMD/Rule/Design/TooManyMethods.php @@ -32,7 +32,7 @@ class TooManyMethods extends AbstractRule implements ClassAware * * @var string */ - private $ignoreRegexp; + protected $ignoreRegexp; /** * This method checks the number of methods with in a given class and checks @@ -71,7 +71,7 @@ public function apply(AbstractNode $node) * @param \PHPMD\Node\AbstractTypeNode $node * @return integer */ - private function countMethods(AbstractTypeNode $node) + protected function countMethods(AbstractTypeNode $node) { $count = 0; foreach ($node->getMethodNames() as $name) { diff --git a/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php b/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php index 454148045..e35179989 100644 --- a/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php +++ b/src/main/php/PHPMD/Rule/Design/TooManyPublicMethods.php @@ -32,7 +32,7 @@ class TooManyPublicMethods extends AbstractRule implements ClassAware * * @var string */ - private $ignoreRegexp; + protected $ignoreRegexp; /** * This method checks the number of public methods with in a given class and checks @@ -71,7 +71,7 @@ public function apply(AbstractNode $node) * @param \PHPMD\Node\AbstractTypeNode $node * @return integer */ - private function countMethods(AbstractTypeNode $node) + protected function countMethods(AbstractTypeNode $node) { $count = 0; foreach ($node->getMethods() as $method) { From 91a785cfdbef4453556beb2ddc675b2d242a8275 Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Wed, 22 Jul 2020 16:47:49 +0300 Subject: [PATCH 085/218] Private methods are switched to protected in Naming rules --- .../php/PHPMD/Rule/Naming/BooleanGetMethodName.php | 8 ++++---- src/main/php/PHPMD/Rule/Naming/LongClassName.php | 4 ++-- src/main/php/PHPMD/Rule/Naming/LongVariable.php | 10 +++++----- src/main/php/PHPMD/Rule/Naming/ShortClassName.php | 4 ++-- src/main/php/PHPMD/Rule/Naming/ShortMethodName.php | 2 +- src/main/php/PHPMD/Rule/Naming/ShortVariable.php | 12 ++++++------ 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/BooleanGetMethodName.php b/src/main/php/PHPMD/Rule/Naming/BooleanGetMethodName.php index 85cd65ab1..67a03ebe3 100644 --- a/src/main/php/PHPMD/Rule/Naming/BooleanGetMethodName.php +++ b/src/main/php/PHPMD/Rule/Naming/BooleanGetMethodName.php @@ -51,7 +51,7 @@ public function apply(AbstractNode $node) * @param \PHPMD\Node\MethodNode $node * @return boolean */ - private function isBooleanGetMethod(MethodNode $node) + protected function isBooleanGetMethod(MethodNode $node) { return $this->isGetterMethodName($node) && $this->isReturnTypeBoolean($node) @@ -64,7 +64,7 @@ private function isBooleanGetMethod(MethodNode $node) * @param \PHPMD\Node\MethodNode $node * @return boolean */ - private function isGetterMethodName(MethodNode $node) + protected function isGetterMethodName(MethodNode $node) { return (preg_match('(^_?get)i', $node->getImage()) > 0); } @@ -75,7 +75,7 @@ private function isGetterMethodName(MethodNode $node) * @param \PHPMD\Node\MethodNode $node * @return boolean */ - private function isReturnTypeBoolean(MethodNode $node) + protected function isReturnTypeBoolean(MethodNode $node) { $comment = $node->getDocComment(); @@ -89,7 +89,7 @@ private function isReturnTypeBoolean(MethodNode $node) * @param \PHPMD\Node\MethodNode $node * @return boolean */ - private function isParameterizedOrIgnored(MethodNode $node) + protected function isParameterizedOrIgnored(MethodNode $node) { if ($this->getBooleanProperty('checkParameterizedMethods')) { return $node->getParameterCount() === 0; diff --git a/src/main/php/PHPMD/Rule/Naming/LongClassName.php b/src/main/php/PHPMD/Rule/Naming/LongClassName.php index 504d28d07..41e352d10 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/LongClassName.php @@ -33,7 +33,7 @@ class LongClassName extends AbstractRule implements ClassAware, InterfaceAware * * @var string[]|null */ - private $subtractSuffixes; + protected $subtractSuffixes; /** * Check if a class name exceeds the configured maximum length and emit a rule violation @@ -56,7 +56,7 @@ public function apply(AbstractNode $node) * * @return string[] */ - private function getSubtractSuffixList() + protected function getSubtractSuffixList() { if ($this->subtractSuffixes === null) { $this->subtractSuffixes = Strings::splitToList( diff --git a/src/main/php/PHPMD/Rule/Naming/LongVariable.php b/src/main/php/PHPMD/Rule/Naming/LongVariable.php index 9de30ee52..159aac559 100644 --- a/src/main/php/PHPMD/Rule/Naming/LongVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/LongVariable.php @@ -35,7 +35,7 @@ class LongVariable extends AbstractRule implements ClassAware, MethodAware, Func * * @var string[]|null */ - private $subtractSuffixes; + protected $subtractSuffixes; /** * Temporary map holding variables that were already processed in the @@ -43,7 +43,7 @@ class LongVariable extends AbstractRule implements ClassAware, MethodAware, Func * * @var array(string=>boolean) */ - private $processedVariables = array(); + protected $processedVariables = array(); /** * Extracts all variable and variable declarator nodes from the given node @@ -125,7 +125,7 @@ protected function checkMaximumLength(AbstractNode $node) * @param \PHPMD\AbstractNode $node * @return boolean */ - private function isNameAllowedInContext(AbstractNode $node) + protected function isNameAllowedInContext(AbstractNode $node) { return $this->isChildOf($node, 'MemberPrimaryPrefix'); } @@ -138,7 +138,7 @@ private function isNameAllowedInContext(AbstractNode $node) * @param string $type * @return boolean */ - private function isChildOf(AbstractNode $node, $type) + protected function isChildOf(AbstractNode $node, $type) { $parent = $node->getParent(); while (is_object($parent)) { @@ -188,7 +188,7 @@ protected function isNotProcessed(AbstractNode $node) * * @return string[] */ - private function getSubtractSuffixList() + protected function getSubtractSuffixList() { if ($this->subtractSuffixes === null) { $this->subtractSuffixes = Strings::splitToList($this->getStringProperty('subtract-suffixes', ''), ','); diff --git a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php index 8a41fcd64..4d0ab8a55 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortClassName.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortClassName.php @@ -33,7 +33,7 @@ class ShortClassName extends AbstractRule implements ClassAware, InterfaceAware * * @var array|null */ - private $exceptions; + protected $exceptions; /** * Check if a class or interface name is below the minimum configured length and emit a rule violation @@ -62,7 +62,7 @@ public function apply(AbstractNode $node) * * @return array */ - private function getExceptionsList() + protected function getExceptionsList() { if ($this->exceptions === null) { $this->exceptions = array_flip( diff --git a/src/main/php/PHPMD/Rule/Naming/ShortMethodName.php b/src/main/php/PHPMD/Rule/Naming/ShortMethodName.php index 7ea95b81c..d24cb7781 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortMethodName.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortMethodName.php @@ -63,7 +63,7 @@ public function apply(AbstractNode $node) * * @return array */ - private function getExceptionsList() + protected function getExceptionsList() { try { $exceptions = $this->getStringProperty('exceptions'); diff --git a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php index d36b13361..d33b25c87 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php @@ -35,7 +35,7 @@ class ShortVariable extends AbstractRule implements ClassAware, MethodAware, Fun * * @var array(string=>boolean) */ - private $processedVariables = array(); + protected $processedVariables = array(); /** * Extracts all variable and variable declarator nodes from the given node @@ -68,7 +68,7 @@ public function apply(AbstractNode $node) * @param AbstractNode $node * @return void */ - private function applyClass(AbstractNode $node) + protected function applyClass(AbstractNode $node) { $fields = $node->findChildrenOfType('FieldDeclaration'); foreach ($fields as $field) { @@ -89,7 +89,7 @@ private function applyClass(AbstractNode $node) * @param AbstractNode $node * @return void */ - private function applyNonClass(AbstractNode $node) + protected function applyNonClass(AbstractNode $node) { $declarators = $node->findChildrenOfType('VariableDeclarator'); foreach ($declarators as $declarator) { @@ -150,7 +150,7 @@ protected function checkMinimumLength(AbstractNode $node) * * @return array */ - private function getExceptionsList() + protected function getExceptionsList() { try { $exceptions = $this->getStringProperty('exceptions'); @@ -169,7 +169,7 @@ private function getExceptionsList() * @param \PHPMD\AbstractNode $node * @return boolean */ - private function isNameAllowedInContext(AbstractNode $node) + protected function isNameAllowedInContext(AbstractNode $node) { return $this->isChildOf($node, 'CatchStatement') || $this->isChildOf($node, 'ForInit') @@ -185,7 +185,7 @@ private function isNameAllowedInContext(AbstractNode $node) * @param string $type * @return boolean */ - private function isChildOf(AbstractNode $node, $type) + protected function isChildOf(AbstractNode $node, $type) { $parent = $node->getParent(); while (is_object($parent)) { From ba9057ee593f7080e8561c039e3457d09115f666 Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Wed, 22 Jul 2020 22:23:15 +0300 Subject: [PATCH 086/218] Restoreg original array in src/main/php/PHPMD/Rule/UnusedFormalParameter.php --- src/main/php/PHPMD/Rule/UnusedFormalParameter.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/php/PHPMD/Rule/UnusedFormalParameter.php b/src/main/php/PHPMD/Rule/UnusedFormalParameter.php index 655eb5acf..2538ef959 100644 --- a/src/main/php/PHPMD/Rule/UnusedFormalParameter.php +++ b/src/main/php/PHPMD/Rule/UnusedFormalParameter.php @@ -32,7 +32,7 @@ class UnusedFormalParameter extends AbstractLocalVariable implements FunctionAwa * * @var \PHPMD\Node\ASTNode[] */ - protected $nodes = []; + protected $nodes = array(); /** * This method checks that all parameters of a given function or method are @@ -60,7 +60,7 @@ public function apply(AbstractNode $node) return; } - $this->nodes = []; + $this->nodes = array(); $this->collectParameters($node); $this->removeUsedParameters($node); @@ -249,7 +249,7 @@ protected function removeVariablesUsedByFuncGetArgs(AbstractNode $node) foreach ($functionCalls as $functionCall) { if ($this->isFunctionNameEqual($functionCall, 'func_get_args')) { - $this->nodes = []; + $this->nodes = array(); } if ($this->isFunctionNameEndingWith($functionCall, 'compact')) { From 3ef8ce3144f2e20fc808e6670f4923d8ccef63b6 Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Thu, 23 Jul 2020 10:35:37 +0300 Subject: [PATCH 087/218] Added regression test for issue 790 --- .../PHPMD/Rule/Naming/ShortVariableTest.php | 22 ++++++++++++ ...estRuleAppliesToVariablesWithinForeach.php | 34 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100755 src/test/resources/files/Rule/Naming/ShortVariable/testRuleAppliesToVariablesWithinForeach.php diff --git a/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php b/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php index b57f645aa..1d25332aa 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php @@ -345,4 +345,26 @@ public function testRuleNotAppliesToVariablesFromExceptionsList() $rule->apply($this->getClass()); } + + + + /** + * testRuleAppliesToVariablesWithinForeach + * + * @return void + */ + public function testRuleAppliesToVariablesWithinForeach() + { + $rule = new ShortVariable(); + $rule->addProperty('minimum', 3); + $rule->addProperty('exceptions', ''); + $rule->setReport($this->getReportMock(2)); + + $class = $this->getClass(); + $rule->apply($class); + + foreach ($class->getMethods() as $method) { + $rule->apply($method); + } + } } diff --git a/src/test/resources/files/Rule/Naming/ShortVariable/testRuleAppliesToVariablesWithinForeach.php b/src/test/resources/files/Rule/Naming/ShortVariable/testRuleAppliesToVariablesWithinForeach.php new file mode 100755 index 000000000..96b31894b --- /dev/null +++ b/src/test/resources/files/Rule/Naming/ShortVariable/testRuleAppliesToVariablesWithinForeach.php @@ -0,0 +1,34 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleAppliesToVariablesWithinForeach +{ + public function testing() + { + $abc = 1; + + foreach ([1, 2, 3] as $i) { + $a = $i; + echo $a; + foreach ([4, 5, 6] as $k => $v) { + echo $k; + echo $v; + $x = (string) $k . (string) $v; + } + } + } +} From 13adfa2b511ccfdd7030fffac884680ee964b9f9 Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Thu, 23 Jul 2020 10:36:24 +0300 Subject: [PATCH 088/218] Added fix for ShortVariable Rule to process names inside freach loop --- .../php/PHPMD/Rule/Naming/ShortVariable.php | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php index d36b13361..f9047fd12 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php @@ -171,12 +171,59 @@ private function getExceptionsList() */ private function isNameAllowedInContext(AbstractNode $node) { + if ($this->isChildOf($node, 'ForeachStatement')) { + return $this->isInitializedInLoop($node); + } + return $this->isChildOf($node, 'CatchStatement') || $this->isChildOf($node, 'ForInit') - || $this->isChildOf($node, 'ForeachStatement') || $this->isChildOf($node, 'MemberPrimaryPrefix'); } + /** + * Checks if a short name is initialized within a foreach loop statement + * + * @param \PHPMD\AbstractNode $node + * @return boolean + */ + protected function isInitializedInLoop(AbstractNode $node) + { + $exceptionVariables = []; + + $parentForeaches = $this->getParentsOfType($node, 'ForeachStatement'); + foreach ($parentForeaches as $foreach) { + foreach ($foreach->getChildren() as $foreachChild) { + $exceptionVariables[] = $foreachChild->getImage(); + } + } + + $exceptionVariables = array_filter(array_unique($exceptionVariables)); + + return in_array($node->getImage(), $exceptionVariables, true); + } + + /** + * Returns an array of parent nodes of the specified type + * + * @param \PHPMD\AbstractNode $node + * @return boolean + */ + protected function getParentsOfType(AbstractNode $node, $type) + { + $parents = []; + + $parent = $node->getParent(); + + while (is_object($parent)) { + if ($parent->isInstanceOf($type)) { + $parents[] = $parent; + } + $parent = $parent->getParent(); + } + + return $parents; + } + /** * Checks if the given node is a direct or indirect child of a node with * the given type. From a87be542444f1ed03f76383373c2039779c590d0 Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Thu, 23 Jul 2020 10:42:07 +0300 Subject: [PATCH 089/218] Removed empty lines in ShortVariableTest --- src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php b/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php index 1d25332aa..2b5db12c2 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php @@ -346,8 +346,6 @@ public function testRuleNotAppliesToVariablesFromExceptionsList() $rule->apply($this->getClass()); } - - /** * testRuleAppliesToVariablesWithinForeach * From dd41323cb72f081573827eaad53dec07acd6e7bf Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 23 Jul 2020 10:15:03 +0200 Subject: [PATCH 090/218] Fix PHP 5.3 compatibility for $exceptionVariable --- src/main/php/PHPMD/Rule/Naming/ShortVariable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php index f9047fd12..9deb8f4d6 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php @@ -188,7 +188,7 @@ private function isNameAllowedInContext(AbstractNode $node) */ protected function isInitializedInLoop(AbstractNode $node) { - $exceptionVariables = []; + $exceptionVariables = array(); $parentForeaches = $this->getParentsOfType($node, 'ForeachStatement'); foreach ($parentForeaches as $foreach) { From ad70a1ae064b56eb82c4a8c9e6cee9c5d937e395 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 23 Jul 2020 10:16:32 +0200 Subject: [PATCH 091/218] Fix PHP 5.3 compatibility for $parents --- src/main/php/PHPMD/Rule/Naming/ShortVariable.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php index 9deb8f4d6..00590b7cc 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php @@ -208,9 +208,7 @@ protected function isInitializedInLoop(AbstractNode $node) * @param \PHPMD\AbstractNode $node * @return boolean */ - protected function getParentsOfType(AbstractNode $node, $type) - { - $parents = []; + $parents = array(); $parent = $node->getParent(); From 5075b6d890f7bb16d10a7186e2a1f1001758ba77 Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Thu, 23 Jul 2020 11:26:09 +0300 Subject: [PATCH 092/218] Aray initialization changed to support old PHP verions --- src/main/php/PHPMD/Rule/Naming/ShortVariable.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php index f9047fd12..a8ca3559d 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php @@ -188,7 +188,7 @@ private function isNameAllowedInContext(AbstractNode $node) */ protected function isInitializedInLoop(AbstractNode $node) { - $exceptionVariables = []; + $exceptionVariables = array(); $parentForeaches = $this->getParentsOfType($node, 'ForeachStatement'); foreach ($parentForeaches as $foreach) { @@ -210,7 +210,7 @@ protected function isInitializedInLoop(AbstractNode $node) */ protected function getParentsOfType(AbstractNode $node, $type) { - $parents = []; + $parents = array(); $parent = $node->getParent(); From 7bd0ebcbeb8669c103ed7b3d84bc05af8c2e49ce Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 23 Jul 2020 10:26:37 +0200 Subject: [PATCH 093/218] Revert unwanted code removal --- src/main/php/PHPMD/Rule/Naming/ShortVariable.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php index 00590b7cc..a8ca3559d 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php @@ -208,6 +208,8 @@ protected function isInitializedInLoop(AbstractNode $node) * @param \PHPMD\AbstractNode $node * @return boolean */ + protected function getParentsOfType(AbstractNode $node, $type) + { $parents = array(); $parent = $node->getParent(); From bb74280a8a9e307afbd5db4bfc5561ebada7c284 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 23 Jul 2020 10:51:49 +0200 Subject: [PATCH 094/218] Fix wrong return type --- src/main/php/PHPMD/Rule/Naming/ShortVariable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php index a8ca3559d..ad46123d1 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php @@ -206,7 +206,7 @@ protected function isInitializedInLoop(AbstractNode $node) * Returns an array of parent nodes of the specified type * * @param \PHPMD\AbstractNode $node - * @return boolean + * @return array */ protected function getParentsOfType(AbstractNode $node, $type) { From 281bee538c7bdb4e41caf73fb9405dba7a2ae87e Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Sun, 26 Jul 2020 11:02:17 +0200 Subject: [PATCH 095/218] Fix #808 Ignore rule path for supression annotation --- src/main/php/PHPMD/Node/Annotation.php | 5 +++- src/test/php/PHPMD/Node/ClassNodeTest.php | 29 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Node/Annotation.php b/src/main/php/PHPMD/Node/Annotation.php index 3339371d4..dc3207b95 100644 --- a/src/main/php/PHPMD/Node/Annotation.php +++ b/src/main/php/PHPMD/Node/Annotation.php @@ -80,7 +80,10 @@ private function isSuppressed(Rule $rule) { if (in_array($this->value, array('PHPMD', 'PMD'))) { return true; - } elseif (preg_match('/^(PH)?PMD\.' . $rule->getName() . '/', $this->value)) { + } elseif (preg_match( + '/^(PH)?PMD\.' . preg_replace('/^.*\/([^\/]*)$/', '$1', $rule->getName()) . '/', + $this->value + )) { return true; } diff --git a/src/test/php/PHPMD/Node/ClassNodeTest.php b/src/test/php/PHPMD/Node/ClassNodeTest.php index a52df9778..995fbf777 100644 --- a/src/test/php/PHPMD/Node/ClassNodeTest.php +++ b/src/test/php/PHPMD/Node/ClassNodeTest.php @@ -21,6 +21,7 @@ use PDepend\Source\AST\ASTMethod; use PDepend\Source\AST\ASTNamespace; use PHPMD\AbstractTest; +use PHPMD\Rule\Design\CouplingBetweenObjects; /** * Test case for the class node implementation. @@ -62,6 +63,34 @@ public function testHasSuppressWarningsAnnotationForReturnsTrue() $this->assertTrue($node->hasSuppressWarningsAnnotationFor($rule)); } + /** + * testHasSuppressWarningsWithRuleNameContainingSlashes + * + * @return void + */ + public function testHasSuppressWarningsWithRuleNameContainingSlashes() + { + $class = new ASTClass(null); + $class->setComment('/** @SuppressWarnings(PMD.CouplingBetweenObjects) */'); + + $rule = new CouplingBetweenObjects(); + $rule->setName('rulesets/design.xml/CouplingBetweenObjects'); + + $node = new ClassNode($class); + + $this->assertTrue($node->hasSuppressWarningsAnnotationFor($rule)); + + $class = new ASTClass(null); + $class->setComment('/** @SuppressWarnings(PMD.TooManyFields) */'); + + $rule = new CouplingBetweenObjects(); + $rule->setName('rulesets/design.xml/CouplingBetweenObjects'); + + $node = new ClassNode($class); + + $this->assertFalse($node->hasSuppressWarningsAnnotationFor($rule)); + } + /** * testGetFullQualifiedNameReturnsExpectedValue * From 532fbc66ea378aeae8c52f61418d84e3ec0673c9 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Mon, 27 Jul 2020 22:20:50 +0200 Subject: [PATCH 096/218] Reduce the complexity by removing 2 not needed checks. --- src/main/php/PHPMD/Rule/AbstractLocalVariable.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php index 428e14970..b7573db48 100644 --- a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php +++ b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php @@ -211,8 +211,7 @@ protected function getVariableImage($variable) $base = $variable; $parent = $this->getNode($variable->getParent()); - while ($parent && - $parent instanceof ASTArrayIndexExpression && + while ($parent instanceof ASTArrayIndexExpression && $base instanceof ASTNode && $parent->getChild(0) === $base->getNode() ) { @@ -220,7 +219,7 @@ protected function getVariableImage($variable) $parent = $this->getNode($base->getParent()); } - if ($parent && $parent instanceof ASTPropertyPostfix) { + if ($parent instanceof ASTPropertyPostfix) { $parent = $parent->getParent(); if ($parent instanceof ASTMemberPrimaryPrefix && From b010c1a607f28bfcb8b560ff9dcfebf2172b71af Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Fri, 31 Jul 2020 07:17:35 +0300 Subject: [PATCH 097/218] Short variables in cycles are made configurable --- src/main/php/PHPMD/Rule/Naming/ShortVariable.php | 4 ++++ .../php/PHPMD/Rule/Naming/ShortVariableTest.php | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php index ad46123d1..3cfbc625e 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php @@ -188,6 +188,10 @@ private function isNameAllowedInContext(AbstractNode $node) */ protected function isInitializedInLoop(AbstractNode $node) { + if (!$this->getBooleanProperty('allow-short-variables-in-loop', true)) { + return false; + } + $exceptionVariables = array(); $parentForeaches = $this->getParentsOfType($node, 'ForeachStatement'); diff --git a/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php b/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php index 2b5db12c2..d1f9961c6 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php @@ -349,14 +349,16 @@ public function testRuleNotAppliesToVariablesFromExceptionsList() /** * testRuleAppliesToVariablesWithinForeach * + * @dataProvider provideClassWithShortForeachVariables * @return void */ - public function testRuleAppliesToVariablesWithinForeach() + public function testRuleAppliesToVariablesWithinForeach($allowShortVarInLoop, $expectedErrorsCount) { $rule = new ShortVariable(); $rule->addProperty('minimum', 3); $rule->addProperty('exceptions', ''); - $rule->setReport($this->getReportMock(2)); + $rule->addProperty('allow-short-variables-in-loop', $allowShortVarInLoop); + $rule->setReport($this->getReportMock($expectedErrorsCount)); $class = $this->getClass(); $rule->apply($class); @@ -365,4 +367,12 @@ public function testRuleAppliesToVariablesWithinForeach() $rule->apply($method); } } + + public function provideClassWithShortForeachVariables() + { + return [ + [true, 2], + [false, 5], + ]; + } } From 0409c2dcc462ac8fabb1fc07a23a2a83f047986a Mon Sep 17 00:00:00 2001 From: Artem Prozorov Date: Fri, 31 Jul 2020 07:27:24 +0300 Subject: [PATCH 098/218] Array declaration is changed from [] to array --- src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php b/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php index d1f9961c6..fb744843b 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php @@ -370,9 +370,9 @@ public function testRuleAppliesToVariablesWithinForeach($allowShortVarInLoop, $e public function provideClassWithShortForeachVariables() { - return [ - [true, 2], - [false, 5], - ]; + return array( + array(true, 2), + array(false, 5), + ); } } From c9540edc5773c2692fdc60d51cf0868e8d6e9a7d Mon Sep 17 00:00:00 2001 From: Frank Dekker Date: Sat, 1 Aug 2020 16:15:05 +0200 Subject: [PATCH 099/218] Updated documentation for Short and Long Class name rules --- src/site/rst/rules/naming.rst | 59 ++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/site/rst/rules/naming.rst b/src/site/rst/rules/naming.rst index a870b7088..9dd05a873 100644 --- a/src/site/rst/rules/naming.rst +++ b/src/site/rst/rules/naming.rst @@ -4,6 +4,63 @@ Naming Rules The Naming Ruleset contains a collection of rules about names - too long, too short, and so forth. +LongClassName +============= + +Since: PHPMD 2.9 + +Detects when classes or interfaces are declared with excessively long names. + +Example: :: + + class ATooLongClassNameThatHintsAtADesignProblem { + + } + + interface ATooLongInterfaceNameThatHintsAtADesignProblem { + + } + +This rule has the following properties: + ++-----------------------------------+---------------+------------------------------------------------------------+ +| Name | Default Value | Description | ++===================================+===============+============================================================+ +| maximum | 40 | The class name length reporting threshold. | ++-----------------------------------+---------------+------------------------------------------------------------+ +| subtract-suffixes | | Comma-separated list of suffixes that will not count in | +| | | the length of the class name. Only the first matching | +| | | suffix will be subtracted. | ++-----------------------------------+---------------+------------------------------------------------------------+ + +ShortClassName +============== + +Since: PHPMD 2.9 + +Detects when classes or interfaces have a very short name. + +Example: :: + + class Fo { + + } + + interface Fo { + + } + +This rule has the following properties: + ++-----------------------------------+---------------+------------------------------------------------------------+ +| Name | Default Value | Description | ++===================================+===============+============================================================+ +| minimum | 3 | The class name length reporting threshold | ++-----------------------------------+---------------+------------------------------------------------------------+ +| exceptions | | Comma-separated list of exceptions. Example: Log,URL,FTP | ++-----------------------------------+---------------+------------------------------------------------------------+ + + ShortVariable ============= @@ -158,4 +215,4 @@ Remark This document is based on a ruleset xml-file, that was taken from the original source of the `PMD`__ project. This means that most parts of the content on this page are the intellectual work of the PMD community and its contributors and not of the PHPMD project. __ http://pmd.sourceforge.net/ - + From 5bc45a5941ef713dd1f50f155b55896a9bcc1e49 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Tue, 4 Aug 2020 22:34:59 +0200 Subject: [PATCH 100/218] Add new items to the changelog --- CHANGELOG | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 682525d1c..9c2b99a6c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,9 +11,15 @@ phpmd-2.9.0 (2020/05/25) - Fixed #770: Fixed #769 Handle deconstruction assignation for undefined variable - Fixed #781: Fixed #714 static:: and self:: properties access - Fixed #784: Fixed #672 Handle passing-by-reference in native PHP functions -- Updated different parts of the documentation. #717 #736 #748 -- Changed: #529 : Replaced HTML renderer with new "pretty HTML" renderer -- Changed: Internal code improvement #750 #752 #756 #757 #758 #759 #768 #773 #775 #785 #787 +- Fixed #793: Fixed #580 Raise UnusedFormalParameter instead UnusedLocalVariable for unused closure parameter +- Fixed #794: Fixed #540 Detect unused variable declared multiple times +- Fixed #805: Fixed #802 Prevent an error with nested arrays +- Fixed #807: Fixed #790 Fix for short variables rule inside foreach statements +- Fixed #809: Fixed #808 Ignore rule path for supression annotation +- Updated different parts of the documentation. #717 #736 #748 #811 +- Changed: #529 : Replaced HTML renderer with new "pretty HTML" renderer +- Changed: #806 : Changed #44 Change private methods to protected in rules. Make rules extendable +- Changed: Internal code improvement #750 #752 #756 #757 #758 #759 #768 #773 #775 #785 #787 #791 #792 - Deprecated all the PHPMD exceptions that aren't part of the PHPMD\Exceptions namespace. See #775 ### A potential BC change: From 8c5775a2b5226c08a0607fa4988323a1e8e03b32 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Tue, 1 Sep 2020 21:12:30 +0200 Subject: [PATCH 101/218] Lets change the release date for 2.9.0 to 2020/09/02 --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 97d2e7363..6dc5f57fd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -phpmd-2.9.0 (2020/07/23) +phpmd-2.9.0 (2020/09/02) ======================== - Added #496: Added rule for PHP's @ operator From 4607d6f932ed232568a1f12736c226ddac7d315c Mon Sep 17 00:00:00 2001 From: Alexander Menshchikov Date: Wed, 2 Sep 2020 13:51:52 +0300 Subject: [PATCH 102/218] Fixed undefined index referring --- src/main/php/PHPMD/Rule/AbstractLocalVariable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php index d8d5e81c8..962d5433e 100644 --- a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php +++ b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php @@ -268,7 +268,7 @@ protected function isPassedByReference($variable) $reflectionFunction = new ReflectionFunction($functionName); $parameters = $reflectionFunction->getParameters(); - if ($parameters[$argumentPosition]->isPassedByReference()) { + if (isset($parameters[$argumentPosition]) && $parameters[$argumentPosition]->isPassedByReference()) { return true; } } catch (ReflectionException $exception) { From 987c48809880483e43e33fa5d883466f0b978937 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 3 Sep 2020 13:14:53 +0200 Subject: [PATCH 103/218] Upgrade build version number for next patch --- build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.properties b/build.properties index 1b7adce0c..147fc3cb5 100644 --- a/build.properties +++ b/build.properties @@ -1,7 +1,7 @@ project.dir = project.uri = phpmd.org project.name = phpmd -project.version = 2.8.1 +project.version = 2.9.1 project.stability = stable # Disable pear support. This cannot be removed as long as setup tool is used From 2e0b64e6e17755f835a24354d38e566453994083 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Fri, 4 Sep 2020 17:10:47 +0200 Subject: [PATCH 104/218] #818 Don't check function arguments if the callee is a method --- .../php/PHPMD/Rule/AbstractLocalVariable.php | 7 ++++- src/test/php/PHPMD/AbstractTest.php | 2 +- .../testRuleAppliesToExtraParameters.php | 31 +++++++++++++++++++ ...uleAppliesToMethodMatchingFunctionName.php | 29 +++++++++++++++++ ...tRuleAppliesToUndefinedVariableOnArray.php | 2 +- ...liesToUndefinedVariableOnArrayWithKeys.php | 2 +- ...ToUndefinedVariableWithDefinedVariable.php | 2 +- .../testRuleAppliesToUnknownArguments.php | 24 ++++++++++++++ .../testRuleDoesNotApplyToUnknownMethod.php | 24 ++++++++++++++ .../testRuleDoesNotApplyToUsedProperties.php | 2 +- 10 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToExtraParameters.php create mode 100644 src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToMethodMatchingFunctionName.php create mode 100644 src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUnknownArguments.php create mode 100644 src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToUnknownMethod.php diff --git a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php index 962d5433e..90c8f09ea 100644 --- a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php +++ b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php @@ -262,8 +262,14 @@ protected function isPassedByReference($variable) if ($parent && $parent instanceof ASTArguments) { $argumentPosition = array_search($this->getNode($variable), $parent->getChildren()); $function = $this->getNode($parent->getParent()); + $functionParent = $this->getNode($function->getParent()); $functionName = $function->getImage(); + if ($functionParent instanceof ASTMemberPrimaryPrefix) { + // @TODO: Find a way to handle methods + return false; + } + try { $reflectionFunction = new ReflectionFunction($functionName); $parameters = $reflectionFunction->getParameters(); @@ -273,7 +279,6 @@ protected function isPassedByReference($variable) } } catch (ReflectionException $exception) { // @TODO: Find a way to handle user-land functions - // @TODO: Find a way to handle methods } } diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 9d5ebaa1a..d8d0ab49e 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -253,7 +253,7 @@ protected function expectRuleHasViolationsForFile(Rule $rule, $expectedInvokes, if (!$assertion) { throw new PHPUnit_Framework_ExpectationFailedException( - $this->getViolationFailureMessage($file, $actualInvokes, $expectedInvokes, $violations) + $this->getViolationFailureMessage($file, $expectedInvokes, $actualInvokes, $violations) ); } diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToExtraParameters.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToExtraParameters.php new file mode 100644 index 000000000..d4d63e28d --- /dev/null +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToExtraParameters.php @@ -0,0 +1,31 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleAppliesToExtraParameters +{ + function testRuleAppliesToExtraParameters() + { + $x = 42; + + $this->foo($x, $y); + } + + function foo(&$a) + { + $a++; + } +} diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToMethodMatchingFunctionName.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToMethodMatchingFunctionName.php new file mode 100644 index 000000000..b8c8046ef --- /dev/null +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToMethodMatchingFunctionName.php @@ -0,0 +1,29 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleAppliesToMethodMatchingFunctionName +{ + public function testRuleAppliesToMethodMatchingFunctionName() + { + $this->preg_match('a', 'b', $undefined); + } + + public function preg_match($a, $b, $c) + { + // noop + } +} diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableOnArray.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableOnArray.php index 0937f52a7..5f9ba6ef7 100644 --- a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableOnArray.php +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableOnArray.php @@ -15,7 +15,7 @@ * @link http://phpmd.org/ */ -class testRuleAppliesToUndefinedVariableOnArray extends AbstractTest +class testRuleAppliesToUndefinedVariableOnArray { function testRuleAppliesToUndefinedVariableOnArray() { diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableOnArrayWithKeys.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableOnArrayWithKeys.php index cdba11288..12dfca0f8 100644 --- a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableOnArrayWithKeys.php +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableOnArrayWithKeys.php @@ -15,7 +15,7 @@ * @link http://phpmd.org/ */ -class testRuleAppliesToUndefinedVariableOnArray extends AbstractTest +class testRuleAppliesToUndefinedVariableOnArray { function testRuleAppliesToUndefinedVariableOnArrayWithKeys() { diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableWithDefinedVariable.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableWithDefinedVariable.php index 39f2d95d4..9f088e737 100644 --- a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableWithDefinedVariable.php +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUndefinedVariableWithDefinedVariable.php @@ -15,7 +15,7 @@ * @link http://phpmd.org/ */ -class testRuleAppliesToUndefinedVariableWithDefinedVariable extends AbstractTest +class testRuleAppliesToUndefinedVariableWithDefinedVariable { function testRuleAppliesToUndefinedVariableWithDefinedVariable() { diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUnknownArguments.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUnknownArguments.php new file mode 100644 index 000000000..4850530b2 --- /dev/null +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleAppliesToUnknownArguments.php @@ -0,0 +1,24 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleAppliesToUnknownArguments +{ + function testRuleAppliesToUnknownArguments(UnknownObject $object) + { + $object->foo($a); + } +} diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToUnknownMethod.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToUnknownMethod.php new file mode 100644 index 000000000..e31411476 --- /dev/null +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToUnknownMethod.php @@ -0,0 +1,24 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleDoesNotApplyToUnknownMethod +{ + function testRuleDoesNotApplyToUnknownMethod(UnknownObject $object) + { + $this->foo($object); + } +} diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToUsedProperties.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToUsedProperties.php index 81598cf6a..528f8501d 100644 --- a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToUsedProperties.php +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToUsedProperties.php @@ -15,7 +15,7 @@ * @link http://phpmd.org/ */ -class testRuleDoesNotApplyToUsedProperties extends AbstractTest +class testRuleDoesNotApplyToUsedProperties { protected $x = 'abc'; From 3fcd159abb074752fd78951f7cfdd5fe1ba19b9a Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Mon, 7 Sep 2020 11:46:49 +0200 Subject: [PATCH 105/218] Fix #714 Improve static member detection --- .../php/PHPMD/Rule/AbstractLocalVariable.php | 23 +++++++++++++++---- src/test/php/PHPMD/AbstractTest.php | 2 +- ...testRuleDoesNotApplyToStaticProperties.php | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php index 962d5433e..a12a04a3c 100644 --- a/src/main/php/PHPMD/Rule/AbstractLocalVariable.php +++ b/src/main/php/PHPMD/Rule/AbstractLocalVariable.php @@ -220,11 +220,9 @@ protected function getVariableImage($variable) } if ($parent instanceof ASTPropertyPostfix) { - $parent = $parent->getParent(); + $previousChildImage = $this->getParentMemberPrimaryPrefixImage($image, $parent); - if ($parent instanceof ASTMemberPrimaryPrefix && - in_array($parent->getChild(0)->getImage(), $this->selfReferences) - ) { + if (in_array($previousChildImage, $this->selfReferences, true)) { return "::$image"; } } @@ -232,6 +230,23 @@ protected function getVariableImage($variable) return $image; } + protected function getParentMemberPrimaryPrefixImage($image, ASTPropertyPostfix $postfix) + { + do { + $postfix = $postfix->getParent(); + } while ($postfix && $postfix->getChild(0) && $postfix->getChild(0)->getImage() === $image); + + $previousChildImage = $postfix->getChild(0)->getImage(); + + if ($postfix instanceof ASTMemberPrimaryPrefix && + in_array($previousChildImage, $this->selfReferences) + ) { + return $previousChildImage; + } + + return null; + } + /** * Return the PDepend node of ASTNode PHPMD node. * diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index 9d5ebaa1a..d8d0ab49e 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -253,7 +253,7 @@ protected function expectRuleHasViolationsForFile(Rule $rule, $expectedInvokes, if (!$assertion) { throw new PHPUnit_Framework_ExpectationFailedException( - $this->getViolationFailureMessage($file, $actualInvokes, $expectedInvokes, $violations) + $this->getViolationFailureMessage($file, $expectedInvokes, $actualInvokes, $violations) ); } diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToStaticProperties.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToStaticProperties.php index a37fdaaa6..b80ef1871 100644 --- a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToStaticProperties.php +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToStaticProperties.php @@ -23,7 +23,7 @@ class testRuleDoesNotApplyToStaticProperties function testRuleDoesNotApplyToStaticProperties($key) { if (isset(static::$array[$key])) { - return static::$array[$key]; + return static::$array[$key]->foo(); } return $key; From 66baea121750127c6cc7eb56437144fb829ff2b0 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Mon, 7 Sep 2020 11:52:43 +0200 Subject: [PATCH 106/218] #714 Add dedicated unit test for call with static member --- ...oesNotApplyToCallsWithStaticProperties.php | 26 +++++++++++++++++++ ...testRuleDoesNotApplyToStaticProperties.php | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToCallsWithStaticProperties.php diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToCallsWithStaticProperties.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToCallsWithStaticProperties.php new file mode 100644 index 000000000..8e738fd7d --- /dev/null +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToCallsWithStaticProperties.php @@ -0,0 +1,26 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +class testRuleDoesNotApplyToCallsWithStaticProperties +{ + protected static $test = []; + + function testRuleDoesNotApplyToCallsWithStaticProperties() + { + self::$test[0]->foo(); + } +} diff --git a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToStaticProperties.php b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToStaticProperties.php index b80ef1871..a37fdaaa6 100644 --- a/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToStaticProperties.php +++ b/src/test/resources/files/Rule/CleanCode/UndefinedVariable/testRuleDoesNotApplyToStaticProperties.php @@ -23,7 +23,7 @@ class testRuleDoesNotApplyToStaticProperties function testRuleDoesNotApplyToStaticProperties($key) { if (isset(static::$array[$key])) { - return static::$array[$key]->foo(); + return static::$array[$key]; } return $key; From 5b6db17865d10bbf7896ffcee523bdf0dadd153b Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 23 Sep 2020 15:44:07 +0200 Subject: [PATCH 107/218] Add Changelog for 2.9.1 --- CHANGELOG | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 6dc5f57fd..a6b344008 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +phpmd-2.9.1 (2020/09/23) +======================== + +- Fixed #714: Improved static member detection +- Fixed #816: Fixed undefined index referring + phpmd-2.9.0 (2020/09/02) ======================== From 0f224c43dafc3ab69f85d36a2e3b098467ef4b36 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Thu, 24 Sep 2020 19:01:19 +0200 Subject: [PATCH 108/218] Fix #826 consider foreach exception only for direct children --- .../php/PHPMD/Rule/Naming/ShortVariable.php | 4 ++- .../PHPMD/Rule/Naming/ShortVariableTest.php | 14 ++++++++++ ...otAppliesToTryCatchBlocksInsideForeach.php | 27 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/files/Rule/Naming/ShortVariable/testRuleNotAppliesToTryCatchBlocksInsideForeach.php diff --git a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php index 4c391b51b..29f25e486 100644 --- a/src/main/php/PHPMD/Rule/Naming/ShortVariable.php +++ b/src/main/php/PHPMD/Rule/Naming/ShortVariable.php @@ -171,7 +171,9 @@ protected function getExceptionsList() */ protected function isNameAllowedInContext(AbstractNode $node) { - if ($this->isChildOf($node, 'ForeachStatement')) { + $parent = $node->getParent(); + + if ($parent && $parent->isInstanceOf('ForeachStatement')) { return $this->isInitializedInLoop($node); } diff --git a/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php b/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php index fb744843b..db5f5dc7d 100644 --- a/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php +++ b/src/test/php/PHPMD/Rule/Naming/ShortVariableTest.php @@ -41,6 +41,20 @@ public function testRuleAppliesToLocalVariableInFunctionWithNameShorterThanThres $rule->apply($this->getFunction()); } + /** + * testRuleAppliesToTryCatchBlocks + * + * @return void + */ + public function testRuleNotAppliesToTryCatchBlocksInsideForeach() + { + $rule = new ShortVariable(); + $rule->addProperty('minimum', 3); + $rule->addProperty('exceptions', ''); + $rule->setReport($this->getReportWithNoViolation()); + $rule->apply($this->getFunction()); + } + /** * testRuleNotAppliesToLocalVariableInFunctionWithNameLongerThanThreshold * diff --git a/src/test/resources/files/Rule/Naming/ShortVariable/testRuleNotAppliesToTryCatchBlocksInsideForeach.php b/src/test/resources/files/Rule/Naming/ShortVariable/testRuleNotAppliesToTryCatchBlocksInsideForeach.php new file mode 100644 index 000000000..614da105a --- /dev/null +++ b/src/test/resources/files/Rule/Naming/ShortVariable/testRuleNotAppliesToTryCatchBlocksInsideForeach.php @@ -0,0 +1,27 @@ +. + * All rights reserved. + * + * Licensed under BSD License + * For full copyright and license information, please see the LICENSE file. + * Redistributions of files must retain the above copyright notice. + * + * @author Manuel Pichler + * @copyright Manuel Pichler. All rights reserved. + * @license https://opensource.org/licenses/bsd-license.php BSD License + * @link http://phpmd.org/ + */ + +function testRuleNotAppliesToTryCatchBlocksInsideForeach() +{ + foreach ([1, 2] as $number) { + try { + echo $number; + } catch (InvalidArgumentException $e) { + var_dump($e); + } + } +} From 42864126f825532606663b4a3af082046ed94435 Mon Sep 17 00:00:00 2001 From: Raffael Comi Date: Sat, 3 Oct 2020 18:39:43 +0200 Subject: [PATCH 109/218] Add missing return/throws annotation --- src/test/php/PHPMD/AbstractTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/php/PHPMD/AbstractTest.php b/src/test/php/PHPMD/AbstractTest.php index d8d0ab49e..4d503c75a 100644 --- a/src/test/php/PHPMD/AbstractTest.php +++ b/src/test/php/PHPMD/AbstractTest.php @@ -239,6 +239,8 @@ protected function getNodeForTestFile($file) * @param Rule $rule Rule to test. * @param int $expectedInvokes Count of expected invocations. * @param string $file Test file containing a method with the same name to be tested. + * @return void + * @throws PHPUnit_Framework_ExpectationFailedException */ protected function expectRuleHasViolationsForFile(Rule $rule, $expectedInvokes, $file) { From 41a1f4b90d4d8460dfec7f681b481fa911713671 Mon Sep 17 00:00:00 2001 From: Jeff Horton Date: Sat, 3 Oct 2020 23:36:36 +0100 Subject: [PATCH 110/218] Add externalInfoUrl for UndefinedVariable --- src/main/resources/rulesets/cleancode.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/rulesets/cleancode.xml b/src/main/resources/rulesets/cleancode.xml index 64f856b3b..bfb58c5b5 100644 --- a/src/main/resources/rulesets/cleancode.xml +++ b/src/main/resources/rulesets/cleancode.xml @@ -204,7 +204,7 @@ function make() { since="2.8.0" message="Avoid using undefined variables such as '{0}' which will lead to PHP notices." class="PHPMD\Rule\CleanCode\UndefinedVariable" - externalInfoUrl=""> + externalInfoUrl="https://phpmd.org/rules/cleancode.html#undefinedvariable"> Detects when a variable is used that has not been defined before. From 6f5c74db39144643dc8f024976970f89ba5bd2b6 Mon Sep 17 00:00:00 2001 From: Jeff Horton Date: Sun, 4 Oct 2020 00:20:10 +0100 Subject: [PATCH 111/218] Add test for missing externalInfoUrl --- src/test/php/PHPMD/RuleSetFactoryTest.php | 35 ++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/test/php/PHPMD/RuleSetFactoryTest.php b/src/test/php/PHPMD/RuleSetFactoryTest.php index a05ca2b18..699c18704 100644 --- a/src/test/php/PHPMD/RuleSetFactoryTest.php +++ b/src/test/php/PHPMD/RuleSetFactoryTest.php @@ -711,6 +711,39 @@ public function testIfGettingRuleFilePathExcludeUnreadablePaths() $this->assertEquals(5, $ruleSetNotFoundExceptionCount); } + /** + * Checks the ruleset XML files provided with PHPMD all provide externalInfoUrls + * + * @param string $file The path to the ruleset xml to test + * @return void + * @dataProvider getDefaultRuleSets + */ + public function testDefaultRuleSetsProvideExternalInfoUrls($file) + { + $rulesets = $this->createRuleSetsFromFiles($file); + $ruleset = $rulesets[0]; + /** @var Rule $rule */ + foreach ($ruleset->getRules() as $rule) { + $message = sprintf( + '%s in rule set %s should provide an externalInfoUrl', + $rule->getName(), + $ruleset->getName() + ); + + $this->assertNotEmpty($rule->getExternalInfoUrl(), $message); + } + } + + /** + * Provides an array of the file paths to rule sets provided with PHPMD + * + * @return array + */ + public function getDefaultRuleSets() + { + return static::getValuesAsArrays(glob(__DIR__ . '/../../../main/resources/rulesets/*.xml')); + } + /** * Invokes the createRuleSets() of the {@link RuleSetFactory} * class. @@ -741,7 +774,7 @@ private function createRuleSetsFromFiles($file) $args = func_get_args(); $factory = new RuleSetFactory(); - + return $factory->createRuleSets(implode(',', $args)); } From e5758ffd9316c58bead8bedd1b3c593110695771 Mon Sep 17 00:00:00 2001 From: Jeff Horton Date: Sun, 4 Oct 2020 00:58:13 +0100 Subject: [PATCH 112/218] Minor commit to retry build that failed due to 'Peer fingerprint did not match' --- src/test/php/PHPMD/RuleSetFactoryTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/php/PHPMD/RuleSetFactoryTest.php b/src/test/php/PHPMD/RuleSetFactoryTest.php index 699c18704..282cf916c 100644 --- a/src/test/php/PHPMD/RuleSetFactoryTest.php +++ b/src/test/php/PHPMD/RuleSetFactoryTest.php @@ -720,14 +720,14 @@ public function testIfGettingRuleFilePathExcludeUnreadablePaths() */ public function testDefaultRuleSetsProvideExternalInfoUrls($file) { - $rulesets = $this->createRuleSetsFromFiles($file); - $ruleset = $rulesets[0]; + $ruleSets = $this->createRuleSetsFromFiles($file); + $ruleSet = $ruleSets[0]; /** @var Rule $rule */ - foreach ($ruleset->getRules() as $rule) { + foreach ($ruleSet->getRules() as $rule) { $message = sprintf( '%s in rule set %s should provide an externalInfoUrl', $rule->getName(), - $ruleset->getName() + $ruleSet->getName() ); $this->assertNotEmpty($rule->getExternalInfoUrl(), $message); From 58b6f6994b8df0b1613396ac74023b213689bf69 Mon Sep 17 00:00:00 2001 From: martzd Date: Mon, 5 Oct 2020 20:28:05 +0200 Subject: [PATCH 113/218] Add "tool" property to main "pmd" tag in XML report --- src/main/php/PHPMD/Renderer/XMLRenderer.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/php/PHPMD/Renderer/XMLRenderer.php b/src/main/php/PHPMD/Renderer/XMLRenderer.php index 2a34441c8..218e04972 100644 --- a/src/main/php/PHPMD/Renderer/XMLRenderer.php +++ b/src/main/php/PHPMD/Renderer/XMLRenderer.php @@ -57,6 +57,7 @@ public function renderReport(Report $report) { $writer = $this->getWriter(); $writer->write('write('tool="phpmd" '); $writer->write('timestamp="' . date('c') . '">'); $writer->write(PHP_EOL); From a5203dc5c715c9e0b3df13beeaacca336b75e504 Mon Sep 17 00:00:00 2001 From: martzd Date: Mon, 5 Oct 2020 22:46:29 +0200 Subject: [PATCH 114/218] Fix tests --- src/test/resources/files/pmd/default-xml.xml | 2 +- src/test/resources/files/pmd/single-directory.xml | 2 +- src/test/resources/files/pmd/single-file.xml | 2 +- src/test/resources/files/renderer/xml_renderer_expected1.xml | 2 +- .../resources/files/renderer/xml_renderer_processing_errors.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/resources/files/pmd/default-xml.xml b/src/test/resources/files/pmd/default-xml.xml index 0b05f1626..8f53dc552 100755 --- a/src/test/resources/files/pmd/default-xml.xml +++ b/src/test/resources/files/pmd/default-xml.xml @@ -1,5 +1,5 @@ - + The function ccn_function() has a Cyclomatic Complexity of 12. The configured cyclomatic complexity threshold is 10. diff --git a/src/test/resources/files/pmd/single-directory.xml b/src/test/resources/files/pmd/single-directory.xml index df5097924..4259d677a 100755 --- a/src/test/resources/files/pmd/single-directory.xml +++ b/src/test/resources/files/pmd/single-directory.xml @@ -1,5 +1,5 @@ - + The function ccn_function() has a Cyclomatic Complexity of 12. The configured cyclomatic complexity threshold is 10. diff --git a/src/test/resources/files/pmd/single-file.xml b/src/test/resources/files/pmd/single-file.xml index 0b05f1626..8f53dc552 100755 --- a/src/test/resources/files/pmd/single-file.xml +++ b/src/test/resources/files/pmd/single-file.xml @@ -1,5 +1,5 @@ - + The function ccn_function() has a Cyclomatic Complexity of 12. The configured cyclomatic complexity threshold is 10. diff --git a/src/test/resources/files/renderer/xml_renderer_expected1.xml b/src/test/resources/files/renderer/xml_renderer_expected1.xml index c38d43b40..eb7eaa5fe 100755 --- a/src/test/resources/files/renderer/xml_renderer_expected1.xml +++ b/src/test/resources/files/renderer/xml_renderer_expected1.xml @@ -1,5 +1,5 @@ - + Test description diff --git a/src/test/resources/files/renderer/xml_renderer_processing_errors.xml b/src/test/resources/files/renderer/xml_renderer_processing_errors.xml index 964cee322..0c08ef5cb 100755 --- a/src/test/resources/files/renderer/xml_renderer_processing_errors.xml +++ b/src/test/resources/files/renderer/xml_renderer_processing_errors.xml @@ -1,5 +1,5 @@ - + From de5c079a4d57610f96838a79ae09a25839154498 Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Tue, 6 Oct 2020 15:17:12 +0200 Subject: [PATCH 115/218] Add unit tests for #829 --- src/test/php/PHPMD/TextUI/CommandTest.php | 20 +++++++++++++++++++ .../source/source_with_anonymous_class.php | 14 +++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/test/resources/files/source/source_with_anonymous_class.php diff --git a/src/test/php/PHPMD/TextUI/CommandTest.php b/src/test/php/PHPMD/TextUI/CommandTest.php index 1bb88c3a8..6a1ff779b 100644 --- a/src/test/php/PHPMD/TextUI/CommandTest.php +++ b/src/test/php/PHPMD/TextUI/CommandTest.php @@ -132,6 +132,26 @@ public function testWithMultipleReportFiles() $this->assertFileExists($json); } + public function testOutput() + { + $uri = realpath(self::createFileUri('source/source_with_anonymous_class.php')); + $temp = self::createTempFileUri(); + $exitCode = Command::main(array( + __FILE__, + $uri, + 'text', + 'naming', + '--reportfile', + $temp, + )); + + $this->assertSame(Command::EXIT_VIOLATION, $exitCode); + $this->assertSame( + "$uri:8 Avoid variables with short names like \$a. Configured minimum length is 3." . PHP_EOL, + file_get_contents($temp) + ); + } + /** * @param string $option * @param string $value diff --git a/src/test/resources/files/source/source_with_anonymous_class.php b/src/test/resources/files/source/source_with_anonymous_class.php new file mode 100644 index 000000000..036fc9ad3 --- /dev/null +++ b/src/test/resources/files/source/source_with_anonymous_class.php @@ -0,0 +1,14 @@ + Date: Wed, 14 Oct 2020 13:15:46 +0200 Subject: [PATCH 116/218] Mute filename error --- src/main/php/PHPMD/AbstractNode.php | 11 +++++++++-- src/main/php/PHPMD/RuleViolation.php | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/php/PHPMD/AbstractNode.php b/src/main/php/PHPMD/AbstractNode.php index 508f351c4..e9a3a683b 100644 --- a/src/main/php/PHPMD/AbstractNode.php +++ b/src/main/php/PHPMD/AbstractNode.php @@ -17,6 +17,7 @@ namespace PHPMD; +use PDepend\Source\AST\AbstractASTArtifact; use PHPMD\Node\ASTNode; /** @@ -194,11 +195,17 @@ public function getEndLine() /** * Returns the name of the declaring source file. * - * @return string + * @return string|null */ public function getFileName() { - return (string)$this->node->getCompilationUnit()->getFileName(); + $compilationUnit = $this->node instanceof AbstractASTArtifact + ? $this->node->getCompilationUnit() + : null; + + return $compilationUnit + ? (string)$compilationUnit->getFileName() + : null; // @TODO: Find the name from some parent node } /** diff --git a/src/main/php/PHPMD/RuleViolation.php b/src/main/php/PHPMD/RuleViolation.php index 9f60cbe7e..641b36dbb 100644 --- a/src/main/php/PHPMD/RuleViolation.php +++ b/src/main/php/PHPMD/RuleViolation.php @@ -136,7 +136,7 @@ public function getMetric() /** * Returns the file name where this rule violation was detected. * - * @return string + * @return string|null */ public function getFileName() { From 2d9f453f626f8f9b6c9d57116303e53cb7fadfb2 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 19 Oct 2020 09:29:59 +0200 Subject: [PATCH 117/218] Link todo to issue --- src/main/php/PHPMD/AbstractNode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/php/PHPMD/AbstractNode.php b/src/main/php/PHPMD/AbstractNode.php index e9a3a683b..dc13f8bc2 100644 --- a/src/main/php/PHPMD/AbstractNode.php +++ b/src/main/php/PHPMD/AbstractNode.php @@ -205,7 +205,7 @@ public function getFileName() return $compilationUnit ? (string)$compilationUnit->getFileName() - : null; // @TODO: Find the name from some parent node + : null; // @TODO: Find the name from some parent node https://github.com/phpmd/phpmd/issues/837 } /** From 3429c96aa413f84b359e17b7f7639fabbd67d722 Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Thu, 29 Oct 2020 16:47:35 +0100 Subject: [PATCH 118/218] Change the naming error where possible --- src/main/php/PHPMD/ParserFactory.php | 10 +++---- src/main/php/PHPMD/Renderer/HTMLRenderer.php | 28 ++++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/php/PHPMD/ParserFactory.php b/src/main/php/PHPMD/ParserFactory.php index f40e66d8a..ac4586b38 100644 --- a/src/main/php/PHPMD/ParserFactory.php +++ b/src/main/php/PHPMD/ParserFactory.php @@ -65,11 +65,11 @@ private function createInstance() { $application = new Application(); - $currentWorkingDirectory = getcwd(); - if (file_exists($currentWorkingDirectory . self::PDEPEND_CONFIG_FILE_NAME)) { - $application->setConfigurationFile($currentWorkingDirectory . self::PDEPEND_CONFIG_FILE_NAME); - } elseif (file_exists($currentWorkingDirectory . self::PDEPEND_CONFIG_FILE_NAME_DIST)) { - $application->setConfigurationFile($currentWorkingDirectory . self::PDEPEND_CONFIG_FILE_NAME_DIST); + $workingDirectory = getcwd(); + if (file_exists($workingDirectory . self::PDEPEND_CONFIG_FILE_NAME)) { + $application->setConfigurationFile($workingDirectory . self::PDEPEND_CONFIG_FILE_NAME); + } elseif (file_exists($workingDirectory . self::PDEPEND_CONFIG_FILE_NAME_DIST)) { + $application->setConfigurationFile($workingDirectory . self::PDEPEND_CONFIG_FILE_NAME_DIST); } return $application->getEngine(); diff --git a/src/main/php/PHPMD/Renderer/HTMLRenderer.php b/src/main/php/PHPMD/Renderer/HTMLRenderer.php index a25f93ef8..5d11565de 100644 --- a/src/main/php/PHPMD/Renderer/HTMLRenderer.php +++ b/src/main/php/PHPMD/Renderer/HTMLRenderer.php @@ -318,13 +318,13 @@ function toggle(id) { */ public function renderReport(Report $report) { - $w = $this->getWriter(); + $writer = $this->getWriter(); $index = 0; $violations = $report->getRuleViolations(); $count = count($violations); - $w->write(sprintf('

%d problems found

', $count)); + $writer->write(sprintf('

%d problems found

', $count)); // If no problems were found, don't bother with rendering anything else. if (!$count) { @@ -332,7 +332,7 @@ public function renderReport(Report $report) } // Render summary tables. - $w->write("

Summary

"); + $writer->write("

Summary

"); $categorized = self::sumUpViolations($violations); $this->writeTable('By priority', 'Priority', $categorized[self::CATEGORY_PRIORITY]); $this->writeTable('By namespace', 'PHP Namespace', $categorized[self::CATEGORY_NAMESPACE]); @@ -340,8 +340,8 @@ public function renderReport(Report $report) $this->writeTable('By name', 'Rule name', $categorized[self::CATEGORY_RULE]); // Render details of each violation and place the "Details" display toggle. - $w->write("

Details

"); - $w->write(" + $writer->write("

Details

"); + $writer->write(" Show details ▼ "); - $w->write("