-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement ExceptionsPunctuation (#41)
- Loading branch information
1 parent
58f5ee6
commit 37ad12b
Showing
5 changed files
with
361 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
172 changes: 172 additions & 0 deletions
172
src/PedroTroller/CS/Fixer/CodingStyle/ExceptionsPunctuationFixer.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PedroTroller\CS\Fixer\CodingStyle; | ||
|
||
use PedroTroller\CS\Fixer\AbstractFixer; | ||
use PhpCsFixer\Tokenizer\Token; | ||
use PhpCsFixer\Tokenizer\Tokens; | ||
use SplFileInfo; | ||
|
||
final class ExceptionsPunctuationFixer extends AbstractFixer | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function isCandidate(Tokens $tokens) | ||
{ | ||
return $tokens->isTokenKindFound(T_THROW); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function isRisky() | ||
{ | ||
return true; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getSampleCode() | ||
{ | ||
return <<<'PHP' | ||
<?php | ||
use LogicException; | ||
class MyClass { | ||
public function fun1() | ||
{ | ||
throw new \Exception('This is the message'); | ||
} | ||
public function fun2($data) | ||
{ | ||
throw new LogicException(sprintf('This is the %s', 'message')); | ||
} | ||
} | ||
PHP; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getDocumentation() | ||
{ | ||
return 'Exception messages MUST ends by ".", "…", "?" or "!".<br /><br /><i>Risky: will change the exception message.</i>'; | ||
} | ||
|
||
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)]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace tests\UseCase; | ||
|
||
use PedroTroller\CS\Fixer\CodingStyle\ExceptionsPunctuationFixer; | ||
use tests\UseCase; | ||
|
||
final class ExceptionsPunctuation implements UseCase | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getFixer() | ||
{ | ||
return new ExceptionsPunctuationFixer(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getRawScript() | ||
{ | ||
return <<<'PHP' | ||
<?php | ||
use LogicException; | ||
use RuntimeException; | ||
class MyClass { | ||
public function fun1() | ||
{ | ||
throw new \Exception('This is the message'); | ||
} | ||
public function fun2($data) | ||
{ | ||
throw new LogicException(sprintf('This is the %s', 'message')); | ||
} | ||
public function fun3($data) | ||
{ | ||
throw new RuntimeException('This is the '.message); | ||
} | ||
public function fun4($data) | ||
{ | ||
throw new RuntimeException('Are you sure ?'); | ||
} | ||
} | ||
PHP; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getExpectation() | ||
{ | ||
return <<<'PHP' | ||
<?php | ||
use LogicException; | ||
use RuntimeException; | ||
class MyClass { | ||
public function fun1() | ||
{ | ||
throw new \Exception('This is the message.'); | ||
} | ||
public function fun2($data) | ||
{ | ||
throw new LogicException(sprintf('This is the %s.', 'message')); | ||
} | ||
public function fun3($data) | ||
{ | ||
throw new RuntimeException('This is the '.message); | ||
} | ||
public function fun4($data) | ||
{ | ||
throw new RuntimeException('Are you sure ?'); | ||
} | ||
} | ||
PHP; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getMinSupportedPhpVersion() | ||
{ | ||
return 0; | ||
} | ||
} |