Skip to content
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

Model call chains as an AbstractTokenTarget #443

Merged
merged 60 commits into from
Aug 23, 2023
Merged

Conversation

reese
Copy link
Collaborator

@reese reese commented Aug 16, 2023

Resolves #397

(Apologies in advance for the large PR, but this a pretty foundational change that required quite a bit of boilerplate!)

This PR implements call chains as a new AbstractTokenTarget: BreakableCallChainEntry. This means that multilining for call chains -- just like for existing breakables -- will be decided on-the-fly during rendering, where we have more contextual information and can better enforce line length.

This is done with a combination of the normal breakable machinery and some additional "magic tokens." Specifically, this adds tokens at the beginning and end of the indent-able portion of the call chain, and then during rendering, we maintain a count of how many nested call chains we're in and adjust indentation accordingly. This isn't exactly the cleanest implementation, but given the complexity in use-cases for call chains, it was the best I could muster in a way that functioned how users would generally expect.

This is a fairly large PR, but there's primarily three main portions which each are about a third of the total diff each: fixtures, the boilerplate in ripper_tree_types to support getting expression starting lines, and finally the main formatting changes. I've done my best to comment these areas appropriately, but it's helpful to add further explanation there, I'm more than happy to add more.

@reese reese force-pushed the reese-call-chain-breakable branch from f6208b6 to 4cb900c Compare August 16, 2023 20:36
# some stuff
}
.each do
<<~MYHEREDOC
Copy link
Owner

Choose a reason for hiding this comment

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

crimes

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

on the downside, i'm currently still debugging even more crimes

@reese reese force-pushed the reese-call-chain-breakable branch from 00da814 to 087a994 Compare August 18, 2023 00:44
@reese reese force-pushed the reese-call-chain-breakable branch from 8ff1e2b to 5653f0f Compare August 18, 2023 16:10
@reese reese force-pushed the reese-call-chain-breakable branch from b6b6103 to 64d273a Compare August 21, 2023 02:21
@reese reese changed the title [WIP] Call chain breakables Model call chains as an AbstractTokenTarget Aug 21, 2023
@reese reese marked this pull request as ready for review August 21, 2023 05:41
librubyfmt/src/format.rs Outdated Show resolved Hide resolved
librubyfmt/src/format.rs Outdated Show resolved Hide resolved
librubyfmt/src/format.rs Outdated Show resolved Hide resolved
} else {
format_ident(ps, ident);
}
ps.shift_comments();
}
CallChainElement::Block(b) => {
ps.emit_space();
format_block(ps, b)

Choose a reason for hiding this comment

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

are we missing a shift_comments call here?

Copy link
Collaborator Author

@reese reese Aug 22, 2023

Choose a reason for hiding this comment

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

I don't think we need to because format_{do,brace}_block should handle comment shifting internally (since they'll want to render the comments inside the block delimiters), but I'll add a comment here to make that explicit

librubyfmt/src/format.rs Outdated Show resolved Hide resolved
librubyfmt/src/render_targets.rs Outdated Show resolved Hide resolved
.any(|fc| fc == &FormattingContext::StringEmbexpr)
}

fn contains_hard_newline(&self) -> bool {

Choose a reason for hiding this comment

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

does this need to iter any nested breakable entries?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't think so, at least not in the way it's currently used, because when we check this we also check whether self.line_numbers has multiple lines, which I think would handle having a multiline nested breakable. (FWIW this method is unchanged from before)

librubyfmt/src/render_targets.rs Outdated Show resolved Hide resolved
@reese reese force-pushed the reese-call-chain-breakable branch from 8282aa6 to cf581b7 Compare August 23, 2023 15:59
@reese reese force-pushed the reese-call-chain-breakable branch from cf581b7 to 24f4b27 Compare August 23, 2023 15:59
Copy link
Owner

@fables-tales fables-tales left a comment

Choose a reason for hiding this comment

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

lgtm

@reese reese merged commit d170616 into trunk Aug 23, 2023
7 checks passed
@reese reese deleted the reese-call-chain-breakable branch August 23, 2023 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants