mirror of
https://github.com/elyby/php-code-style.git
synced 2025-05-31 14:12:05 +05:30
First implementation
This commit is contained in:
13
src/Fixer/AbstractFixer.php
Normal file
13
src/Fixer/AbstractFixer.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace Ely\CS\Fixer;
|
||||
|
||||
abstract class AbstractFixer extends \PhpCsFixer\AbstractFixer {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName() {
|
||||
return sprintf('Ely/%s', parent::getName());
|
||||
}
|
||||
|
||||
}
|
||||
179
src/Fixer/Operator/NewWithBracesFixer.php
Normal file
179
src/Fixer/Operator/NewWithBracesFixer.php
Normal file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Fixer\Operator;
|
||||
|
||||
use Ely\CS\Fixer\AbstractFixer;
|
||||
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
|
||||
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
|
||||
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\Tokenizer\CT;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
|
||||
/**
|
||||
* This is the extended version of the original new_with_braces fixer.
|
||||
* It allows you to remove braces around an anonymous class declaration in a case
|
||||
* when said class constructor doesn't contain any arguments.
|
||||
*
|
||||
* @url https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/5c5de791ab/src/Fixer/Operator/NewWithBracesFixer.php
|
||||
*
|
||||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
*/
|
||||
final class NewWithBracesFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition() {
|
||||
return new FixerDefinition(
|
||||
'All instances created with new keyword must be followed by braces.',
|
||||
[
|
||||
new CodeSample("<?php \$x = new X;\n"),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens) {
|
||||
return $tokens->isTokenKindFound(T_NEW);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function applyFix(\SplFileInfo $file, Tokens $tokens) {
|
||||
static $nextTokenKinds = null;
|
||||
if ($nextTokenKinds === null) {
|
||||
$nextTokenKinds = [
|
||||
'?',
|
||||
';',
|
||||
',',
|
||||
'(',
|
||||
')',
|
||||
'[',
|
||||
']',
|
||||
':',
|
||||
'<',
|
||||
'>',
|
||||
'+',
|
||||
'-',
|
||||
'*',
|
||||
'/',
|
||||
'%',
|
||||
'&',
|
||||
'^',
|
||||
'|',
|
||||
[T_CLASS],
|
||||
[T_IS_SMALLER_OR_EQUAL],
|
||||
[T_IS_GREATER_OR_EQUAL],
|
||||
[T_IS_EQUAL],
|
||||
[T_IS_NOT_EQUAL],
|
||||
[T_IS_IDENTICAL],
|
||||
[T_IS_NOT_IDENTICAL],
|
||||
[T_CLOSE_TAG],
|
||||
[T_LOGICAL_AND],
|
||||
[T_LOGICAL_OR],
|
||||
[T_LOGICAL_XOR],
|
||||
[T_BOOLEAN_AND],
|
||||
[T_BOOLEAN_OR],
|
||||
[T_SL],
|
||||
[T_SR],
|
||||
[T_INSTANCEOF],
|
||||
[T_AS],
|
||||
[T_DOUBLE_ARROW],
|
||||
[T_POW],
|
||||
[CT::T_ARRAY_SQUARE_BRACE_OPEN],
|
||||
[CT::T_ARRAY_SQUARE_BRACE_CLOSE],
|
||||
[CT::T_BRACE_CLASS_INSTANTIATION_OPEN],
|
||||
[CT::T_BRACE_CLASS_INSTANTIATION_CLOSE],
|
||||
];
|
||||
|
||||
if (defined('T_SPACESHIP')) {
|
||||
$nextTokenKinds[] = [T_SPACESHIP];
|
||||
}
|
||||
}
|
||||
|
||||
for ($index = $tokens->count() - 3; $index > 0; --$index) {
|
||||
$token = $tokens[$index];
|
||||
if (!$token->isGivenKind(T_NEW)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$nextIndex = $tokens->getNextTokenOfKind($index, $nextTokenKinds);
|
||||
$nextToken = $tokens[$nextIndex];
|
||||
|
||||
// new anonymous class definition
|
||||
if ($nextToken->isGivenKind(T_CLASS)) {
|
||||
if ($this->configuration['remove_for_anonymous_classes']) {
|
||||
$nextTokenIndex = $tokens->getNextMeaningfulToken($nextIndex);
|
||||
$nextNextTokenIndex = $tokens->getNextMeaningfulToken($nextTokenIndex);
|
||||
if ($tokens[$nextTokenIndex]->equals('(') && $tokens[$nextNextTokenIndex]->equals(')')) {
|
||||
$this->removeBracesAfter($tokens, $nextIndex);
|
||||
}
|
||||
} else {
|
||||
if (!$tokens[$tokens->getNextMeaningfulToken($nextIndex)]->equals('(')) {
|
||||
$this->insertBracesAfter($tokens, $nextIndex);
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// entrance into array index syntax - need to look for exit
|
||||
while ($nextToken->equals('[')) {
|
||||
$nextIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $nextIndex) + 1;
|
||||
$nextToken = $tokens[$nextIndex];
|
||||
}
|
||||
|
||||
// new statement has a gap in it - advance to the next token
|
||||
if ($nextToken->isWhitespace()) {
|
||||
$nextIndex = $tokens->getNextNonWhitespace($nextIndex);
|
||||
$nextToken = $tokens[$nextIndex];
|
||||
}
|
||||
|
||||
// new statement with () - nothing to do
|
||||
if ($nextToken->equals('(')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->insertBracesAfter($tokens, $tokens->getPrevMeaningfulToken($nextIndex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createConfigurationDefinition() {
|
||||
return new FixerConfigurationResolver([
|
||||
(new FixerOptionBuilder('remove_for_anonymous_classes', 'when enabled will remove braces around an anonymous class declaration in a case when constructor doesn\'t contain any arguments'))
|
||||
->setAllowedTypes(['bool'])
|
||||
->setDefault(false)
|
||||
->getOption(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Tokens $tokens
|
||||
* @param int $index
|
||||
*/
|
||||
private function insertBracesAfter(Tokens $tokens, $index) {
|
||||
$tokens->insertAt(++$index, [new Token('('), new Token(')')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Tokens $tokens
|
||||
* @param int $index
|
||||
*/
|
||||
private function removeBracesAfter(Tokens $tokens, int $index) {
|
||||
$tokens->clearRange(
|
||||
$tokens->getNextTokenOfKind($index, ['(']),
|
||||
$tokens->getNextTokenOfKind($index, [')'])
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
150
src/Fixer/Whitespace/BlankLineAroundClassBodyFixer.php
Normal file
150
src/Fixer/Whitespace/BlankLineAroundClassBodyFixer.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Fixer\Whitespace;
|
||||
|
||||
use Ely\CS\Fixer\AbstractFixer;
|
||||
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
|
||||
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
|
||||
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
|
||||
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
use PhpCsFixer\Tokenizer\TokensAnalyzer;
|
||||
use PhpCsFixer\Utils;
|
||||
|
||||
/**
|
||||
* This is copy of the PR https://github.com/FriendsOfPHP/PHP-CS-Fixer/pull/3688
|
||||
*
|
||||
* @author ErickSkrauch <erickskrauch@ely.by>
|
||||
*/
|
||||
final class BlankLineAroundClassBodyFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface, WhitespacesAwareFixerInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition() {
|
||||
return new FixerDefinition(
|
||||
'Ensure that class body contains one blank line after class definition and before its end.',
|
||||
[
|
||||
new CodeSample(
|
||||
'<?php
|
||||
class Sample
|
||||
{
|
||||
protected function foo()
|
||||
{
|
||||
}
|
||||
}
|
||||
'
|
||||
),
|
||||
new CodeSample(
|
||||
'<?php
|
||||
new class extends Foo {
|
||||
|
||||
protected function foo()
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
',
|
||||
['apply_to_anonymous_classes' => false]
|
||||
),
|
||||
new CodeSample(
|
||||
'<?php
|
||||
new class extends Foo {
|
||||
protected function foo()
|
||||
{
|
||||
}
|
||||
};
|
||||
',
|
||||
['apply_to_anonymous_classes' => true]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPriority() {
|
||||
// should be run after the BracesFixer
|
||||
return -26;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens) {
|
||||
return $tokens->isAnyTokenKindsFound(Token::getClassyTokenKinds());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function applyFix(\SplFileInfo $file, Tokens $tokens) {
|
||||
$analyzer = new TokensAnalyzer($tokens);
|
||||
foreach ($tokens as $index => $token) {
|
||||
if (!$token->isClassy()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$countLines = $this->configuration['blank_lines_count'];
|
||||
if (!$this->configuration['apply_to_anonymous_classes'] && $analyzer->isAnonymousClass($index)) {
|
||||
$countLines = 0;
|
||||
}
|
||||
|
||||
$startBraceIndex = $tokens->getNextTokenOfKind($index, ['{']);
|
||||
if ($tokens[$startBraceIndex + 1]->isWhitespace()) {
|
||||
$nextStatementIndex = $tokens->getNextMeaningfulToken($startBraceIndex);
|
||||
// Traits should be placed right after a class opening brace,
|
||||
if ($tokens[$nextStatementIndex]->getContent() !== 'use') {
|
||||
$this->fixBlankLines($tokens, $startBraceIndex + 1, $countLines);
|
||||
}
|
||||
}
|
||||
|
||||
$endBraceIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $startBraceIndex);
|
||||
if ($tokens[$endBraceIndex - 1]->isWhitespace()) {
|
||||
$this->fixBlankLines($tokens, $endBraceIndex - 1, $countLines);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createConfigurationDefinition() {
|
||||
return new FixerConfigurationResolver([
|
||||
(new FixerOptionBuilder('blank_lines_count', 'adjusts an amount of the blank lines.'))
|
||||
->setAllowedTypes(['int'])
|
||||
->setDefault(1)
|
||||
->getOption(),
|
||||
(new FixerOptionBuilder('apply_to_anonymous_classes', 'whether this fixer should be applied to anonymous classes.'))
|
||||
->setAllowedTypes(['bool'])
|
||||
->setDefault(true)
|
||||
->getOption(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup a whitespace token.
|
||||
*
|
||||
* @param Tokens $tokens
|
||||
* @param int $index
|
||||
* @param int $countLines
|
||||
*/
|
||||
private function fixBlankLines(Tokens $tokens, $index, $countLines) {
|
||||
$content = $tokens[$index]->getContent();
|
||||
// Apply fix only in the case when the count lines do not equals to expected
|
||||
if (substr_count($content, "\n") === $countLines + 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The final bit of the whitespace must be the next statement's indentation
|
||||
$lines = Utils::splitLines($content);
|
||||
$eol = $this->whitespacesConfig->getLineEnding();
|
||||
$tokens[$index] = new Token([T_WHITESPACE, str_repeat($eol, $countLines + 1) . end($lines)]);
|
||||
}
|
||||
|
||||
}
|
||||
103
src/Fixer/Whitespace/BlankLineBeforeReturnFixer.php
Normal file
103
src/Fixer/Whitespace/BlankLineBeforeReturnFixer.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Fixer\Whitespace;
|
||||
|
||||
use Ely\CS\Fixer\AbstractFixer;
|
||||
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
use SplFileInfo;
|
||||
|
||||
/**
|
||||
* This is extended version of the original `blank_line_before_statement` fixer.
|
||||
* It applies only to `return` statements and only in cases, when on the current nesting level more than one statements.
|
||||
*
|
||||
* @url https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/5c5de791ab/src/Fixer/Whitespace/BlankLineBeforeStatementFixer.php
|
||||
*
|
||||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
* @author Andreas Möller <am@localheinz.com>
|
||||
* @author SpacePossum
|
||||
*/
|
||||
final class BlankLineBeforeReturnFixer extends AbstractFixer implements WhitespacesAwareFixerInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition() {
|
||||
return new FixerDefinition(
|
||||
'An empty line feed should precede a return statement.',
|
||||
[new CodeSample("<?php\nfunction A()\n{\n echo 1;\n return 1;\n}\n")]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens) {
|
||||
return $tokens->isTokenKindFound(T_RETURN);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPriority() {
|
||||
// should be run after NoUselessReturnFixer, ClassDefinitionFixer and BracesFixer
|
||||
return -26;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function applyFix(SplFileInfo $file, Tokens $tokens) {
|
||||
for ($index = 0, $limit = $tokens->count(); $index < $limit; ++$index) {
|
||||
$token = $tokens[$index];
|
||||
if (!$token->isGivenKind(T_RETURN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$eol = $this->whitespacesConfig->getLineEnding();
|
||||
|
||||
$prevNonWhitespaceToken = $tokens[$tokens->getPrevNonWhitespace($index)];
|
||||
if (!$prevNonWhitespaceToken->equalsAny([';', '}'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$prevIndex = $index - 1;
|
||||
$prevToken = $tokens[$prevIndex];
|
||||
if ($prevToken->isWhitespace()) {
|
||||
$countParts = substr_count($prevToken->getContent(), "\n");
|
||||
if ($countParts === 0) {
|
||||
$tokens[$prevIndex] = new Token([T_WHITESPACE, rtrim($prevToken->getContent(), " \t") . $eol . $eol]);
|
||||
} elseif ($countParts === 1) {
|
||||
$backwardIndex = $prevIndex;
|
||||
do {
|
||||
if (--$backwardIndex < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
$backwardToken = $tokens[$backwardIndex];
|
||||
if ($backwardToken->getContent() === '{') {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($backwardToken->isWhitespace()) {
|
||||
$countParts += substr_count($backwardToken->getContent(), "\n");
|
||||
}
|
||||
} while ($countParts < 3);
|
||||
|
||||
if ($countParts !== 2) {
|
||||
$tokens[$prevIndex] = new Token([T_WHITESPACE, $eol . $prevToken->getContent()]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$tokens->insertAt($index, new Token([T_WHITESPACE, $eol . $eol]));
|
||||
++$index;
|
||||
++$limit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
163
src/Fixer/Whitespace/LineBreakAfterStatementsFixer.php
Normal file
163
src/Fixer/Whitespace/LineBreakAfterStatementsFixer.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Fixer\Whitespace;
|
||||
|
||||
use Ely\CS\Fixer\AbstractFixer;
|
||||
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
use PhpCsFixer\Utils;
|
||||
use SplFileInfo;
|
||||
|
||||
/**
|
||||
* This is rewritten version of the original fixer created by @PedroTroller with improved cases validation and
|
||||
* targeted to the PHP-CS-Fixer 2.11 version.
|
||||
*
|
||||
* @url https://github.com/PedroTroller/PhpCSFixer-Custom-Fixers/blob/affdf99f51/src/PedroTroller/CS/Fixer/CodingStyle/LineBreakBetweenStatementsFixer.php
|
||||
*
|
||||
* @author ErickSkrauch <erickskrauch@ely.by>
|
||||
*/
|
||||
final class LineBreakAfterStatementsFixer extends AbstractFixer implements WhitespacesAwareFixerInterface {
|
||||
|
||||
/**
|
||||
* There is no 'do', 'cause the processing of the 'while' also includes do {} while (); construction
|
||||
*/
|
||||
const STATEMENTS = [
|
||||
T_IF,
|
||||
T_SWITCH,
|
||||
T_FOR,
|
||||
T_FOREACH,
|
||||
T_WHILE,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDefinition() {
|
||||
return new FixerDefinition(
|
||||
'Ensures that there is one blank line above the control statements',
|
||||
[
|
||||
new CodeSample(
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function foo() {
|
||||
do {
|
||||
// ...
|
||||
} while (true);
|
||||
foreach (["foo", "bar"] as $str) {
|
||||
// ...
|
||||
}
|
||||
if (true === false) {
|
||||
// ...
|
||||
}
|
||||
foreach (["foo", "bar"] as $str) {
|
||||
if ($str === "foo") {
|
||||
// smth
|
||||
}
|
||||
|
||||
}
|
||||
while (true) {
|
||||
// ...
|
||||
}
|
||||
switch("123") {
|
||||
case "123":
|
||||
break;
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}
|
||||
'
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens) {
|
||||
return $tokens->isAnyTokenKindsFound(self::STATEMENTS);
|
||||
}
|
||||
|
||||
protected function applyFix(SplFileInfo $file, Tokens $tokens) {
|
||||
foreach ($tokens as $index => $token) {
|
||||
if (!$token->isGivenKind(self::STATEMENTS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$endStatementIndex = $this->findStatementEnd($tokens, $index);
|
||||
$nextStatementIndex = $tokens->getNextNonWhitespace($endStatementIndex);
|
||||
if ($nextStatementIndex === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($tokens[$nextStatementIndex]->equals('}')) {
|
||||
$this->fixBlankLines($tokens, $endStatementIndex + 1, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->fixBlankLines($tokens, $endStatementIndex + 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private function fixBlankLines(Tokens $tokens, $index, $countLines) {
|
||||
$content = $tokens[$index]->getContent();
|
||||
// Apply fix only in the case when the count lines do not equals to expected
|
||||
if (substr_count($content, "\n") === $countLines + 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The final bit of the whitespace must be the next statement's indentation
|
||||
$lines = Utils::splitLines($content);
|
||||
$eol = $this->whitespacesConfig->getLineEnding();
|
||||
$tokens[$index] = new Token([T_WHITESPACE, str_repeat($eol, $countLines + 1) . end($lines)]);
|
||||
}
|
||||
|
||||
private function findStatementEnd(Tokens $tokens, int $index): int {
|
||||
$nextIndex = $tokens->getNextMeaningfulToken($index);
|
||||
$nextToken = $tokens[$nextIndex];
|
||||
|
||||
if ($nextToken->equals('(')) {
|
||||
$parenthesisEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $nextIndex);
|
||||
$possibleStartBraceIndex = $tokens->getNextNonWhitespace($parenthesisEndIndex);
|
||||
} else {
|
||||
$possibleStartBraceIndex = $nextIndex;
|
||||
}
|
||||
|
||||
// `do {} while ();`
|
||||
if ($tokens[$index]->isGivenKind(T_WHILE) && $tokens[$possibleStartBraceIndex]->equals(';')) {
|
||||
return $possibleStartBraceIndex;
|
||||
}
|
||||
|
||||
$blockEnd = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $possibleStartBraceIndex);
|
||||
$nextStatementIndex = $tokens->getNextMeaningfulToken($blockEnd);
|
||||
if ($nextStatementIndex === null) {
|
||||
return $blockEnd;
|
||||
}
|
||||
|
||||
// `if () {} elseif {}`
|
||||
if ($tokens[$nextStatementIndex]->isGivenKind(T_ELSEIF)) {
|
||||
return $this->findStatementEnd($tokens, $nextStatementIndex);
|
||||
}
|
||||
|
||||
// `if () {} else if {}` or simple `if () {} else {}`
|
||||
if ($tokens[$nextStatementIndex]->isGivenKind(T_ELSE)) {
|
||||
$nextNextStatementIndex = $tokens->getNextMeaningfulToken($nextStatementIndex);
|
||||
if ($tokens[$nextNextStatementIndex]->isGivenKind(T_IF)) {
|
||||
return $this->findStatementEnd($tokens, $nextNextStatementIndex);
|
||||
}
|
||||
|
||||
return $this->findStatementEnd($tokens, $nextStatementIndex);
|
||||
}
|
||||
|
||||
return $blockEnd;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user