14

I've extended a class of the PSR-2 sniff set. Now the checks are executed two times -- even if my chid class is empty.

Why? And how to do it correctly?


EDIT:

I have an idea now why: Probably the Sniffer processes the rulesets bottom-up -- from the ruleset of the actually called standard to the highest (directly or inderectly included) parent standard. It executes them apparently completely. (Is ist so?) OK, but what to do? How to override parent rulesets -- replace their classes but custom ones and deactivate single rules?


Code:

[CodeSniffer]/Standards/ZF/ruleset.xml

<?xml version="1.0"?>
<ruleset name="ZF">
    <description>...</description>
    <!-- Include the whole PSR-2 standard -->
    <rule ref="PSR2"/>
    <!-- Argument lists MAY be split across multiple lines, where each subsequent line is indented once. When doing so, the first item in the list MUST be on the next line, and there MUST be only one argument per line. When the argument list is split across multiple lines, the closing parenthesis and opening brace MUST be placed together on their own line with one space between them. -->
    <rule ref="ZF.Functions.MultiLineFunctionDeclaration"/>
    ... just comments yet
    <!-- 5.7.2. Closure Definitions -->
    <!-- TODO: Revome unwished check: Space after the function keyword is required. -->
    <!-- 5.7.3. Function and Method Usage -->
    <!-- TODO: Revome unwished check: one argument per line in a multi-line function call is required. -->
    ... just comments yet
</ruleset>

[CodeSniffer]/Standards/ZF/Sniffs/Functions/MultiLineFunctionDeclarationSniff.php

<?php
if (class_exists('PEAR_Sniffs_Functions_FunctionDeclarationSniff', true) === false) {
    $error = 'Class PEAR_Sniffs_Functions_FunctionDeclarationSniff not found';
    throw new PHP_CodeSniffer_Exception($error);
}

class ZF_Sniffs_Functions_MultiLineFunctionDeclarationSniff extends PEAR_Sniffs_Functions_FunctionDeclarationSniff
{
    public function processMultiLineDeclaration(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens)
    {
    }

    public function processBracket(PHP_CodeSniffer_File $phpcsFile, $openBracket, $tokens, $type='function')
    {
    }
}
?>

Call:

$ phpcs --standard=ZF -sw /path/to/Test.php

FILE: /path/to/Test.php
--------------------------------------------------------------------------------
FOUND 2 ERROR(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
 106 | ERROR | Expected 1 space after FUNCTION keyword; 0 found
     |       | (ZF.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction)
 106 | ERROR | Expected 1 space after FUNCTION keyword; 0 found
     |       | (Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction)
--------------------------------------------------------------------------------

Background information:

I want to write a PHP CodeSniffer ruleset for a Zend Framework 2 project. Around half of the Zend Framework 2 Coding Standards is already implemented in the PSR-2 sniffs folder.

The goal now is not to implement the whole Zend standard. I want to start with PSR-2 and maybe add/implement other Zend rules step by step.

The Problem is, that the PSR-2 sniffs also contain a couple of checks, that break the Zend standards. So I have to override these sniffs. Example: /path/to/php/PHP/CodeSniffer/Standards/Squiz/Sniffs/Functions/MultiLineFunctionDeclarationSniff.php (requires a space after the function keyword in closures). PSR-2 is based on PSR-1 and it uses this sniff. So I have to overwrite them.

automatix
  • 14,018
  • 26
  • 105
  • 230
  • Create your own 'standard' and just include the ones you want. I did this to create our company rules which are not the same as the PSRs. Therefore, I just include those that I want. – Steven Scott Nov 05 '13 at 22:47
  • I've already done it. `ZF` is my custom standard, that is based on PSR-2. But now I have troubles with doublechecks. – automatix Nov 05 '13 at 23:06
  • Can you add -s to your phpcs command so I see which sniffs are producing those errors (phpcs --standard=ZF -sw /path/to/Test.php). The solution is probably going to be to exclude the sniff or exclude the message. – Greg Sherwood Nov 05 '13 at 23:10
  • Just updated the question. Now I also see, that the errors are produced by the rules of my custom ZF standrad first and then by Squiz. And it's equal, whether the overriding methods are copies of the Squiz' methods or empty. It's even equal, whether they exist or my my chuild class is empty. – automatix Nov 06 '13 at 09:40
  • If you get a positive result, do not forget to give a link! –  Nov 12 '13 at 20:22
  • What do you mean? Link to what? – automatix Nov 12 '13 at 23:30

1 Answers1

25

Excluding of a single sniff is easy done with the exclude direction, e.g.:

<?xml version="1.0"?>
<ruleset name="ZF">
    <description>...</description>
    <!-- Include the whole PSR-2 standard -->
    <rule ref="PSR2">
        <!-- to disable a single error -->
        <exclude name="Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction"/>
        <!-- or to disable the whole sniff -->
        <exclude name="Squiz.Functions.MultiLineFunctionDeclaration"/>
    </rule>
    ...
</ruleset>

instead of

<?xml version="1.0"?>
<ruleset name="ZF">
    <description>...</description>
    <!-- Include the whole PSR-2 standard -->
    <rule ref="PSR2"/>
    ...
</ruleset>

Overriding = Excluding of a sniff + Creating of an alternative one.

See also the annotated sample ruleset.xml in the PHP CodeSniffer manual.

automatix
  • 14,018
  • 26
  • 105
  • 230