-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 0fa206e
Showing
18 changed files
with
3,198 additions
and
0 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
/* | ||
* This file is part of the Vairogs package. | ||
* | ||
* (c) Dāvis Zālītis (k0d3r1s) <davis@vairogs.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Vairogs\PhpCsFixerCustomFixers\Fixer; | ||
|
||
use PhpCsFixer\Tokenizer\Token; | ||
use PhpCsFixer\Tokenizer\Tokens; | ||
use SplFileInfo; | ||
use Vairogs\Component\Functions\Preg\_Replace; | ||
use Vairogs\PhpCsFixerCustomFixers\PhpCsFixer\AbstractFixer; | ||
|
||
use function assert; | ||
use function is_int; | ||
use function stripos; | ||
use function substr; | ||
|
||
use const T_DECLARE; | ||
use const T_OPEN_TAG; | ||
use const T_WHITESPACE; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
final class DeclareAfterOpeningTagFixer extends AbstractFixer | ||
{ | ||
public function applyFix( | ||
SplFileInfo $file, | ||
Tokens $tokens, | ||
): void { | ||
if (!$tokens[0]->isGivenKind(T_OPEN_TAG)) { | ||
return; | ||
} | ||
|
||
$openingTagTokenContent = $tokens[0]->getContent(); | ||
|
||
$declareIndex = $tokens->getNextTokenOfKind(0, [[T_DECLARE]]); | ||
assert(is_int($declareIndex)); | ||
|
||
$openParenthesisIndex = $tokens->getNextMeaningfulToken($declareIndex); | ||
assert(is_int($openParenthesisIndex)); | ||
|
||
$closeParenthesisIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openParenthesisIndex); | ||
|
||
if (false === stripos($tokens->generatePartialCode($openParenthesisIndex, $closeParenthesisIndex), 'strict_types')) { | ||
return; | ||
} | ||
|
||
$tokens[0] = new Token([T_OPEN_TAG, substr($openingTagTokenContent, 0, 5) . ' ']); | ||
|
||
if ($declareIndex <= 2) { | ||
$tokens->clearRange(1, $declareIndex - 1); | ||
|
||
return; | ||
} | ||
|
||
$semicolonIndex = $tokens->getNextMeaningfulToken($closeParenthesisIndex); | ||
assert(is_int($semicolonIndex)); | ||
|
||
$tokensToInsert = []; | ||
for ($index = $declareIndex; $index <= $semicolonIndex; $index++) { | ||
$tokensToInsert[] = $tokens[$index]; | ||
} | ||
|
||
if ($tokens[1]->isGivenKind(T_WHITESPACE)) { | ||
$tokens[1] = new Token([T_WHITESPACE, substr($openingTagTokenContent, 5) . $tokens[1]->getContent()]); | ||
} else { | ||
$tokensToInsert[] = new Token([T_WHITESPACE, substr($openingTagTokenContent, 5)]); | ||
} | ||
|
||
if ($tokens[$semicolonIndex + 1]->isGivenKind(T_WHITESPACE)) { | ||
$content = (new class { | ||
use _Replace; | ||
})::replace('/^(\\R?)(?=\\R)/', '', $tokens[$semicolonIndex + 1]->getContent()); | ||
|
||
$tokens->ensureWhitespaceAtIndex($semicolonIndex + 1, 0, $content); | ||
} | ||
|
||
$tokens->clearRange($declareIndex + 1, $semicolonIndex); | ||
self::removeWithLinesIfPossible($tokens, $declareIndex); | ||
|
||
$tokens->insertAt(1, $tokensToInsert); | ||
} | ||
|
||
public function getDocumentation(): string | ||
{ | ||
return 'Declare statement for strict types must be placed on the same line, after the opening tag.'; | ||
} | ||
|
||
public function getSampleCode(): string | ||
{ | ||
return "<?php\n\$foo;\ndeclare(strict_types=1);\n\$bar;\n"; | ||
} | ||
|
||
public function isCandidate( | ||
Tokens $tokens, | ||
): bool { | ||
return $tokens->isTokenKindFound(T_DECLARE); | ||
} | ||
} |
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,118 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
/* | ||
* This file is part of the Vairogs package. | ||
* | ||
* (c) Dāvis Zālītis (k0d3r1s) <davis@vairogs.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Vairogs\PhpCsFixerCustomFixers\Fixer; | ||
|
||
use Doctrine\Migrations\AbstractMigration; | ||
use PhpCsFixer\Tokenizer\Token; | ||
use PhpCsFixer\Tokenizer\Tokens; | ||
use SplFileInfo; | ||
use Vairogs\PhpCsFixerCustomFixers\PhpCsFixer\AbstractFixer; | ||
|
||
use function class_exists; | ||
use function explode; | ||
use function implode; | ||
use function in_array; | ||
use function trim; | ||
|
||
use const T_COMMENT; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
final class DoctrineMigrationsFixer extends AbstractFixer | ||
{ | ||
public function getDocumentation(): string | ||
{ | ||
return 'Unnecessary comments MUST BE removed from Doctrine migrations'; | ||
} | ||
|
||
public function getSampleCode(): string | ||
{ | ||
return <<<'SPEC' | ||
<?php declare(strict_types=1); | ||
namespace Doctrine\Migrations; | ||
use Doctrine\DBAL\Schema\Schema; | ||
use Doctrine\Migrations\AbstractMigration; | ||
/** | ||
* Auto-generated Migration: Please modify to your needs! | ||
*/ | ||
final class VersionTest extends AbstractMigration | ||
{ | ||
public function getDescription() | ||
{ | ||
return ''; | ||
} | ||
public function up(Schema $schema) | ||
{ | ||
// this up() migration is auto-generated, please modify it to your needs | ||
} | ||
public function down(Schema $schema) | ||
{ | ||
// this down() migration is auto-generated, please modify it to your needs | ||
} | ||
} | ||
SPEC; | ||
} | ||
|
||
public function isCandidate( | ||
Tokens $tokens, | ||
): bool { | ||
return class_exists(AbstractMigration::class) && $this->extendsClass($tokens, AbstractMigration::class); | ||
} | ||
|
||
protected function applyFix( | ||
SplFileInfo $file, | ||
Tokens $tokens, | ||
): void { | ||
$this->removeUselessComments($tokens); | ||
} | ||
|
||
private function removeUselessComments( | ||
Tokens $tokens, | ||
): void { | ||
$blacklist = [ | ||
'Auto-generated Migration: Please modify to your needs!', | ||
'this up() migration is auto-generated, please modify it to your needs', | ||
'this down() migration is auto-generated, please modify it to your needs', | ||
]; | ||
|
||
foreach ($this->getComments($tokens) as $position => $comment) { | ||
$lines = explode("\n", $comment->getContent()); | ||
$changed = false; | ||
|
||
foreach ($lines as $index => $line) { | ||
if (in_array(trim($line, '/* '), $blacklist, true)) { | ||
unset($lines[$index]); | ||
$changed = true; | ||
} | ||
} | ||
|
||
if (false === $changed) { | ||
continue; | ||
} | ||
|
||
if (empty(trim(implode("\n", $lines), " /*\n"))) { | ||
$tokens->clearAt($position); | ||
$tokens->removeTrailingWhitespace($position); | ||
|
||
continue; | ||
} | ||
|
||
$tokens[$position] = new Token([T_COMMENT, implode("\n", $lines)]); | ||
} | ||
} | ||
} |
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,103 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
/* | ||
* This file is part of the Vairogs package. | ||
* | ||
* (c) Dāvis Zālītis (k0d3r1s) <davis@vairogs.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Vairogs\PhpCsFixerCustomFixers\Fixer; | ||
|
||
use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer; | ||
use PhpCsFixer\Tokenizer\Token; | ||
use PhpCsFixer\Tokenizer\Tokens; | ||
use SplFileInfo; | ||
use Vairogs\PhpCsFixerCustomFixers\PhpCsFixer\AbstractFixer; | ||
|
||
use function assert; | ||
use function count; | ||
use function is_int; | ||
|
||
use const T_ISSET; | ||
use const T_STRING; | ||
use const T_WHITESPACE; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
final class IssetToArrayKeyExistsFixer extends AbstractFixer | ||
{ | ||
public function applyFix( | ||
SplFileInfo $file, | ||
Tokens $tokens, | ||
): void { | ||
for ($index = $tokens->count() - 1; $index > 0; $index--) { | ||
if (!$tokens[$index]->isGivenKind(T_ISSET)) { | ||
continue; | ||
} | ||
|
||
if (1 !== count((new FunctionsAnalyzer())->getFunctionArguments($tokens, $index))) { | ||
continue; | ||
} | ||
|
||
$openParenthesis = $tokens->getNextMeaningfulToken($index); | ||
assert(is_int($openParenthesis)); | ||
|
||
$closeParenthesis = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openParenthesis); | ||
|
||
$closeBrackets = $tokens->getPrevMeaningfulToken($closeParenthesis); | ||
assert(is_int($closeBrackets)); | ||
if (!$tokens[$closeBrackets]->equals(']')) { | ||
continue; | ||
} | ||
|
||
$openBrackets = $tokens->findBlockStart(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $closeBrackets); | ||
|
||
$keyStartIndex = $tokens->getNextMeaningfulToken($openBrackets); | ||
assert(is_int($keyStartIndex)); | ||
$keyEndIndex = $tokens->getPrevMeaningfulToken($closeBrackets); | ||
|
||
$keyTokens = []; | ||
for ($i = $keyStartIndex; $i <= $keyEndIndex; $i++) { | ||
if ($tokens[$i]->equals('')) { | ||
continue; | ||
} | ||
$keyTokens[] = $tokens[$i]; | ||
} | ||
$keyTokens[] = new Token(','); | ||
$keyTokens[] = new Token([T_WHITESPACE, ' ']); | ||
|
||
$tokens->clearRange($openBrackets, $closeBrackets); | ||
$tokens->insertAt($openParenthesis + 1, $keyTokens); | ||
$tokens[$index] = new Token([T_STRING, 'array_key_exists']); | ||
} | ||
} | ||
|
||
public function getDocumentation(): string | ||
{ | ||
return 'Function `array_key_exists` must be used instead of `isset` when possible.'; | ||
} | ||
|
||
public function getSampleCode(): string | ||
{ | ||
return '<?php | ||
if (isset($array[$key])) { | ||
echo $array[$key]; | ||
} | ||
'; | ||
} | ||
|
||
public function isCandidate( | ||
Tokens $tokens, | ||
): bool { | ||
return $tokens->isTokenKindFound(T_ISSET); | ||
} | ||
|
||
public function isRisky(): bool | ||
{ | ||
return true; | ||
} | ||
} |
Oops, something went wrong.