Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Tokens::insertSlices not moving around all affected tokens #6058

Merged

Conversation

paulbalandan
Copy link
Contributor

While working on #5953 in refactoring to call insertSlices once, I stumbled into a problem where parse error would appear after fixing. After digging into it more, I found out that the culprit is in the insertSlices method itself. If there are multiple slices to be inserted in an index and this is repeated in other indexes, there exists a "hole" left in the moving around of tokens. This causes the unmoved tokens to be inadvertently replaced by other else possibly resulting to parse errors after.

@coveralls
Copy link

coveralls commented Oct 7, 2021

Coverage Status

Coverage decreased (-0.01%) to 93.023% when pulling fbac555 on paulbalandan:tokens-insert-slices-multiple into 2c944f8 on FriendsOfPHP:master.

@SpacePossum
Copy link
Contributor

looks promising,yet like to have @keradus to take look if he has time

@SpacePossum
Copy link
Contributor

reviewed, left some suggestions here paulbalandan#1

@SpacePossum
Copy link
Contributor

Thank you @paulbalandan.

@SpacePossum SpacePossum merged commit 4ecba58 into PHP-CS-Fixer:master Dec 14, 2021
@paulbalandan paulbalandan deleted the tokens-insert-slices-multiple branch December 14, 2021 07:36
@@ -859,20 +860,28 @@ public function insertSlices(array $slices): void

krsort($slices);

if (array_key_first($slices) > $oldSize) {
throw new \OutOfBoundsException('Cannot insert outside of collection.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced it's good validation, as it's checking only index for first slice. And it looks like there are not tests checking it? :(

ref #6172

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we sort the keys above it, so we know all other keys are of a lower value so we only need to test the first,
all others are tested to be greater or equal to zero

Comment on lines -895 to +904
if ($this->changed) {
return true;
}

return false;
return $this->changed;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i remember the idea here was to have different lines for different paths, so we can have explicit code coverage not just by one-liner covered, but to ensure both paths are covered for this crucial core-level functionality

@SpacePossum , should we move back to multiline approach, perhaps?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow, what is the benefit of higher LOC's here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i remember initial reasoning. we wanted to ensure, initially, that we don't test only cases like "this->changed=true"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh like in the coverage it won't show if both true and false and checked.... that is true. I value a more direct and compact notation even if that means a bit less verbose coverage report.

<?php

$after = get_class($after);
$before = get_class($before);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this case is wrong, we must avoid having whitespace next to whitespace as 2 separated tokens!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

somehow, in line 1398, we check only text-representation of collection. this is wrong, as to whitespace token should not be place one to each other (new Token([T_WHITESPACE, ' ']), new Token([T_WHITESPACE, ' ']))
after strong check of assertTokens, this case is failing d865593

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants