Skip to content

Commit

Permalink
Merge pull request #496 from eeree/issue-62
Browse files Browse the repository at this point in the history
Add rule for PHP's @ operator
  • Loading branch information
kylekatarnls committed Apr 29, 2020
2 parents 77681d4 + 6855506 commit ac1dd52
Show file tree
Hide file tree
Showing 9 changed files with 273 additions and 1 deletion.
50 changes: 50 additions & 0 deletions src/main/php/PHPMD/Rule/CleanCode/ErrorControlOperator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) Manuel Pichler <mapi@phpmd.org>.
* 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 <mapi@phpmd.org>
* @copyright Manuel Pichler. All rights reserved.
* @license https://opensource.org/licenses/bsd-license.php BSD License
* @link http://phpmd.org/
*/

namespace PHPMD\Rule\CleanCode;

use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;

/**
* Error Control Operators Rule
*
* This rule detects usage of error control operator (@).
*
* @author Kamil Szymanaski <kamil.szymanski@gmail.com>
* @link http://php.net/manual/en/language.operators.errorcontrol.php
*/
class ErrorControlOperator extends AbstractRule implements MethodAware, FunctionAware
{
/**
* Loops trough all class or function nodes and looks for '@' sign.
*
* @param AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->findChildrenOfType('UnaryExpression') as $unaryExpression) {
if ($unaryExpression->getImage() === '@') {
$this->addViolation($node, array($unaryExpression->getBeginLine()));
}
}
}
}
22 changes: 22 additions & 0 deletions src/main/resources/rulesets/cleancode.xml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,28 @@ function createArray() {
</example>
</rule>

<rule name="ErrorControlOperator"
message="Remove error control operator '@' on line {0}."
class="PHPMD\Rule\CleanCode\ErrorControlOperator"
externalInfoUrl="http://phpmd.org/rules/cleancode.html#errorcontroloperator">
<description>
<![CDATA[
Error suppression should be avoided if possible as it doesn't just suppress the error, that
you are trying to stop, but will also suppress errors that you didn't predict would ever occur.
Consider changing error_reporting() level and/or setting up your own error handler.
]]>
</description>
<priority>1</priority>
<example>
<![CDATA[
function foo($filePath) {
$file = @fopen($filPath); // hides exceptions
$key = @$array[$notExistingKey]; // assigns null to $key
}
]]>
</example>
</rule>

<rule name="MissingImport"
since="2.7.0"
message="Missing class import via use statement (line '{0}', column '{1}')."
Expand Down
16 changes: 15 additions & 1 deletion src/site/rst/rules/cleancode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ Example: ::
];
}

ErrorControlOperator
====================

Since: PHPMD 2.9.0

Error suppression should be avoided if possible as it doesn't just suppress the error, that you are trying to stop, but will also suppress errors that you didn't predict would ever occur. Moreover it can slow down the execution of your code. Consider changing error_reporting() level and/or setting up your own error handler.

Example: ::

function foo($filePath) {
$file = @fopen($filPath); // hides exceptions
$key = @$array[$notExistingKey]; // assigns null to $key
}

MissingImport
=============

Expand Down Expand Up @@ -138,4 +152,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/

1 change: 1 addition & 0 deletions src/site/rst/rules/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Clean Code Rules
- `DuplicateArrayKey <cleancode.html#duplicatearraykey>`_: Defining another value for the same key in an array literal overrides the previous key/value, which makes it effectively an unused code. If it's known from the beginning that the key will have different value, there is usually no point in defining first one.
- `MissingImport <cleancode.html#missingimport>`_: Importing all external classes in a file through use statements makes them clearly visible.
- `UndefinedVariable <cleancode.html#undefinedvariable>`_: Detects when a variable is used that has not been defined before.
- `ErrorControlOperator <cleancode.html#errorcontroloperator>`_: Error suppression should be avoided if possible as it doesn't just suppress the error, that you are trying to stop, but will also suppress errors that you didn't predict would ever occur. Moreover it can slow down the execution of your code. Consider changing error_reporting() level and/or setting up your own error handler.

Code Size Rules
===============
Expand Down
67 changes: 67 additions & 0 deletions src/test/php/PHPMD/Rule/CleanCode/ErrorControlOperatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) Manuel Pichler <mapi@phpmd.org>.
* 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 <mapi@phpmd.org>
* @copyright Manuel Pichler. All rights reserved.
* @license https://opensource.org/licenses/bsd-license.php BSD License
* @link http://phpmd.org/
*/

namespace PHPMD\Rule\CleanCode;

use PHPMD\AbstractTest;

/**
* Error Control Operator Test
*
* @coversDefaultClass \PHPMD\Rule\CleanCode\ErrorControlOperator
*/
class ErrorControlOperatorTest extends AbstractTest
{
/**
* Tests that the rule does not apply to unary operators in functions
*
* @return void
* @covers ::apply
*/
public function testDoesNotApplyToOtherUnaryOperatorsInFunction()
{
$rule = new ErrorControlOperator();
$rule->setReport($this->getReportWithOneViolation());
$rule->apply($this->getFunction());
}

/**
* Tests that the rule applies error control operators to functions
*
* @return void
* @covers ::apply
*/
public function testAppliesToErrorControlOperatorInFunction()
{
$rule = new ErrorControlOperator();
$rule->setReport($this->getReportMock(3));
$rule->apply($this->getFunction());
}

/**
* Tests that the rule applies error control operators to classes and methods
*
* @return void
* @covers ::apply
*/
public function testAppliedToClassesAndMethods()
{
$rule = new ErrorControlOperator();
$rule->setReport($this->getReportMock(6));
$rule->apply($this->getClass());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,15 @@ public function testRuleNotAppliesToMethodWithinNamespaceByDefault()

/**
* Get a configured DevelopmentCodeFragment rule
*
* @return DevelopmentCodeFragment
*/
private function getRule()
{
$rule = new DevelopmentCodeFragment();
$rule->addProperty('unwanted-functions', 'var_dump,print_r,debug_zval_dump,debug_print_backtrace');
$rule->addProperty('ignore-namespaces', 'false');

return $rule;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) Manuel Pichler <mapi@phpmd.org>.
* 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 <mapi@phpmd.org>
* @copyright Manuel Pichler. All rights reserved.
* @license https://opensource.org/licenses/bsd-license.php BSD License
* @link http://phpmd.org/
*/

/**
* Class testAppliedToClassesAndMethods
*/
class testAppliedToClassesAndMethods
{
/**
* @var string
*/
private $baz = 'baz';

/**
* testAppliedToClassesAndMethods
*/
public function testAppliedToClassesAndMethods()
{
$foo = @$this->fooBar();
++$foo;
@!$baz = 1 / 0;
if (@is_readable(__FILE__)) {
$bar = new DateTime('now');
@$baz = $bar;
}
$this->baz = !$foo;
}

/**
* fooBar
*
* @return int
*/
private function fooBar()
{
@$foo = $this->baz / 0;
@$baz = !$foo;

return 2;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) Manuel Pichler <mapi@phpmd.org>.
* 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 <mapi@phpmd.org>
* @copyright Manuel Pichler. All rights reserved.
* @license https://opensource.org/licenses/bsd-license.php BSD License
* @link http://phpmd.org/
*/

/**
* testAppliesToErrorControlOperatorInFunction
*
* @return array
*/
function testAppliesToErrorControlOperatorInFunction()
{
$foo = @debug_backtrace();
$bar = @is_dir(__FILE__);
@$average = 3 / 0;

return [$foo, $bar, $average];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) Manuel Pichler <mapi@phpmd.org>.
* 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 <mapi@phpmd.org>
* @copyright Manuel Pichler. All rights reserved.
* @license https://opensource.org/licenses/bsd-license.php BSD License
* @link http://phpmd.org/
*/

/**
* testDoesNotApplyToOtherUnaryOperatorsInFunction
*
* @return bool
*/
function testDoesNotApplyToOtherUnaryOperatorsInFunction()
{
@$foo = is_dir(__DIR__);
$bar = !$foo;
++$bar;
$baz = ++$bar;

return !--$baz;
}

0 comments on commit ac1dd52

Please sign in to comment.