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

[Php72][TypeDeclaration] Fix infinite loop on ParseStrWithResultArgumentRector+DeclareStrictTypesRector #5699

Merged
merged 9 commits into from Mar 7, 2024

Conversation

samsonasik
Copy link
Member

@samsonasik
Copy link
Member Author

@kapersoft this should fix rectorphp/rector#8531

@samsonasik
Copy link
Member Author

@kenjis this probably should fix infinite loop on CodeIgniter4 project as well when running DeclareStrictTypesRector

@samsonasik
Copy link
Member Author

All checks have passed 🎉 @TomasVotruba I am merging it ;)

@samsonasik samsonasik merged commit 13bafcb into main Mar 7, 2024
41 checks passed
@samsonasik samsonasik deleted the infinite-loop branch March 7, 2024 21:07
@kapersoft
Copy link

@samsonasik I have checked your fix with my codebase and the endless loops are gone 😄

Thanks for quick response! 👍

@samsonasik
Copy link
Member Author

@kapersoft you're welcome, I am actually not sure why current() don't work, while $nodes[0] fix it, and only reproducible via vendor/bin/rector, while it only run once on unit test, so kind of phpunit flow probably.

it may require e2e in the future.

@samsonasik
Copy link
Member Author

The issue seems happen only on scoped code (php 7.2 compat), as can't be produced in rector-src on php 8.2, so array seems somewhere goes to end() of loop when downgraded, if the current() still needed, the reset() is needed first to ensure it start from the beginnning:

        // use 0 index to avoid infinite loop
-        $rootStmt = $newStmts[0] ?? null;
+        reset($newStmts);
+        $rootStmt = current($newStmts);        
        $stmt = $rootStmt;
        if ($rootStmt instanceof FileWithoutNamespace) {
            // use 0 index to avoid infinite loop
-            $currentStmt = $rootStmt->stmts[0] ?? null;
+            reset($rootStmt->stmts);
+            $currentStmt = current($rootStmt->stmts);

@samsonasik
Copy link
Member Author

current solution with index 0 seems ok as is :)

@samsonasik
Copy link
Member Author

samsonasik commented Mar 8, 2024

I see, the issue is on ParseStrWithResultArgumentRector, which

$totalKeys = array_key_last($stmtsAware->stmts);

downgraded to

        \end($stmtsAware->stmts);
        $totalKeys = \key($stmtsAware->stmts);

which make it always goes to last stmts, then it never resetted, I think the proper solution is refactor DowngradeArrayKeyFirstLastRector to make call reset($stmtsAware->stmts after get the key:

        \end($stmtsAware->stmts);
        $totalKeys = \key($stmtsAware->stmts);
+        reset($stmtsAware->stmts);

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