topological sorting for refactoring #31499
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In order to traverse a graph in "dependency order", meaning all dependencies of a node have been visited before the node itself is visited, you need to first create a topological sort of the graph nodes. Terraform core has always done this, accomplishing the sort through a parallel walk of all nodes, with each node becoming unblocked as soon as dependencies are satisfied, naturally creating a topological order for the visits. There however was no simple synchronous walk function which provided the same ordering of nodes. This led the refactoring package to erroneously use the only type of synchronous walk available,
ReverseDepthFirstWalk
. Since the majority of move graphs reduce into a simple tree, the depth-first walk appears to be correct at first glance, however if you take a simple diamond shaped graph like so:You can see that a depth-first walk from the top cannot work, since
4
is always going to be visited before one of it's dependencies, otherwise it would not be depth-first. (Note that breadth-first appears to work in this case, but that will just fail for differently shaped graphs where a node can be found at different depths via different paths, since breadth-first is also not a topological sort.)Add
TopologicalOrder
andReverseTopologicalOrder
methods todag.AcyclicGraph
, returning a sorted slice which can be used to visit the nodes in an order ensuring dependencies will always be satisfied. During thedag
package refactoring, additional breadth-first walks were also added for comparison and additional test coverage.Use
ReverseTopologicalSort
in therefactoring
package and iterate directly over each move statement. We can refactor this test too, removing all the address literals and parsing them directly from the test fixture.Fixes #31489.