Skip to content

Commit

Permalink
fix with rewrites when keyword with an else stab (#220)
Browse files Browse the repository at this point in the history
Closes #219

fixes for both <1.17 and >=1.17
  • Loading branch information
novaugust authored Feb 20, 2025
1 parent 74d6fd2 commit fc6fb5d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ they can and will change without that change being reflected in Styler's semanti

#### Ex1.17+

Replace `:timer.units(x)` with the new `to_timeout(unit: x)` for `hours|minutes|seconds`
- Replace `:timer.units(x)` with the new `to_timeout(unit: x)` for `hours|minutes|seconds`
- Handle `, else: (_ -> x)` bugs introduced by `(_ -> x)` being termed a literal (#219, h/t @iamhassangm)

#### Ex1.18+

Expand Down Expand Up @@ -48,6 +49,7 @@ This release taught Styler to try just that little bit harder when doing alias l
### Fixes

- `pipes`: handle pipifying when the first arg is itself a pipe: `c(a |> b, d)` => `a |> b() |> c(d)` (#214, h/t @kybishop)
- `with`: correctly handle a stabby `with` `, else: (_ -> :ok)` being rewritten to a case (#219, h/t @iamhassangm)

## 1.3.3

Expand Down
25 changes: 23 additions & 2 deletions lib/style/blocks.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,31 @@ defmodule Styler.Style.Blocks do
# to `case single_statement do success -> body; ...elses end`
def run({{:with, m, [{:<-, am, [success, single_statement]}, [body, elses]]}, zm}, ctx) do
{{:__block__, do_meta, [:do]}, body} = body
{{:__block__, _else_meta, [:else]}, elses} = elses
{{:__block__, _, [:else]}, elses} = elses

elses =
case elses do
# unwrap a stab ala `, else: (_ -> :ok)`. these became literals in 1.17
{:__block__, _, [[{:->, _, _}] = stab]} -> stab
elses -> elses
end

# drops keyword formatting etc
do_meta = [line: do_meta[:line]]
clauses = [{{:__block__, am, [:do]}, [{:->, do_meta, [[success], body]} | elses]}]
end_line = Style.max_line(elses) + 1

# fun fact: i added the detailed meta just because i noticed it was missing while debugging something ...
# ... and it fixed the bug 🤷
case_meta = [
end_of_expression: [newlines: 1, line: end_line],
do: do_meta,
end: [line: end_line],
line: m[:line]
]

# recurse in case this new case should be rewritten to a `if`, etc
run({{:case, m, [single_statement, clauses]}, zm}, ctx)
run({{:case, case_meta, [single_statement, clauses]}, zm}, ctx)
end

# `with true <- x, do: bar` =>`if x, do: bar`
Expand Down
16 changes: 15 additions & 1 deletion test/style/blocks_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ defmodule Styler.Style.BlocksTest do
end
end

describe "with statements" do
describe "with" do
test "replacement due to no (or all removed) arrows" do
assert_style(
"""
Expand Down Expand Up @@ -787,6 +787,20 @@ defmodule Styler.Style.BlocksTest do
end
"""
end

test "elixir1.17+ stab regressions" do
assert_style(
"""
with :ok <- foo, do: :bar, else: (_ -> :baz)
""",
"""
case foo do
:ok -> :bar
_ -> :baz
end
"""
)
end
end

test "Credo.Check.Refactor.CondStatements" do
Expand Down

0 comments on commit fc6fb5d

Please sign in to comment.