From 3349e87ef7b1ac381b7d9d16cee95a01bbae5428 Mon Sep 17 00:00:00 2001 From: Lionel Zoubritzky Date: Wed, 2 Mar 2022 00:11:42 +0100 Subject: [PATCH] Factored representation for REPLCompletion --- stdlib/REPL/src/REPLCompletions.jl | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 162d1184d18c39..190af01334b29b 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -42,8 +42,8 @@ end struct MethodCompletion <: Completion tt # may be used by an external consumer to infer return type, etc. - method::Method - MethodCompletion(@nospecialize(tt), method::Method) = new(tt, method) + method::Base.FactoredMethod + MethodCompletion(@nospecialize(tt), method::Base.FactoredMethod) = new(tt, method) end struct BslashCompletion <: Completion @@ -78,7 +78,7 @@ function Base.getproperty(c::Completion, name::Symbol) elseif name === :field return getfield(c, :field)::Symbol elseif name === :method - return getfield(c, :method)::Method + return getfield(c, :method)::Base.FactoredMethod elseif name === :bslash return getfield(c, :bslash)::String elseif name === :text @@ -575,7 +575,7 @@ function complete_any_methods(ex_org::Expr, callee_module::Module, context_modul filter!(out) do c isa(c, TextCompletion) && return false isa(c, MethodCompletion) || return true - sig = Base.unwrap_unionall(c.method.sig)::DataType + sig = Base.unwrap_unionall(c.method.m.sig)::DataType return !all(T -> T === Any || T === Vararg{Any}, sig.parameters[2:end]) end end @@ -611,15 +611,24 @@ end function complete_methods!(out::Vector{Completion}, @nospecialize(funct), args_ex::Vector{Any}, kwargs_ex::Bool, max_method_completions::Int) # Input types and number of arguments t_in = Tuple{funct, args_ex...} - m = Base._methods_by_ftype(t_in, nothing, max_method_completions, Base.get_world_counter(), + ml = Base._methods_by_ftype(t_in, nothing, max_method_completions, Base.get_world_counter(), #=ambig=# true, Ref(typemin(UInt)), Ref(typemax(UInt)), Ptr{Int32}(C_NULL)) - if m === false + if ml === false push!(out, TextCompletion(sprint(Base.show_signature_function, funct) * "( too many methods to show )")) end - m isa Vector || return - for match in m + ml isa Vector || return + isempty(ml) && return + mm = [m::Core.MethodMatch for m in ml] + first_m = mm[1].method + if first_m.sig === Tuple # Builtin + push!(out, MethodCompletion(t_in, Base.FactoredMethod(first_m))) + return + end + mt = Base.get_methodtable(first_m) + fml = Base.FactoredMethodList(Base.MethodList([m.method for m in mm], mt)) + for (fm, pos) in zip(fml.list, fml.positions) # TODO: if kwargs_ex, filter out methods without kwargs? - push!(out, MethodCompletion(match.spec_types, match.method)) + push!(out, MethodCompletion(mm[last(pos)].spec_types, fm)) end end