Как правильно переопределить правило /sniff в наборе правил PHP CodeSniffer и избежать двойной проверки кода?

Я расширил класс набора флюидов PSR-2. Теперь проверки выполняются два раза - даже если мой класс chid пуст.

Почему? И как это сделать правильно?


EDIT:

Теперь у меня есть идея, почему: Вероятно, Sniffer обрабатывает наборы правил снизу вверх - от набора правил фактически называемого стандартного до самого высокого (напрямую или безразлично) родительского стандарта. Он полностью их исполняет. (Is ist?) Хорошо, но что делать? Как переопределить родительские наборы правил - заменить их классы, но пользовательские и деактивировать отдельные правила?


код:

[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')
    {
    }
}
?>

Вызов:

$ 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)
--------------------------------------------------------------------------------

Фоновая информация:

Я хочу написать набор правил PHP CodeSniffer для проекта Zend Framework 2. Около половины стандартов кодирования Zend Framework 2 уже реализовано в папке PSR-2.

Теперь цель не в том, чтобы реализовать весь стандарт Zend. Я хочу начать с PSR-2 и, возможно, добавить/реализовать другие правила Zend шаг за шагом.

Проблема заключается в том, что флипы PSR-2 также содержат пару проверок, которые нарушают стандарты Zend. Поэтому я должен переопределить эти нюансы. Пример: /path/to/php/PHP/CodeSniffer/Standards/Squiz/Sniffs/Functions/MultiLineFunctionDeclarationSniff.php (требуется пробел после ключевого слова function в закрытии). PSR-2 основан на PSR-1, и он использует этот sniff. Поэтому я должен перезаписать их.

Ответ 1

Исключение одного sniff легко выполняется с помощью направления exclude, например:

<?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>

вместо

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

Переопределение= Исключение sniff + Создание альтернативного.

См. также аннотированный образец ruleset.xml в руководстве PHP CodeSniffer.