Browse Source

Don't add explicit returns in `do` blocks (#70)

pull/71/head
Fredrik Ekre 1 year ago committed by GitHub
parent
commit
65f4cc340b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 15
      README.md
  2. 2
      src/runestone.jl
  3. 20
      test/runtests.jl

15
README.md

@ -411,9 +411,8 @@ x = a + b * @@ -411,9 +411,8 @@ x = a + b *
### Explicit `return`
Explicit `return` statements are ensured in function/macro definitions as well as in
`do`-blocks by adding `return` in front of the last expression, with some exceptions listed
below.
Explicit `return` statements are ensured in function and macro definitions by adding
`return` in front of the last expression, with some exceptions listed below.
- If the last expression is a `for` or `while` loop (which both always evaluate to
`nothing`) `return` is added *after* the loop.
@ -423,6 +422,8 @@ below. @@ -423,6 +422,8 @@ below.
there is no `return` inside the block.
- If the last expression is a macro call, the `return` is only added in case there is no
`return` inside the macro.
- No `return` is added in short form functions (`f(...) = ...`), short form anonymous
functions (`(...) -> ...`), and `do`-blocks (`f(...) do ...; ...; end`).
- If the last expression is a function call, and the function name is (or contains) `throw`
or `error`, no `return` is added. This is because it is already obvious that these calls
terminate the function and don't return any value.
@ -449,14 +450,6 @@ Examples: @@ -449,14 +450,6 @@ Examples:
- :(generate_expr(args...))
+ return :(generate_expr(args...))
end
function g()
- open("/dev/random", "r") do f
- read(f, 8)
+ return open("/dev/random", "r") do f
+ return read(f, 8)
end
end
```
#### Potential changes

2
src/runestone.jl

@ -3584,7 +3584,7 @@ function explicit_return_block(ctx, node) @@ -3584,7 +3584,7 @@ function explicit_return_block(ctx, node)
end
function explicit_return(ctx::Context, node::Node)
if !(!is_leaf(node) && kind(node) in KSet"function macro do")
if !(!is_leaf(node) && kind(node) in KSet"function macro")
return nothing
end
if !safe_to_insert_return(ctx, node)

20
test/runtests.jl

@ -487,9 +487,9 @@ end @@ -487,9 +487,9 @@ end
@test format_string("try\nerror()\ncatch$(sp)e\nend") == "try\n error()\ncatch e\nend"
@test format_string("A$(sp)where$(sp){T}") == "A where {T}"
@test format_string("A$(sp)where$(sp){T}$(sp)where$(sp){S}") == "A where {T} where {S}"
@test format_string("f()$(sp)do$(sp)x\ny\nend") == "f() do x\n return y\nend"
@test format_string("f()$(sp)do\ny\nend") == "f() do\n return y\nend"
@test format_string("f()$(sp)do; y end") == "f() do;\n return y\nend"
@test format_string("f()$(sp)do$(sp)x\ny\nend") == "f() do x\n y\nend"
@test format_string("f()$(sp)do\ny\nend") == "f() do\n y\nend"
@test format_string("f()$(sp)do; y end") == "f() do;\n y\nend"
# After `where` (anywhere else?) a newline can be used instead of a space
@test format_string("A$(sp)where$(sp)\n{A}") == "A where\n{A}"
end
@ -647,8 +647,8 @@ end @@ -647,8 +647,8 @@ end
"try\n$(sp)x\n$(sp)catch err\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)finally\n$(sp)z\n$(sp)end"
) == "try\n x\ncatch err\n y\nelse\n z\nfinally\n z\nend"
# do-end
@test format_string("open() do\n$(sp)a\n$(sp)end") == "open() do\n return a\nend"
@test format_string("open() do io\n$(sp)a\n$(sp)end") == "open() do io\n return a\nend"
@test format_string("open() do\n$(sp)a\n$(sp)end") == "open() do\n a\nend"
@test format_string("open() do io\n$(sp)a\n$(sp)end") == "open() do io\n a\nend"
# module-end, baremodule-end
for b in ("", "bare")
# Just a module
@ -1082,11 +1082,11 @@ end @@ -1082,11 +1082,11 @@ end
@test format_string("try$(d)x$(d)catch err$(d)y$(d)else$(d)z$(d)finally$(d)z$(d)end") ==
"try\n x\ncatch err\n y\nelse\n z\nfinally\n z\nend"
# do-end
@test format_string("open() do\na$(d)end") == "open() do\n return a\nend"
@test format_string("open() do\na$(d)end") == "open() do\n a\nend"
@test format_string("open() do\nend") == "open() do\nend"
@test_broken format_string("open() do;a$(d)end") == "open() do\n a\nend"
@test_broken format_string("open() do ;a$(d)end") == "open() do\n a\nend"
@test format_string("open() do io$(d)a end") == "open() do io\n return a\nend"
@test format_string("open() do io$(d)a end") == "open() do io\n a\nend"
# let-end
@test format_string("let a = 1\nx$(d)end") == "let a = 1\n x\nend"
@test format_string("let\nx$(d)end") == "let\n x\nend"
@ -1216,7 +1216,7 @@ end @@ -1216,7 +1216,7 @@ end
"begin", "quote", "for i in I", "let", "let x = 1", "while cond",
"if cond", "macro f()", "function f()", "f() do", "f() do x",
)
rx = prefix in ("function f()", "macro f()", "f() do", "f() do x") ? " return x\n" : ""
rx = prefix in ("function f()", "macro f()") ? " return x\n" : ""
@test format_string("$(prefix)\n$(body)$(rx)\nend") == "$prefix\n$(bodyfmt)$(rx)\nend"
end
@test format_string(
@ -1255,7 +1255,7 @@ end @@ -1255,7 +1255,7 @@ end
end
@testset "explicit return" begin
for f in ("function f()", "function ()", "f() do", "macro m()")
for f in ("function f()", "function ()", "macro m()")
# Simple cases just prepend `return`
for r in (
"x", "*", "x, y", "(x, y)", "f()", "[1, 2]", "Int[1, 2]", "[1 2]", "Int[1 2]",
@ -1265,7 +1265,7 @@ end @@ -1265,7 +1265,7 @@ end
"a.b", "a.b.c", "x -> x^2", "[x for x in X]", "Int[x for x in X]",
"A{T} where {T}", "(@m a, b)", "A{T}",
"r\"foo\"", "r\"foo\"m", "`foo`", "```foo```", "r`foo`",
"f() do\n return x\n end", "f() do x\n return x\n end",
"f() do\n x\n end", "f() do x\n x\n end",
"function f()\n return x\n end",
"function ()\n return x\n end",
"quote\n x\n end", "begin\n x\n end",

Loading…
Cancel
Save