Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrite substitution resolver, use explicit immutable ResolveSource
The immediate motivation here was to fix #177, which this does, but in this commit a couple of existing test cases are broken in a way which seems to relate to order of resolution and resolve memoization. So we need to layer on to this commit better solutions for caching and cycle detection to get rid of yet more mutable state. The previous setup used a side-effect-based lookup table of "replacement" values to conceptually modify the tree without actually modifying it. Unfortunately that setup was hacky and hard to reason about and, apparently, broken in cases such as #177. This new setup actually creates a modified tree and passes it around explicitly instead of inside ResolveContext. In this commit, ResolveContext still unfortunately has a mutable cache and a mutable table of "cycle markers." Both of those in theory could also be replaced by simply modifying the tree. The main downside to this commit - and to cleaning up the remaining mutable state - is that we're using Java collections which have to be copied wholesale for every mutation (they are not persistent functional data structures). This will have an unknown performance impact, though in a sane world Config.resolve() is not a bottleneck in anyone's production app. Some other details of this commit: * resolve concerns removed from peekPath in AbstractConfigObject and relocated into ResolveSource * recursive resolution removed from lookupSubst and moved to ConfigReference * new hasDescendant() method used only in debug tracing, it is grossly inefficient to ever call this full tree traversal * new replaceChild() method is inefficient due to Java collections but could in theory be made efficient * most complexity relates to always knowing the parent of a node that we might have to replace, so we can walk up replacing it in its ancestor chain TODO in subsequent commits: * fix failing test cases * we cannot replaceChild if we are a descendant of ConfigConcatenation, but we probably (?) need to be able to; consider / fix this * instead of memoizing resolve results in a hash table, just continuously modify the ResolveSource to have the most recent results * instead of using the "cycle markers" table, change the ConfigReference to a cycle detector value
- Loading branch information
Showing
17 changed files
with
751 additions
and
351 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.