diff --git a/src/main/php/PHP/PMD/Node/Method.php b/src/main/php/PHP/PMD/Node/Method.php index 737e06dc4..ffb4ccf1b 100644 --- a/src/main/php/PHP/PMD/Node/Method.php +++ b/src/main/php/PHP/PMD/Node/Method.php @@ -133,4 +133,35 @@ public function getParentType() } return new PHP_PMD_Node_Interface($parentNode); } + + /** + * Returns true when this method is the initial method declaration. + * Otherwise this method will return false. + * + * @return boolean + * @since 1.2.1 + */ + public function isDeclaration() + { + if ($this->isPrivate()) { + return true; + } + + $parentNode = $this->getNode()->getParent(); + foreach ($parentNode->getInterfaces() as $parentType) { + $methods = $parentType->getAllMethods(); + if (isset($methods[$this->getName()])) { + return false; + } + } + + if (is_object($parentType = $parentNode->getParentClass())) { + $methods = $parentType->getAllMethods(); + if (isset($methods[$this->getName()])) { + return false; + } + } + + return true; + } } diff --git a/src/main/php/PHP/PMD/Rule/UnusedFormalParameter.php b/src/main/php/PHP/PMD/Rule/UnusedFormalParameter.php index 0c96d1c3e..495de7ba6 100644 --- a/src/main/php/PHP/PMD/Rule/UnusedFormalParameter.php +++ b/src/main/php/PHP/PMD/Rule/UnusedFormalParameter.php @@ -89,6 +89,10 @@ public function apply(PHP_PMD_AbstractNode $node) return; } + if ($this->_isNotDeclaration($node)) { + return; + } + $this->_nodes = array(); $this->_collectParameters($node); @@ -114,6 +118,23 @@ private function _isAbstractMethod(PHP_PMD_AbstractNode $node) return false; } + /** + * Tests if the given $node is a method and if this method is also + * the initial declaration. + * + * @param PHP_PMD_AbstractNode $node The context method or a function instance. + * + * @return boolean + * @since 1.2.1 + */ + private function _isNotDeclaration(PHP_PMD_AbstractNode $node) + { + if ($node instanceof PHP_PMD_Node_Method) { + return !$node->isDeclaration(); + } + return false; + } + /** * This method extracts all parameters for the given function or method node * and it stores the parameter images in the $_images property. diff --git a/src/site/docx/changes.xml b/src/site/docx/changes.xml index a81c68cea..4b306c5d7 100644 --- a/src/site/docx/changes.xml +++ b/src/site/docx/changes.xml @@ -16,6 +16,10 @@ False detection of unused variable + + + PHPMD should exclude unused parameters from inherited methods + getMethod(); - self::assertInstanceOf(PHP_PMD_Node_Interface::CLAZZ, $method->getParentType()); + $this->assertInstanceOf( + PHP_PMD_Node_Interface::CLAZZ, + $this->getMethod()->getParentType() + ); } /** * testGetParentTypeReturnsClassForClassMethod * * @return void - * @covers PHP_PMD_Node_Method::getParentType - * @group phpmd - * @group phpmd::node - * @group unittest */ public function testGetParentTypeReturnsClassForClassMethod() { @@ -133,10 +124,6 @@ public function testGetParentTypeReturnsClassForClassMethod() * testHasSuppressWarningsExecutesDefaultImplementation * * @return void - * @covers PHP_PMD_Node_Method::hasSuppressWarningsAnnotationFor - * @group phpmd - * @group phpmd::node - * @group unittest */ public function testHasSuppressWarningsExecutesDefaultImplementation() { @@ -151,10 +138,6 @@ public function testHasSuppressWarningsExecutesDefaultImplementation() * testHasSuppressWarningsDelegatesToParentClassMethod * * @return void - * @covers PHP_PMD_Node_Method::hasSuppressWarningsAnnotationFor - * @group phpmd - * @group phpmd::node - * @group unittest */ public function testHasSuppressWarningsDelegatesToParentClassMethod() { @@ -169,10 +152,6 @@ public function testHasSuppressWarningsDelegatesToParentClassMethod() * testHasSuppressWarningsDelegatesToParentInterfaceMethod * * @return void - * @covers PHP_PMD_Node_Method::hasSuppressWarningsAnnotationFor - * @group phpmd - * @group phpmd::node - * @group unittest */ public function testHasSuppressWarningsDelegatesToParentInterfaceMethod() { @@ -182,4 +161,64 @@ public function testHasSuppressWarningsDelegatesToParentInterfaceMethod() $method = $this->getMethod(); $this->assertTrue($method->hasSuppressWarningsAnnotationFor($rule)); } + + /** + * testIsDeclarationReturnsTrueForMethodDeclaration + * + * @return void + * @since 1.2.1 + */ + public function testIsDeclarationReturnsTrueForMethodDeclaration() + { + $method = $this->getMethod(); + $this->assertTrue($method->isDeclaration()); + } + + /** + * testIsDeclarationReturnsTrueForMethodDeclarationWithParent + * + * @return void + * @since 1.2.1 + */ + public function testIsDeclarationReturnsTrueForMethodDeclarationWithParent() + { + $method = $this->getMethod(); + $this->assertTrue($method->isDeclaration()); + } + + /** + * testIsDeclarationReturnsFalseForInheritMethodDeclaration + * + * @return void + * @since 1.2.1 + */ + public function testIsDeclarationReturnsFalseForInheritMethodDeclaration() + { + $method = $this->getMethod(); + $this->assertFalse($method->isDeclaration()); + } + + /** + * testIsDeclarationReturnsFalseForImplementedAbstractMethod + * + * @return void + * @since 1.2.1 + */ + public function testIsDeclarationReturnsFalseForImplementedAbstractMethod() + { + $method = $this->getMethod(); + $this->assertFalse($method->isDeclaration()); + } + + /** + * testIsDeclarationReturnsFalseForImplementedInterfaceMethod + * + * @return void + * @since 1.2.1 + */ + public function testIsDeclarationReturnsFalseForImplementedInterfaceMethod() + { + $method = $this->getMethod(); + $this->assertFalse($method->isDeclaration()); + } } diff --git a/src/test/php/PHP/PMD/Rule/UnusedFormalParameterTest.php b/src/test/php/PHP/PMD/Rule/UnusedFormalParameterTest.php index 533ab1023..b4d82ee58 100644 --- a/src/test/php/PHP/PMD/Rule/UnusedFormalParameterTest.php +++ b/src/test/php/PHP/PMD/Rule/UnusedFormalParameterTest.php @@ -61,6 +61,12 @@ * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version Release: @package_version@ * @link http://phpmd.org + * + * @covers PHP_PMD_Rule_UnusedFormalParameter + * @covers PHP_PMD_Rule_AbstractLocalVariable + * @group phpmd + * @group phpmd::rule + * @group unittest */ class PHP_PMD_Rule_UnusedFormalParameterTest extends PHP_PMD_AbstractTest { @@ -68,11 +74,6 @@ class PHP_PMD_Rule_UnusedFormalParameterTest extends PHP_PMD_AbstractTest * testRuleAppliesToFunctionUnusedFormalParameter * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleAppliesToFunctionUnusedFormalParameter() { @@ -85,11 +86,6 @@ public function testRuleAppliesToFunctionUnusedFormalParameter() * testRuleAppliesToMultipleFunctionUnusedFormalParameter * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleAppliesToMultipleFunctionUnusedFormalParameter() { @@ -102,11 +98,6 @@ public function testRuleAppliesToMultipleFunctionUnusedFormalParameter() * testRuleAppliesToMethodUnusedFormalParameter * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleAppliesToMethodUnusedFormalParameter() { @@ -119,11 +110,6 @@ public function testRuleAppliesToMethodUnusedFormalParameter() * testRuleAppliesToMultipleMethodUnusedFormalParameter * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleAppliesToMultipleMethodUnusedFormalParameter() { @@ -145,11 +131,6 @@ public function testRuleAppliesToMultipleMethodUnusedFormalParameter() * * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleAppliesToFormalParameterWhenSimilarStaticMemberIsAccessed() { @@ -170,11 +151,6 @@ public function testRuleAppliesToFormalParameterWhenSimilarStaticMemberIsAccesse * * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleNotAppliesToFormalParameterUsedInPropertyCompoundVariable() { @@ -195,11 +171,6 @@ public function testRuleNotAppliesToFormalParameterUsedInPropertyCompoundVariabl * * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleNotAppliesToFormalParameterUsedInMethodCompoundVariable() { @@ -212,11 +183,6 @@ public function testRuleNotAppliesToFormalParameterUsedInMethodCompoundVariable( * testRuleDoesNotApplyToAbstractMethodFormalParameter * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleDoesNotApplyToAbstractMethodFormalParameter() { @@ -229,11 +195,6 @@ public function testRuleDoesNotApplyToAbstractMethodFormalParameter() * testRuleDoesNotApplyToInterfaceMethodFormalParameter * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleDoesNotApplyToInterfaceMethodFormalParameter() { @@ -246,11 +207,6 @@ public function testRuleDoesNotApplyToInterfaceMethodFormalParameter() * testRuleDoesNotApplyToInnerFunctionDeclaration * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleDoesNotApplyToInnerFunctionDeclaration() { @@ -272,11 +228,6 @@ public function testRuleDoesNotApplyToInnerFunctionDeclaration() * * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleDoesNotApplyToFormalParameterUsedInCompoundExpression() { @@ -297,11 +248,6 @@ public function testRuleDoesNotApplyToFormalParameterUsedInCompoundExpression() * * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleDoesNotApplyToMethodArgument() { @@ -310,6 +256,11 @@ public function testRuleDoesNotApplyToMethodArgument() $rule->apply($this->getMethod()); } + /** + * testRuleDoesNotApplyToMethodArgumentUsedAsArrayIndex + * + * @return void + */ public function testRuleDoesNotApplyToMethodArgumentUsedAsArrayIndex() { $rule = new PHP_PMD_Rule_UnusedFormalParameter(); @@ -329,11 +280,6 @@ public function testRuleDoesNotApplyToMethodArgumentUsedAsArrayIndex() * * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleDoesNotApplyToParameterUsedAsArrayIndex() { @@ -352,12 +298,8 @@ public function testRuleDoesNotApplyToParameterUsedAsArrayIndex() * } * } * + * * @return void - * @covers PHP_PMD_Rule_UnusedFormalParameter - * @covers PHP_PMD_Rule_AbstractLocalVariable - * @group phpmd - * @group phpmd::rule - * @group unittest */ public function testRuleDoesNotApplyToParameterUsedAsStringIndex() { @@ -367,27 +309,65 @@ public function testRuleDoesNotApplyToParameterUsedAsStringIndex() } /** - * testRuleDoesNotApplyToMethodWithFuncGetArgs - * - * If func_get_args() is called then all parameters are - * automatically referenced without needing them to be referenced - * explicitly - * - * - * class Foo { - * function bar($baz) { - * print_r(func_get_args()); - * } - * } - * - * @group phpmd - * @group phpmd::rule - * @group unittest + * testRuleDoesNotApplyToMethodWithFuncGetArgs + * + * If func_get_args() is called then all parameters are + * automatically referenced without needing them to be referenced + * explicitly + * + * + * class Foo { + * function bar($baz) { + * print_r(func_get_args()); + * } + * } + * + * + * @return void */ public function testRuleDoesNotApplyToMethodWithFuncGetArgs() { $rule = new PHP_PMD_Rule_UnusedFormalParameter(); $rule->setReport($this->getReportMock(0)); - $rule->apply($this->getMethod()); + $rule->apply($this->getMethod()); + } + + /** + * testRuleDoesNotApplyToInheritMethod + * + * @return void + * @since 1.2.1 + */ + public function testRuleDoesNotApplyToInheritMethod() + { + $rule = new PHP_PMD_Rule_UnusedFormalParameter(); + $rule->setReport($this->getReportMock(0)); + $rule->apply($this->getMethod()); + } + + /** + * testRuleDoesNotApplyToImplementedAbstractMethod + * + * @return void + * @since 1.2.1 + */ + public function testRuleDoesNotApplyToImplementedAbstractMethod() + { + $rule = new PHP_PMD_Rule_UnusedFormalParameter(); + $rule->setReport($this->getReportMock(0)); + $rule->apply($this->getMethod()); + } + + /** + * testRuleDoesNotApplyToImplementedInterfaceMethod + * + * @return void + * @since 1.2.1 + */ + public function testRuleDoesNotApplyToImplementedInterfaceMethod() + { + $rule = new PHP_PMD_Rule_UnusedFormalParameter(); + $rule->setReport($this->getReportMock(0)); + $rule->apply($this->getMethod()); } } diff --git a/src/test/resources/files/Node/Method/testIsDeclarationReturnsFalseForImplementedAbstractMethod.php b/src/test/resources/files/Node/Method/testIsDeclarationReturnsFalseForImplementedAbstractMethod.php new file mode 100644 index 000000000..f0cda4167 --- /dev/null +++ b/src/test/resources/files/Node/Method/testIsDeclarationReturnsFalseForImplementedAbstractMethod.php @@ -0,0 +1,14 @@ +