-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
[REPL] Fix keyword arguments completions with do block #59123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
# Desugar do block call into call with lambda | ||
if ex_org.head === :do && length(ex_org.args) >= 2 | ||
ex_call = ex_org.args[1] | ||
ex_args = [x for x in ex_call.args if !(x isa Expr && x.head === :parameters)] | ||
ex_params = findfirst(x -> x isa Expr && x.head === :parameters, ex_call.args) | ||
new_args = [ex_args[1], ex_org.args[end], ex_args[2:end]...] | ||
ex_params !== nothing && push!(new_args, ex_call.args[ex_params]) | ||
ex_org = Expr(:call, new_args...) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The special-casing of the do
block makes me slightly nervous and I wonder if a more general solution would be possible (at the juliacon hackathon you mentioned the option of reading just up to position for the purpose of completion, but that also has drawbacks), but I could confirm this fixes the issue (as confirmed by the tests as well) and that makes me happy!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I'd call it a special case; I was just unaware when I changed this that JuliaSyntax puts the do
inside the call node rather than outside, like Expr
:
julia> Base.JuliaSyntax.parsestmt(Base.JuliaSyntax.SyntaxNode, "foo(a) do b; c end")
SyntaxNode:
[call]
foo :: Identifier
a :: Identifier
[do]
[tuple]
b :: Identifier
[block]
c :: Identifier
julia> Meta.show_sexpr(Expr(Base.JuliaSyntax.parsestmt(Base.JuliaSyntax.SyntaxNode, "foo(a) do b; c end")))
(:do, (:call, :foo, :a), (:->, (:tuple, :b), (:block,
:(#= line 1 =#),
:c
)))
The previous REPL completion code would have ignored the do
entirely, iirc. This change actually "fixes" method completion with a do block for free:
julia> foo(f, x::Int, y::Int) = 1
foo(f, x::String, y::String) = 2
foo (generic function with 2 methods)
julia> foo(3, ) do x; x end
foo(f, x::Int64, y::Int64) @ Main REPL[1]:1
Is this useful enough to justify parsing the input beyond the cursor? I don't know, but so far I haven't seen anything that really causes it to explode.
In
_complete_methods
, desugar the:do
Expr into a call with a lambda in the first argument.Fixes #58833.