Skip to content

Commit

Permalink
Add support for endless method definitions (#405)
Browse files Browse the repository at this point in the history
* Fixtures

* Add support for endless method definitions
  • Loading branch information
reese authored Jan 3, 2023
1 parent 124c894 commit a5c6eeb
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 42 deletions.
13 changes: 13 additions & 0 deletions fixtures/small/endless_methods_actual.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class ForWeiMu
def we_are_both(travelers) = "dark-eyed with love".uppercase
def self.and_both_possessed_of = white_cloud_mind

private def why_set_out_for = EastMountain.when_here!
def spring_grasses = grow_deeper_day.by_day?
end

def more_examples = begin
dangerous_stuff!
rescue
puts "saved the day"
end
13 changes: 13 additions & 0 deletions fixtures/small/endless_methods_expected.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class ForWeiMu
def we_are_both(travelers) = "dark-eyed with love".uppercase
def self.and_both_possessed_of = white_cloud_mind

private def why_set_out_for = EastMountain.when_here!
def spring_grasses = grow_deeper_day.by_day?
end

def more_examples = begin
dangerous_stuff!
rescue
puts("saved the day")
end
85 changes: 45 additions & 40 deletions librubyfmt/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,62 @@ pub fn format_def(ps: &mut dyn ConcreteParserState, def: Def) {
ps.emit_indent();
}
ps.emit_def(def_expression.0);

format_def_body(ps, pp, *body, end_line);

if ps.at_start_of_line() {
ps.emit_newline();
}
}

fn format_def_body(
ps: &mut dyn ConcreteParserState,
pp: ParenOrParams,
bodystmt: DefBodyStmt,
end_line: LineNumber,
) {
let has_end = matches!(bodystmt, DefBodyStmt::EndBodyStmt(..));
ps.new_scope(Box::new(|ps| {
format_paren_or_params(ps, pp);

ps.with_formatting_context(
FormattingContext::Def,
Box::new(|ps| {
ps.new_block(Box::new(|ps| {
ps.emit_newline();
Box::new(|ps| match bodystmt {
DefBodyStmt::EndBodyStmt(bodystmt) => {
ps.new_block(Box::new(|ps| {
ps.emit_newline();
ps.with_start_of_line(
true,
Box::new(|ps| {
format_bodystmt(ps, Box::new(bodystmt), end_line);
}),
);
}));
}
DefBodyStmt::EndlessBodyStmt(bodystmt) => {
ps.emit_space();
ps.emit_op("=".to_string());
ps.emit_space();

ps.with_start_of_line(
true,
false,
Box::new(|ps| {
format_bodystmt(ps, body, end_line);
format_expression(ps, bodystmt.1);
}),
);
}));
)
}
}),
);
}));

ps.with_start_of_line(
true,
Box::new(|ps| {
ps.wind_dumping_comments_until_line(end_line);
ps.emit_end();
}),
);

if ps.at_start_of_line() {
ps.emit_newline();
if has_end {
ps.with_start_of_line(
true,
Box::new(|ps| {
ps.wind_dumping_comments_until_line(end_line);
ps.emit_end();
}),
);
}
}

Expand Down Expand Up @@ -2253,32 +2280,10 @@ pub fn format_defs(ps: &mut dyn ConcreteParserState, defs: Defs) {
ps.emit_dot();
let (ident, linecol) = ident_or_kw.to_def_parts();
handle_string_and_linecol(ps, ident, linecol);
format_paren_or_params(ps, paren_or_params);
}),
);

ps.with_formatting_context(
FormattingContext::Def,
Box::new(|ps| {
ps.new_block(Box::new(|ps| {
ps.emit_newline();
ps.with_start_of_line(
true,
Box::new(|ps| {
format_bodystmt(ps, bodystmt, end_line);
}),
);
}));
}),
);

ps.wind_dumping_comments_until_line(end_line);
ps.with_start_of_line(
true,
Box::new(|ps| {
ps.emit_end();
}),
);
format_def_body(ps, paren_or_params, *bodystmt, end_line);

if ps.at_start_of_line() {
ps.emit_newline();
Expand Down
14 changes: 12 additions & 2 deletions librubyfmt/src/ripper_tree_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ pub struct Def(
pub def_tag,
pub IdentOrOpOrKeywordOrConst,
pub ParenOrParams,
pub Box<BodyStmt>,
pub Box<DefBodyStmt>,
pub StartEnd,
);

Expand Down Expand Up @@ -778,6 +778,16 @@ pub struct BodyStmt(
pub Option<Ensure>,
);

// The bodystmt for endless defs
#[derive(Deserialize, Debug, Clone)]
pub struct EndlessBodyStmt(pub bodystmt_tag, pub Expression);

#[derive(RipperDeserialize, Debug, Clone)]
pub enum DefBodyStmt {
EndBodyStmt(BodyStmt),
EndlessBodyStmt(EndlessBodyStmt),
}

// deals with 2.6, where else is a vec expression and not an else
#[derive(RipperDeserialize, Debug, Clone)]
pub enum RescueElseOrExpressionList {
Expand Down Expand Up @@ -1693,7 +1703,7 @@ pub struct Defs(
pub DotOrColon,
pub IdentOrOpOrKeywordOrConst,
pub ParenOrParams,
pub Box<BodyStmt>,
pub Box<DefBodyStmt>,
pub StartEnd,
);

Expand Down

0 comments on commit a5c6eeb

Please sign in to comment.