-
Notifications
You must be signed in to change notification settings - Fork 2.4k
fix(fmt): keep struct field access on same line after named args call #13166
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
Conversation
Fixes #12399 When accessing a struct field after a function call with named arguments (e.g., `_lzSend({...}).guid`), the formatter was incorrectly placing the `.field` on a new line. The fix detects calls with named arguments and skips the zerobreak that was causing the unwanted line break. This keeps the field access on the same line as the closing `})`. Example - before: ```solidity bytes32 guid = _lzSend({ _dstEid: dstEid, ... }) .guid; // <-- unwanted line break ``` Example - after: ```solidity bytes32 guid = _lzSend({ _dstEid: dstEid, ... }).guid; // field stays on same line ``` Amp-Thread-ID: https://ampcode.com/threads/T-019bdc92-a774-749b-a831-7d9de5021e45 Co-authored-by: Amp <amp@ampcode.com>
ff972ff to
2677aa9
Compare
grandizzy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good, @0xrusowsky mind to have a quick look before merge? thanks!
|
Hey @gakonst 👋 Could you add an extra test case for chained calls with named args to ensure the second chained call and final Something like this in // Chained calls with named args
function e() external {
bytes32 guid = firstCall({
param1: value1,
param2: value2
}).secondCall({
arg1: val1,
arg2: val2
}).guid;
}And the corresponding expected output in // Chained calls with named args
function e() external {
bytes32 guid = firstCall({
param1: value1,
param2: value2
}).secondCall({
arg1: val1,
arg2: val2
}).guid;
}This would verify that when you have multiple chained calls each using named args, the fix works for all of them (not just the first call), and that the final |
This reverts commit bb80b1d.
When a chain expression (like _lzSend({...}).guid) doesn't fit on one
line and requires a line break continuation, the chain's ibox may or
may not add indentation depending on whether the callee fits.
Previously, has_chain() would return true for any chain in the stack,
causing without_ind(true) to skip commasep indentation even when the
chain didn't add its own indentation. This resulted in under-indented
named args.
The fix tracks whether each chain context actually added its own
indentation via a new has_indent flag on CallContext. The new
has_chain_with_indent() method only returns true when a chain in
the stack has its own indentation, ensuring we only skip commasep
indentation when it would cause double-indentation.
Also updated test case to use a more realistic chained call pattern
that actually requires line breaks.
…#13166) * fix(fmt): keep struct field access on same line after named args call Fixes #12399 When accessing a struct field after a function call with named arguments (e.g., `_lzSend({...}).guid`), the formatter was incorrectly placing the `.field` on a new line. The fix detects calls with named arguments and skips the zerobreak that was causing the unwanted line break. This keeps the field access on the same line as the closing `})`. Example - before: ```solidity bytes32 guid = _lzSend({ _dstEid: dstEid, ... }) .guid; // <-- unwanted line break ``` Example - after: ```solidity bytes32 guid = _lzSend({ _dstEid: dstEid, ... }).guid; // field stays on same line ``` Amp-Thread-ID: https://ampcode.com/threads/T-019bdc92-a774-749b-a831-7d9de5021e45 Co-authored-by: Amp <amp@ampcode.com> * test(fmt): add chained calls with named args test case * fix(fmt): correct expected indentation in test file * Revert "fix(fmt): correct expected indentation in test file" This reverts commit bb80b1d. * fix(fmt): track chain indentation to fix named args formatting When a chain expression (like _lzSend({...}).guid) doesn't fit on one line and requires a line break continuation, the chain's ibox may or may not add indentation depending on whether the callee fits. Previously, has_chain() would return true for any chain in the stack, causing without_ind(true) to skip commasep indentation even when the chain didn't add its own indentation. This resulted in under-indented named args. The fix tracks whether each chain context actually added its own indentation via a new has_indent flag on CallContext. The new has_chain_with_indent() method only returns true when a chain in the stack has its own indentation, ensuring we only skip commasep indentation when it would cause double-indentation. Also updated test case to use a more realistic chained call pattern that actually requires line breaks. * chore: rustfmt --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com>
* fix(anvil): clear stale block hashes from db cache during reorg After anvil_reorg, the BLOCKHASH opcode was returning stale/incorrect hashes because the block hashes stored in the database cache (used by the EVM for the BLOCKHASH opcode) were not being cleared when blocks were unwound during a reorg. The fix adds a remove_block_hash method to the Db trait and calls it during rollback to remove the stale block hashes for unwound blocks. When new blocks are mined after the reorg, do_mine_block correctly inserts the new block hashes. Fixes #13165 Amp-Thread-ID: https://ampcode.com/threads/T-019be58a-cfdc-770c-a9bf-5a96b31339e9 Co-authored-by: Amp <amp@ampcode.com> * fix: correct return type access and formatting for test * style: apply cargo +nightly fmt * fix: remove incorrect field access on FixedBytes return type * fix: restore preserved block hashes after clearing db cache during rollback The previous fix only removed stale hashes but clear() wipes ALL block hashes including valid ones. Now we collect the hashes for blocks that should be preserved (0 to common_block.number) before clearing, then restore them after. * fix: reorder rollback to unwind first, then restore block hashes from sparse storage Instead of iterating 0..N blocks, we now: 1. Unwind storage first (removes unwound block hashes) 2. Clear db cache and restore accounts 3. Restore block hashes by iterating storage.hashes (sparse, only existing blocks) * fix: collect block hashes before await to avoid holding lock across await * chore(deps): bump to foundry-compilers v0.19.4 (#13178) bump to v0.19.4 * fix(fmt): keep struct field access on same line after named args call (#13166) * fix(fmt): keep struct field access on same line after named args call Fixes #12399 When accessing a struct field after a function call with named arguments (e.g., `_lzSend({...}).guid`), the formatter was incorrectly placing the `.field` on a new line. The fix detects calls with named arguments and skips the zerobreak that was causing the unwanted line break. This keeps the field access on the same line as the closing `})`. Example - before: ```solidity bytes32 guid = _lzSend({ _dstEid: dstEid, ... }) .guid; // <-- unwanted line break ``` Example - after: ```solidity bytes32 guid = _lzSend({ _dstEid: dstEid, ... }).guid; // field stays on same line ``` Amp-Thread-ID: https://ampcode.com/threads/T-019bdc92-a774-749b-a831-7d9de5021e45 Co-authored-by: Amp <amp@ampcode.com> * test(fmt): add chained calls with named args test case * fix(fmt): correct expected indentation in test file * Revert "fix(fmt): correct expected indentation in test file" This reverts commit bb80b1d. * fix(fmt): track chain indentation to fix named args formatting When a chain expression (like _lzSend({...}).guid) doesn't fit on one line and requires a line break continuation, the chain's ibox may or may not add indentation depending on whether the callee fits. Previously, has_chain() would return true for any chain in the stack, causing without_ind(true) to skip commasep indentation even when the chain didn't add its own indentation. This resulted in under-indented named args. The fix tracks whether each chain context actually added its own indentation via a new has_indent flag on CallContext. The new has_chain_with_indent() method only returns true when a chain in the stack has its own indentation, ensuring we only skip commasep indentation when it would cause double-indentation. Also updated test case to use a more realistic chained call pattern that actually requires line breaks. * chore: rustfmt --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com> * refactor: improve rollback block hash restoration - Remove unused remove_block_hash trait method - Acquire db lock once during restore to reduce lock churn - Insert account info before storage to prevent fork-mode RPC fetches - Bound block hash restoration to last 256 blocks (EVM BLOCKHASH limit) - Increase test reorg depth from 1 to 5 for better coverage * test: add deep reorg test for 256-block BLOCKHASH limit Tests a 50-block reorg on a 300+ block chain to verify: - Block hashes within 256 window remain consistent after reorg - BLOCKHASH returns 0 for blocks outside the 256 window * fmt --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Co-authored-by: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com> Co-authored-by: zerosnacks <zerosnacks@protonmail.com>
Motivation
Closes #12399
When accessing a struct field after a function call with named arguments (e.g.,
_lzSend({...}).guid), the formatter was incorrectly placing the.fieldon a new line with weird indentation.Before:
After:
Solution
Added detection for calls with named arguments in the member expression handling. When the preceding expression is a call using named arguments (the
{key: value}syntax), we skip thezerobreak()that was causing the unwanted line break.This specifically targets the pattern from the issue report while preserving existing behavior for:
obj.method().anotherMethod())PR Checklist
testdata/StructFieldAccess/)