Skip to content

Commit a56904d

Browse files
authored
Compat for odd Exprs in long form anonymous functions (#6)
The following construct is parsed oddly by the reference parser with the tuple omitted from the argument list. Add a compatibility hack for that during Expr conversion. function (xs...) body end With this we now have compatible parsing for all of the stdlib for Julia 1.6 and 1.7, so turn on this test by default in those cases.
1 parent e6fd15d commit a56904d

File tree

4 files changed

+24
-2
lines changed

4 files changed

+24
-2
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,10 @@ parsing `key=val` pairs inside parentheses.
546546
or (b) all lines should be dedented only one character, as that's the
547547
matching prefix.
548548

549+
* Parsing of anonymous function arguments is somewhat inconsistent.
550+
`function (xs...) \n body end` parses the argument list as `(... xs)`, whereas
551+
`function (x) \n body end` parses the argument list as `(tuple x)`.
552+
549553
# Comparisons to other packages
550554

551555
### Official Julia compiler

src/syntax_tree.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,16 @@ function _to_expr(node::SyntaxNode, iteration_spec=false)
415415
# Add block for source locations
416416
args[2] = Expr(:block, loc, args[2])
417417
end
418+
elseif headsym == :function
419+
if length(args) > 1 && Meta.isexpr(args[1], :tuple)
420+
# Convert to weird Expr forms for long-form anonymous functions.
421+
#
422+
# (function (tuple (... xs)) body) ==> (function (... xs) body)
423+
if length(args[1].args) == 1 && Meta.isexpr(args[1].args[1], :...)
424+
# function (xs...) \n body end
425+
args[1] = args[1].args[1]
426+
end
427+
end
418428
end
419429
if headsym == :inert || (headsym == :quote && length(args) == 1 &&
420430
!(a1 = only(args); a1 isa Expr || a1 isa QuoteNode ||

test/parse_packages.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ base_tests_path = joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "test")
2020
end
2121

2222
end
23-
if haskey(ENV, "PARSE_STDLIB")
24-
# TODO: Turn on by default
23+
24+
if VERSION < v"1.8-DEV" || haskey(ENV, "PARSE_STDLIB")
25+
# TODO: Fix on 1.8
2526

2627
@testset "Parse Julia stdlib at $(Sys.STDLIB)" begin
2728
for stdlib in readdir(Sys.STDLIB)

test/syntax_tree.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,11 @@
2424
Expr(:(=), Expr(:call, :f), :xs),
2525
Expr(:block))
2626
end
27+
28+
@testset "Long form anonymous functions" begin
29+
@test parseall(Expr, "function (xs...)\nbody end", rule=:statement) ==
30+
Expr(:function,
31+
Expr(:..., :xs),
32+
Expr(:block, :body))
33+
end
2734
end

0 commit comments

Comments
 (0)