matthiasnoback / code-sniffer-sniff-dsl
PHP_CodeSniffer 的嗅探 DSL
v0.3.0
2014-03-21 10:43 UTC
Requires
- beberlei/assert: 2.*
- squizlabs/php_codesniffer: ~1.5
Requires (Dev)
- phpunit/phpunit: ~3.7
This package is auto-updated.
Last update: 2024-08-29 03:58:02 UTC
README
使用这个库,您可以轻松编写用于 PHP_CodeSniffer 的代码嗅探。当您不使用这个 DSL 时,您会发现自己在编写大量特定且不可重用的代码。
示例
假设您想创建一个代码嗅探器,如果 PHP 文件顶部有(自动生成的)文档注释(这被称为“文件注释”),则会触发错误。您首先应该为这种情况创建一个“匹配器”
<?php namespace Matthias\PhpCodingStandard\Sniffs\Commenting; use Matthias\Codesniffer\MatcherInterface; use Matthias\Codesniffer\Sequence\SequenceBuilder; class FileCommentMatcher implements MatcherInterface { public function matches(array $tokens, $tokenIndex) { $forwardSequence = SequenceBuilder::create() ->lookingForward() ->expect() ->token(T_WHITESPACE, ' ') // space ->token(T_STRING) // namespace root ->quantity() // sub namespaces ->any() ->succeeding() ->token(T_NS_SEPARATOR) ->token(T_STRING) ->end() ->end() ->token(T_SEMICOLON) // end of namespace declaration ->quantity() // two blank lines ->exactly(2) ->token(T_WHITESPACE, "\n") ->end() ->end() ->build(); $backwardSequence = SequenceBuilder::create() ->lookingBackward() ->expect() ->quantity() // the first new line is part of the PHP open tag ->exactly(1) ->token(T_WHITESPACE, "\n") ->end() ->end() ->build(); $oneBlankLineAfterNamespace = $forwardSequence->matches($tokens, $tokenIndex); $oneBlankLineBeforeNamespace = $backwardSequence->matches($tokens, $tokenIndex); return $oneBlankLineBeforeNamespace && $oneBlankLineAfterNamespace; } }
接下来,实际的嗅探类相当简单
<?php use Matthias\PhpCodingStandard\Sniffs\Commenting\FileCommentMatcher; class PhpCodingStandard_Sniffs_Commenting_NoFileCommentForClassSniff implements \PHP_CodeSniffer_Sniff { public function register() { // this sniff will be triggered when the code sniffer encounters a T_DOC_COMMENT token return array( T_DOC_COMMENT ); } public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // create the matcher $matcher = new FileCommentMatcher(); // use the matcher to determine if the current token is a file comment if ($matcher->matches($tokens, $stackPtr)) { $phpcsFile->addError('File should not have a file comment', $stackPtr); } } }