Skip to content

Commit 6e246b2

Browse files
JuliaSyntax: fix anonymous function parsing (JuliaLang#60221)
1 parent ea7dbfc commit 6e246b2

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

JuliaSyntax/src/julia/parser.jl

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2218,10 +2218,23 @@ function parse_function_signature(ps::ParseState, is_function::Bool)
22182218
opts = parse_brackets(ps, K")") do had_commas, had_splat, num_semis, num_subexprs
22192219
_parsed_call = was_eventually_call(ps)
22202220
_maybe_grouping_parens = !had_commas && !had_splat && num_semis == 0 && num_subexprs == 1
2221-
# Skip intervening newlines only when the parentheses hold a single
2222-
# expression, which is the ambiguous case between a name like (::T)
2223-
# and an anonymous function parameter list.
2224-
next_kind = peek(ps, 2, skip_newlines=_maybe_grouping_parens)
2221+
# Check if there's a newline between `)` and the next `(` or `.`.
2222+
# We need to find where `)` is and check what immediately follows it.
2223+
# If peek(1, skip_newlines=false) is `)`, we're directly before it.
2224+
# Otherwise there's whitespace/newline before `)`.
2225+
next_token_pos = if peek(ps, 1, skip_newlines=false) == K")"
2226+
# Directly before ), token after ) is at 2
2227+
2
2228+
else
2229+
# There's whitespace before ), so ) is at 2
2230+
# and what follows ) is at 3
2231+
3
2232+
end
2233+
token_after_paren = peek(ps, next_token_pos, skip_newlines=false)
2234+
# If token_after_paren is a newline, this is an anonymous function
2235+
has_newline_after_paren = _maybe_grouping_parens && token_after_paren == K"NewlineWs"
2236+
# Get the next significant token to determine if we need to parse a call
2237+
next_kind = peek(ps, 2, skip_newlines=_maybe_grouping_parens && !has_newline_after_paren)
22252238
_needs_parse_call = next_kind KSet"( ."
22262239
_is_anon_func = (!_needs_parse_call && !_parsed_call) || had_commas
22272240
return (needs_parameters = _is_anon_func,

JuliaSyntax/test/parser.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,8 @@ tests = [
611611
"macro \$f() end" => "(macro (call (\$ f)) (block))"
612612
"macro (\$f)() end" => "(macro (call (parens (\$ f))) (block))"
613613
"function (x) body end"=> "(function (tuple-p x) (block body))"
614+
"function (x)\n body\nend"=> "(function (tuple-p x) (block body))"
615+
"function (x)\n() end" => "(function (tuple-p x) (block (tuple-p)))"
614616
"function (x,y) end" => "(function (tuple-p x y) (block))"
615617
"function (x,y,) end" => "(function (tuple-p-, x y) (block))"
616618
"function (x=1) end" => "(function (tuple-p (= x 1)) (block))"

0 commit comments

Comments
 (0)