Fix issues with AbstractCodeWriter state stacks #2142
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.
Code writer context inheritance wasn't working in the previous implementation of the stack based inheritance system. We were able to resolve context from the current state and parent state (because of eagerly copying states and flattening them per/state), but we weren't able to look at parent states that used a CodeSection. Methods of a CodeSection state can be accessed in named template labels. However, when another state is pushed after setting a CodeSection value for a state, code writer wasn't crawling the state stack to see if previous CodeSections could provide a value for a named label that wasn't explicitly set as parameter in the context map. This was because instead of looking up values lazily by iterating over the state stack, we were making eager copies of different pieces of states. This matters when using things like for loops in templates that push an implicit state to capture the current loop iteration state.
This commit changes our approach to now actually use the stack itself and iterate over states when attempting to resolve context keys, formatters, iterators, and CodeSection values.
Some tests were added to ensure the behavior of the writer is the same. For example, when using inheritance based lookups, removing a context key now means we need to set a context key to an explicit null value to emulate the previous behavior. If we didn't do this, and we just called Map#remove(), the context key may have been set by a parent state, making the remove call do nothing (whereas the previous implementation would actually take effect).
Background
Testing
Links
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.