Skip to content

Validate computeMessageIfAbsent and getMessages() writes against ExecutionContext mutation - #9011

Open
timtebeek wants to merge 1 commit into
mainfrom
tim/recipes-context-validation
Open

timtebeek wants to merge 1 commit into
mainfrom
tim/recipes-context-validation

Conversation

@timtebeek

Copy link
Copy Markdown
Member

RewriteTest's immutableExecutionContext check only covered putMessage: computeMessageIfAbsent and writes through getMessages() went straight to the raw message map, and DelegatingExecutionContext didn't forward computeMessageIfAbsent, so recipes, which receive a wrapped context, bypassed the check entirely. This forwards that call, validates it (only when a value is actually computed), and returns a validating map from getMessages() while the check is on. Production runs are unaffected, as the check is a test-only assert. In-repo writers are adjusted: the Maven and Node context views move to computeMessageIfAbsent, the run-scoped Singleton and Python/JavaScript keys are allowed, and UpgradeTransitiveDependencyVersion caches its parsed Gradle snippets on the root cursor, now threading the parent cursor so nested visitors share it across files. Downstream test suites were run against this change; the only failures it surfaced are fixed by the PRs below.

Downstream:

…utionContext mutation

RewriteTest's immutableExecutionContext check only covered putMessage. computeMessageIfAbsent
wrote to the raw message map, and DelegatingExecutionContext didn't forward it, so writes
through any wrapper view (including the WatchableExecutionContext recipes receive) bypassed
the check; writes through getMessages() did as well.

- Forward computeMessageIfAbsent in DelegatingExecutionContext and validate it in
  CursorValidatingExecutionContextView, only when a value is actually computed.
- Return a validating map from getMessages() while the check is enabled.
- Allow the run-scoped keys used by Singleton and the Python/JavaScript dependency helpers.
- Move Maven and Node context views off getMessages().computeIfAbsent.
- Cache UpgradeTransitiveDependencyVersion's parsed Gradle snippets on the root cursor,
  threading the parent cursor so nested visitors share it across files.
@timtebeek timtebeek added the enhancement New feature or request label Oct 1, 2026
@timtebeek
timtebeek requested a review from sambsnyd October 1, 2026 17:14
@timtebeek

Copy link
Copy Markdown
Member Author

@sambsnyd I think you'd added these checks earlier, right? There were some gaps, and a bug in the missed delegation.

@sambsnyd sambsnyd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks Tim!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Ready to Review

Development

Successfully merging this pull request may close these issues.

2 participants