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 @@
+