Skip to content

Commit

Permalink
Merge branch '2.18'
Browse files Browse the repository at this point in the history
  • Loading branch information
keradus committed Apr 14, 2021
2 parents bc1d2c2 + a503ace commit 4438030
Show file tree
Hide file tree
Showing 63 changed files with 987 additions and 185 deletions.
3 changes: 2 additions & 1 deletion .composer-require-checker.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"T_MATCH",
"T_NAME_FULLY_QUALIFIED",
"T_NAME_QUALIFIED",
"T_NAME_RELATIVE"
"T_NAME_RELATIVE",
"T_NULLSAFE_OBJECT_OPERATOR"
],
"php-core-extensions" : [
"dom", "mbstring", "Phar",
Expand Down
2 changes: 1 addition & 1 deletion doc/rules/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ Operator
- `not_operator_with_successor_space <./operator/not_operator_with_successor_space.rst>`_
Logical NOT operators (``!``) should have one trailing whitespace.
- `object_operator_without_whitespace <./operator/object_operator_without_whitespace.rst>`_
There should not be space before or after object ``T_OBJECT_OPERATOR`` ``->``.
There should not be space before or after object operators ``->`` and ``?->``.
- `operator_linebreak <./operator/operator_linebreak.rst>`_
Operators - when multiline - must always be at the beginning or at the end of the line.
- `pre_increment <./operator/pre_increment.rst>`_ *(deprecated)*
Expand Down
2 changes: 1 addition & 1 deletion doc/rules/operator/object_operator_without_whitespace.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Rule ``object_operator_without_whitespace``
===========================================

There should not be space before or after object ``T_OBJECT_OPERATOR`` ``->``.
There should not be space before or after object operators ``->`` and ``?->``.

Examples
--------
Expand Down
2 changes: 1 addition & 1 deletion src/Fixer/AbstractIncrementOperatorFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ final protected function findStart(Tokens $tokens, $index)
return $this->findStart($tokens, $index);
}

