diff --git a/README.md b/README.md index ab7610a..fb84e65 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,71 @@ return $config; // ``` +## PedroTroller/exceptions_punctuation + +Exception messages MUST ends by ".", "…", "?" or "!".

Risky: will change the exception message. + +### Configuration + +```php +// .php_cs.dist +setRules([ + // ... + 'PedroTroller/exceptions_punctuation' => true, + // ... + ]) + // ... + ->registerCustomFixers(new PedroTroller\CS\Fixer\Fixers()) +; + +return $config; +``` + +**OR** using my [rule list builder](doc/rule-set-factory.md). + +```php +// .php_cs.dist +setRules(PedroTroller\CS\Fixer\RuleSetFactory::create() + ->enable('PedroTroller/exceptions_punctuation') + ->getRules() + ]) + // ... + ->registerCustomFixers(new PedroTroller\CS\Fixer\Fixers()) +; + +return $config; +``` + +### Fixes + +```diff +--- Original // 80 chars ++++ New // +@@ @@ // + class MyClass { // + public function fun1() // + { // +- throw new \Exception('This is the message'); // ++ throw new \Exception('This is the message.'); // + } // + // + public function fun2($data) // + { // +- throw new LogicException(sprintf('This is the %s', 'message')); // ++ throw new LogicException(sprintf('This is the %s.', 'message')); // + } // + } // + // +``` + ## PedroTroller/forbidden_functions Forbidden functions MUST BE commented diff --git a/bin/doc.twig b/bin/doc.twig index e16b5cc..9719f05 100644 --- a/bin/doc.twig +++ b/bin/doc.twig @@ -31,7 +31,7 @@ return $config; ## {{ fixer.name }} -{{ fixer.doc.summary}} +{{ fixer.doc.summary|raw }} {% if fixer.deprecated %} **DEPRECATED** diff --git a/src/PedroTroller/CS/Fixer/CodingStyle/ExceptionsPunctuationFixer.php b/src/PedroTroller/CS/Fixer/CodingStyle/ExceptionsPunctuationFixer.php new file mode 100644 index 0000000..5c04c0b --- /dev/null +++ b/src/PedroTroller/CS/Fixer/CodingStyle/ExceptionsPunctuationFixer.php @@ -0,0 +1,172 @@ +isTokenKindFound(T_THROW); + } + + /** + * {@inheritdoc} + */ + public function isRisky() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function getSampleCode() + { + return <<<'PHP' +
Risky: will change the exception message.'; + } + + protected function applyFix(SplFileInfo $file, Tokens $tokens) + { + $cases = $this->analyze($tokens)->findAllSequences([ + [ + [T_THROW], + [T_NEW], + [T_STRING], + '(', + [T_CONSTANT_ENCAPSED_STRING], + ',', + ], + [ + [T_THROW], + [T_NEW], + [T_NS_SEPARATOR], + [T_STRING], + '(', + [T_CONSTANT_ENCAPSED_STRING], + ',', + ], + [ + [T_THROW], + [T_NEW], + [T_STRING], + '(', + [T_STRING, 'sprintf'], + '(', + [T_CONSTANT_ENCAPSED_STRING], + ',', + ], + [ + [T_THROW], + [T_NEW], + [T_NS_SEPARATOR], + [T_STRING], + '(', + [T_STRING, 'sprintf'], + '(', + [T_CONSTANT_ENCAPSED_STRING], + ',', + ], + [ + [T_THROW], + [T_NEW], + [T_STRING], + '(', + [T_CONSTANT_ENCAPSED_STRING], + ')', + ], + [ + [T_THROW], + [T_NEW], + [T_NS_SEPARATOR], + [T_STRING], + '(', + [T_CONSTANT_ENCAPSED_STRING], + ')', + ], + [ + [T_THROW], + [T_NEW], + [T_STRING], + '(', + [T_STRING, 'sprintf'], + '(', + [T_CONSTANT_ENCAPSED_STRING], + ')', + ], + [ + [T_THROW], + [T_NEW], + [T_NS_SEPARATOR], + [T_STRING], + '(', + [T_STRING, 'sprintf'], + '(', + [T_CONSTANT_ENCAPSED_STRING], + ')', + ], + ]); + + foreach ($cases as $case) { + $keys = array_keys($case); + array_pop($keys); + array_pop($case); + $tokens[end($keys)] = $this->cleanupMessage(end($case)); + } + } + + /** + * @return Token + */ + private function cleanupMessage(Token $token) + { + $content = $token->getContent(); + $chars = str_split($content); + $quotes = array_shift($chars); + $quotes = array_pop($chars); + $ponctuation = end($chars); + + switch ($ponctuation) { + case '.': + case '…': + case '?': + case '!': + return $token; + } + + return new Token([T_CONSTANT_ENCAPSED_STRING, sprintf('%s%s.%s', $quotes, implode($chars), $quotes)]); + } +} diff --git a/src/PedroTroller/CS/Fixer/TokensAnalyzer.php b/src/PedroTroller/CS/Fixer/TokensAnalyzer.php index f865cd3..59de011 100644 --- a/src/PedroTroller/CS/Fixer/TokensAnalyzer.php +++ b/src/PedroTroller/CS/Fixer/TokensAnalyzer.php @@ -406,4 +406,30 @@ public function getLineIndentation($index) return end($parts); } + + /** + * @return array + */ + public function findAllSequences(array $seqs) + { + $sequences = []; + + foreach ($seqs as $seq) { + $index = 0; + + do { + $extract = $this->tokens->findSequence($seq, (int) $index); + + if (null !== $extract) { + $keys = array_keys($extract); + $index = end($keys) + 1; + $sequences[reset($keys)] = $extract; + } + } while (null !== $extract); + } + + ksort($sequences); + + return $sequences; + } } diff --git a/tests/UseCase/ExceptionsPunctuation.php b/tests/UseCase/ExceptionsPunctuation.php new file mode 100644 index 0000000..b3dd708 --- /dev/null +++ b/tests/UseCase/ExceptionsPunctuation.php @@ -0,0 +1,97 @@ +