@@ -34,40 +34,40 @@ The memory consumption estimate is an approximate lower bound on the size of the
3434- `sortby` : the column to sort results by. Options are `:name` (default), `:size`, and `:summary`.
3535"""
3636function varinfo (m:: Module = Main, pattern:: Regex = r" " ; all:: Bool = false , imported:: Bool = false , sortby:: Symbol = :name , recursive:: Bool = false )
37- @assert sortby in [:name , :size , :summary ] " Unrecognized `sortby` value `:$sortby `. Possible options are `:name`, `:size`, and `:summary`"
38- function _populate_rows (m2:: Module , allrows, include_self:: Bool , prep:: String )
39- newrows = Any[
40- let
41- value = getfield (m2, v)
42- ssize_str, ssize = if value=== Base || value=== Main || value=== Core
37+ sortby in (:name , :size , :summary ) || throw (ArgumentError (" Unrecognized `sortby` value `:$sortby `. Possible options are `:name`, `:size`, and `:summary`" ))
38+ rows = Vector{Any}[]
39+ workqueue = [(m, " " ),]
40+ while ! isempty (workqueue)
41+ m2, prep = popfirst! (workqueue)
42+ for v in names (m2; all, imported)
43+ if ! isdefined (m2, v) || ! occursin (pattern, string (v))
44+ continue
45+ end
46+ value = getfield (m2, v)
47+ isbuiltin = value === Base || value === Main || value === Core
48+ if recursive && ! isbuiltin && isa (value, Module) && value != = m2 && nameof (value) === v && parentmodule (value) === m2
49+ push! (workqueue, (value, " $prep$v ." ))
50+ end
51+ ssize_str, ssize = if isbuiltin
4352 (" " , typemax (Int))
4453 else
4554 ss = summarysize (value)
4655 (format_bytes (ss), ss)
4756 end
48- Any[string (prep, v), ssize_str, summary (value), ssize]
49- end
50- for v in names (m2; all, imported)
51- if (string (v) != split (string (m2), " ." )[end ] || include_self) && isdefined (m2, v) && occursin (pattern, string (v)) ]
52- append! (allrows, newrows)
53- if recursive
54- for row in newrows
55- if row[3 ] == " Module" && ! in (split (row[1 ], " ." )[end ], [split (string (m2), " ." )[end ], " Base" , " Main" , " Core" ])
56- _populate_rows (getfield (m2, Symbol (split (row[1 ], " ." )[end ])), allrows, false , prep * " $(row[1 ]) ." )
57- end
58- end
57+ push! (rows, Any[string (prep, v), ssize_str, summary (value), ssize])
5958 end
60- return allrows
6159 end
62- rows = _populate_rows (m, Vector{Any}[], true , " " )
63- if sortby == :name
64- col, reverse = 1 , false
65- elseif sortby == :size
66- col, reverse = 4 , true
67- elseif sortby == :summary
68- col, reverse = 3 , false
60+ let (col, rev) = if sortby == :name
61+ 1 , false
62+ elseif sortby == :size
63+ 4 , true
64+ elseif sortby == :summary
65+ 3 , false
66+ else
67+ @assert " unreachable"
68+ end
69+ sort! (rows; by= r-> r[col], rev)
6970 end
70- rows = sort! (rows, by= r-> r[col], rev= reverse)
7171 pushfirst! (rows, Any[" name" , " size" , " summary" ])
7272
7373 return Markdown. MD (Any[Markdown. Table (map (r-> r[1 : 3 ], rows), Symbol[:l , :r , :l ])])
@@ -208,54 +208,35 @@ function methodswith(t::Type; supertypes::Bool=false)
208208end
209209
210210# subtypes
211- function _subtypes (m:: Module , x:: Type , sts= Base. IdSet {Any} (), visited= Base. IdSet {Module} ())
212- push! (visited, m)
211+ function _subtypes_in! (mods:: Array , x:: Type )
213212 xt = unwrap_unionall (x)
214- if ! isa (xt, DataType)
215- return sts
213+ if ! isabstracttype (x) || ! isa (xt, DataType)
214+ # Fast path
215+ return Type[]
216216 end
217- xt = xt:: DataType
218- for s in names (m, all = true )
219- if isdefined (m, s) && ! isdeprecated (m, s)
220- t = getfield (m, s)
221- if isa (t, DataType)
222- t = t:: DataType
223- if t. name. name === s && supertype (t). name == xt. name
224- ti = typeintersect (t, x)
225- ti != Bottom && push! (sts, ti)
226- end
227- elseif isa (t, UnionAll)
228- t = t:: UnionAll
229- tt = unwrap_unionall (t)
230- isa (tt, DataType) || continue
231- tt = tt:: DataType
232- if tt. name. name === s && supertype (tt). name == xt. name
233- ti = typeintersect (t, x)
234- ti != Bottom && push! (sts, ti)
217+ sts = Vector {Any} ()
218+ while ! isempty (mods)
219+ m = pop! (mods)
220+ xt = xt:: DataType
221+ for s in names (m, all = true )
222+ if isdefined (m, s) && ! isdeprecated (m, s)
223+ t = getfield (m, s)
224+ dt = isa (t, UnionAll) ? unwrap_unionall (t) : t
225+ if isa (dt, DataType)
226+ if dt. name. name === s && dt. name. module == m && supertype (dt). name == xt. name
227+ ti = typeintersect (t, x)
228+ ti != Bottom && push! (sts, ti)
229+ end
230+ elseif isa (t, Module) && nameof (t) === s && parentmodule (t) === m && t != = m
231+ t === Base || push! (mods, t) # exclude Base, since it also parented by Main
235232 end
236- elseif isa (t, Module)
237- t = t:: Module
238- in (t, visited) || _subtypes (t, x, sts, visited)
239233 end
240234 end
241235 end
242- return sts
243- end
244-
245- function _subtypes_in (mods:: Array , x:: Type )
246- if ! isabstracttype (x)
247- # Fast path
248- return Type[]
249- end
250- sts = Base. IdSet {Any} ()
251- visited = Base. IdSet {Module} ()
252- for m in mods
253- _subtypes (m, x, sts, visited)
254- end
255- return sort! (collect (sts), by= string)
236+ return permute! (sts, sortperm (map (string, sts)))
256237end
257238
258- subtypes (m:: Module , x:: Type ) = _subtypes_in ([m], x)
239+ subtypes (m:: Module , x:: Type ) = _subtypes_in! ([m], x)
259240
260241"""
261242 subtypes(T::DataType)
@@ -274,7 +255,7 @@ julia> subtypes(Integer)
274255 Unsigned
275256```
276257"""
277- subtypes (x:: Type ) = _subtypes_in (Base. loaded_modules_array (), x)
258+ subtypes (x:: Type ) = _subtypes_in! (Base. loaded_modules_array (), x)
278259
279260"""
280261 supertypes(T::Type)
0 commit comments