if ($prevToken->isGivenKind(T_OBJECT_OPERATOR)) {
if ($prevToken->isObjectOperator()) {
return $this->findStart($tokens, $prevIndex);
}

Expand Down
25 changes: 20 additions & 5 deletions src/Fixer/Alias/PowToExponentiationFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,11 @@ private function fixPowToExponentiation(Tokens $tokens, $functionNameIndex, $ope
*/
private function isParenthesisNeeded(Tokens $tokens, $argumentStartIndex, $argumentEndIndex)
{
static $allowedKinds = [
T_DNUMBER, T_LNUMBER, T_VARIABLE, T_STRING, T_OBJECT_OPERATOR, T_CONSTANT_ENCAPSED_STRING, T_DOUBLE_CAST,
T_INT_CAST, T_INC, T_DEC, T_NS_SEPARATOR, T_WHITESPACE, T_DOUBLE_COLON, T_LINE, T_COMMENT, T_DOC_COMMENT,
CT::T_NAMESPACE_OPERATOR,
];
static $allowedKinds = null;

if (null === $allowedKinds) {
$allowedKinds = $this->getAllowedKinds();
}

for ($i = $argumentStartIndex; $i <= $argumentEndIndex; ++$i) {
if ($tokens[$i]->isGivenKind($allowedKinds) || $tokens->isEmptyAt($i)) {
Expand Down Expand Up @@ -221,4 +221,19 @@ private function isParenthesisNeeded(Tokens $tokens, $argumentStartIndex, $argum

return false;
}

/**
* @return int[]
*/
private function getAllowedKinds()
{
return array_merge(
[
T_DNUMBER, T_LNUMBER, T_VARIABLE, T_STRING, T_CONSTANT_ENCAPSED_STRING, T_DOUBLE_CAST,
T_INT_CAST, T_INC, T_DEC, T_NS_SEPARATOR, T_WHITESPACE, T_DOUBLE_COLON, T_LINE, T_COMMENT, T_DOC_COMMENT,
CT::T_NAMESPACE_OPERATOR,
],
Token::getObjectOperatorKinds()
);
}
}
42 changes: 24 additions & 18 deletions src/Fixer/Casing/ConstantCaseFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,24 +119,30 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
*/
private function isNeighbourAccepted(Tokens $tokens, $index)
{
static $forbiddenTokens = [
T_AS,
T_CLASS,
T_CONST,
T_EXTENDS,
T_IMPLEMENTS,
T_INSTANCEOF,
T_INSTEADOF,
T_INTERFACE,
T_NEW,
T_NS_SEPARATOR,
T_OBJECT_OPERATOR,
T_PAAMAYIM_NEKUDOTAYIM,
T_TRAIT,
T_USE,
CT::T_USE_TRAIT,
CT::T_USE_LAMBDA,
];
static $forbiddenTokens = null;

if (null === $forbiddenTokens) {
$forbiddenTokens = array_merge(
[
T_AS,
T_CLASS,
T_CONST,
T_EXTENDS,
T_IMPLEMENTS,
T_INSTANCEOF,
T_INSTEADOF,
T_INTERFACE,
T_NEW,
T_NS_SEPARATOR,
T_PAAMAYIM_NEKUDOTAYIM,
T_TRAIT,
T_USE,
CT::T_USE_TRAIT,
CT::T_USE_LAMBDA,
],
Token::getObjectOperatorKinds()
);
}

$token = $tokens[$index];

Expand Down
2 changes: 1 addition & 1 deletion src/Fixer/Casing/LowercaseStaticReferenceFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
}

$prevIndex = $tokens->getPrevMeaningfulToken($index);
if ($tokens[$prevIndex]->isGivenKind([T_CONST, T_DOUBLE_COLON, T_FUNCTION, T_NAMESPACE, T_NS_SEPARATOR, T_OBJECT_OPERATOR, T_PRIVATE, T_PROTECTED, T_PUBLIC])) {
if ($tokens[$prevIndex]->isGivenKind([T_CONST, T_DOUBLE_COLON, T_FUNCTION, T_NAMESPACE, T_NS_SEPARATOR, T_PRIVATE, T_PROTECTED, T_PUBLIC]) || $tokens[$prevIndex]->isObjectOperator()) {
continue;
}

Expand Down
4 changes: 2 additions & 2 deletions src/Fixer/Casing/MagicMethodCasingFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function __Sleep()
*/
public function isCandidate(Tokens $tokens)
{
return $tokens->isTokenKindFound(T_STRING) && $tokens->isAnyTokenKindsFound([T_FUNCTION, T_OBJECT_OPERATOR, T_DOUBLE_COLON]);
return $tokens->isTokenKindFound(T_STRING) && $tokens->isAnyTokenKindsFound(array_merge([T_FUNCTION, T_DOUBLE_COLON], Token::getObjectOperatorKinds()));
}

/**
Expand Down Expand Up @@ -175,7 +175,7 @@ private function isFunctionSignature(Tokens $tokens, $index)
private function isMethodCall(Tokens $tokens, $index)
{
$prevIndex = $tokens->getPrevMeaningfulToken($index);
if (!$tokens[$prevIndex]->equals([T_OBJECT_OPERATOR, '->'])) {
if (!$tokens[$prevIndex]->isObjectOperator()) {
return false; // not a "simple" method call
}

Expand Down
2 changes: 1 addition & 1 deletion src/Fixer/Casing/NativeFunctionCasingFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
}

$functionNamePrefix = $tokens->getPrevMeaningfulToken($index);
if ($tokens[$functionNamePrefix]->isGivenKind([T_DOUBLE_COLON, T_NEW, T_OBJECT_OPERATOR, T_FUNCTION, CT::T_RETURN_REF])) {
if ($tokens[$functionNamePrefix]->isGivenKind([T_DOUBLE_COLON, T_NEW, T_FUNCTION, CT::T_RETURN_REF]) || $tokens[$functionNamePrefix]->isObjectOperator()) {
continue;
}

Expand Down
3 changes: 2 additions & 1 deletion src/Fixer/ClassNotation/ClassAttributesSeparationFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@ private function fixSpaceBelowClassElement(Tokens $tokens, $classEndIndex, $elem
$nextNotWhite = $tokens->getNextNonWhitespace($nextNotWhite);
}

if ($tokens[$nextNotWhite]->isGivenKind(T_FUNCTION)) {
$functionIndex = $tokens->getTokenNotOfKindsSibling($nextNotWhite - 1, 1, [T_ABSTRACT, T_FINAL, T_PUBLIC, T_PROTECTED, T_PRIVATE, T_STATIC, T_WHITESPACE, T_COMMENT, T_DOC_COMMENT]);
if ($tokens[$functionIndex]->isGivenKind(T_FUNCTION)) {
$this->correctLineBreaks($tokens, $elementEndIndex, $nextNotWhite, 2);

return;
Expand Down
171 changes: 93 additions & 78 deletions src/Fixer/ClassNotation/NoPhp4ConstructorFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,25 +164,31 @@ private function fixConstructor(Tokens $tokens, $className, $classStart, $classE
}

// does the PHP4-constructor only call $this->__construct($args, ...)?
list($seq, $case) = $this->getWrapperMethodSequence($tokens, '__construct', $php4['startIndex'], $php4['bodyIndex']);
if (null !== $tokens->findSequence($seq, $php4['bodyIndex'] - 1, $php4['endIndex'], $case)) {
// good, delete it!
for ($i = $php4['startIndex']; $i <= $php4['endIndex']; ++$i) {
$tokens->clearAt($i);
}
list($sequences, $case) = $this->getWrapperMethodSequence($tokens, '__construct', $php4['startIndex'], $php4['bodyIndex']);
foreach ($sequences as $seq) {
if (null !== $tokens->findSequence($seq, $php4['bodyIndex'] - 1, $php4['endIndex'], $case)) {
// good, delete it!
for ($i = $php4['startIndex']; $i <= $php4['endIndex']; ++$i) {
$tokens->clearAt($i);
}

return;
return;
}
}

// does __construct only call the PHP4-constructor (with the same args)?
list($seq, $case) = $this->getWrapperMethodSequence($tokens, $className, $php4['startIndex'], $php4['bodyIndex']);
if (null !== $tokens->findSequence($seq, $php5['bodyIndex'] - 1, $php5['endIndex'], $case)) {
// that was a weird choice, but we can safely delete it and...
for ($i = $php5['startIndex']; $i <= $php5['endIndex']; ++$i) {
$tokens->clearAt($i);
list($sequences, $case) = $this->getWrapperMethodSequence($tokens, $className, $php4['startIndex'], $php4['bodyIndex']);
foreach ($sequences as $seq) {
if (null !== $tokens->findSequence($seq, $php5['bodyIndex'] - 1, $php5['endIndex'], $case)) {
// that was a weird choice, but we can safely delete it and...
for ($i = $php5['startIndex']; $i <= $php5['endIndex']; ++$i) {
$tokens->clearAt($i);
}
// rename the PHP4 one to __construct
$tokens[$php4['nameIndex']] = new Token([T_STRING, '__construct']);

return;
}
// rename the PHP4 one to __construct
$tokens[$php4['nameIndex']] = new Token([T_STRING, '__construct']);
}
}

Expand Down Expand Up @@ -220,28 +226,30 @@ private function fixParent(Tokens $tokens, $classStart, $classEnd)
}
}

// using $this->ParentClassName()
$parentSeq = $tokens->findSequence([
[T_VARIABLE, '$this'],
[T_OBJECT_OPERATOR],
[T_STRING, $parentClass],
'(',
], $classStart, $classEnd, [2 => false]);

if (null !== $parentSeq) {
// we only need indexes
$parentSeq = array_keys($parentSeq);

// replace call with parent::__construct()
$tokens[$parentSeq[0]] = new Token([
T_STRING,
'parent',
]);
$tokens[$parentSeq[1]] = new Token([
T_DOUBLE_COLON,
'::',
]);
$tokens[$parentSeq[2]] = new Token([T_STRING, '__construct']);
foreach (Token::getObjectOperatorKinds() as $objectOperatorKind) {
// using $this->ParentClassName()
$parentSeq = $tokens->findSequence([
[T_VARIABLE, '$this'],
[$objectOperatorKind],
[T_STRING, $parentClass],
'(',
], $classStart, $classEnd, [2 => false]);

if (null !== $parentSeq) {
// we only need indexes
$parentSeq = array_keys($parentSeq);

// replace call with parent::__construct()
$tokens[$parentSeq[0]] = new Token([
T_STRING,
'parent',
]);
$tokens[$parentSeq[1]] = new Token([
T_DOUBLE_COLON,
'::',
]);
$tokens[$parentSeq[2]] = new Token([T_STRING, '__construct']);
}
}
}
}
Expand All @@ -256,23 +264,25 @@ private function fixParent(Tokens $tokens, $classStart, $classEnd)
*/
private function fixInfiniteRecursion(Tokens $tokens, $start, $end)
{
$seq = [
[T_VARIABLE, '$this'],
[T_OBJECT_OPERATOR],
[T_STRING, '__construct'],
];
foreach (Token::getObjectOperatorKinds() as $objectOperatorKind) {
$seq = [
[T_VARIABLE, '$this'],
[$objectOperatorKind],
[T_STRING, '__construct'],
];

while (true) {
$callSeq = $tokens->findSequence($seq, $start, $end, [2 => false]);
while (true) {
$callSeq = $tokens->findSequence($seq, $start, $end, [2 => false]);

if (null === $callSeq) {
return;
}
if (null === $callSeq) {
return;
}

$callSeq = array_keys($callSeq);
$callSeq = array_keys($callSeq);

$tokens[$callSeq[0]] = new Token([T_STRING, 'parent']);
$tokens[$callSeq[1]] = new Token([T_DOUBLE_COLON, '::']);
$tokens[$callSeq[0]] = new Token([T_STRING, 'parent']);
$tokens[$callSeq[1]] = new Token([T_DOUBLE_COLON, '::']);
}
}
}

Expand All @@ -289,42 +299,47 @@ private function fixInfiniteRecursion(Tokens $tokens, $start, $end)
*/
private function getWrapperMethodSequence(Tokens $tokens, $method, $startIndex, $bodyIndex)
{
// initialise sequence as { $this->{$method}(
$seq = [
'{',
[T_VARIABLE, '$this'],
[T_OBJECT_OPERATOR],
[T_STRING, $method],
'(',
];
$case = [3 => false];
$sequences = [];

// parse method parameters, if any
$index = $startIndex;
while (true) {
// find the next variable name
$index = $tokens->getNextTokenOfKind($index, [[T_VARIABLE]]);
foreach (Token::getObjectOperatorKinds() as $objectOperatorKind) {
// initialise sequence as { $this->{$method}(
$seq = [
'{',
[T_VARIABLE, '$this'],
[$objectOperatorKind],
[T_STRING, $method],
'(',
];

if (null === $index || $index >= $bodyIndex) {
// we've reached the body already
break;
}
// parse method parameters, if any
$index = $startIndex;
while (true) {
// find the next variable name
$index = $tokens->getNextTokenOfKind($index, [[T_VARIABLE]]);

if (null === $index || $index >= $bodyIndex) {
// we've reached the body already
break;
}

// append a comma if it's not the first variable
if (\count($seq) > 5) {
$seq[] = ',';
// append a comma if it's not the first variable
if (\count($seq) > 5) {
$seq[] = ',';
}

// append variable name to the sequence
$seq[] = [T_VARIABLE, $tokens[$index]->getContent()];
}

// append variable name to the sequence
$seq[] = [T_VARIABLE, $tokens[$index]->getContent()];
}
// almost done, close the sequence with ); }
$seq[] = ')';
$seq[] = ';';
$seq[] = '}';

// almost done, close the sequence with ); }
$seq[] = ')';
$seq[] = ';';
$seq[] = '}';
$sequences[] = $seq;
}

return [$seq, $case];
return [$sequences, [3 => false]];
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Fixer/ClassNotation/SelfAccessorFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private function replaceNameOccurrences(Tokens $tokens, $namespace, $name, $star
}
$prevToken = $tokens[$tokens->getPrevMeaningfulToken($classStartIndex)];
}
if ($prevToken->isGivenKind([T_OBJECT_OPERATOR, T_STRING])) {
if ($prevToken->isGivenKind(T_STRING) || $prevToken->isObjectOperator()) {
continue;
}

Expand Down
Loading

0 comments on commit 4438030

Please sign in to comment.