@@ -34,40 +34,40 @@ The memory consumption estimate is an approximate lower bound on the size of the
34
34
- `sortby` : the column to sort results by. Options are `:name` (default), `:size`, and `:summary`.
35
35
"""
36
36
function 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
43
52
(" " , typemax (Int))
44
53
else
45
54
ss = summarysize (value)
46
55
(format_bytes (ss), ss)
47
56
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])
59
58
end
60
- return allrows
61
59
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)
69
70
end
70
- rows = sort! (rows, by= r-> r[col], rev= reverse)
71
71
pushfirst! (rows, Any[" name" , " size" , " summary" ])
72
72
73
73
return Markdown. MD (Any[Markdown. Table (map (r-> r[1 : 3 ], rows), Symbol[:l , :r , :l ])])
@@ -206,54 +206,35 @@ function methodswith(t::Type; supertypes::Bool=false)
206
206
end
207
207
208
208
# subtypes
209
- function _subtypes (m:: Module , x:: Type , sts= Base. IdSet {Any} (), visited= Base. IdSet {Module} ())
210
- push! (visited, m)
209
+ function _subtypes_in! (mods:: Array , x:: Type )
211
210
xt = unwrap_unionall (x)
212
- if ! isa (xt, DataType)
213
- return sts
211
+ if ! isabstracttype (x) || ! isa (xt, DataType)
212
+ # Fast path
213
+ return Type[]
214
214
end
215
- xt = xt:: DataType
216
- for s in names (m, all = true )
217
- if isdefined (m, s) && ! isdeprecated (m, s)
218
- t = getfield (m, s)
219
- if isa (t, DataType)
220
- t = t:: DataType
221
- if t. name. name === s && supertype (t). name == xt. name
222
- ti = typeintersect (t, x)
223
- ti != Bottom && push! (sts, ti)
224
- end
225
- elseif isa (t, UnionAll)
226
- t = t:: UnionAll
227
- tt = unwrap_unionall (t)
228
- isa (tt, DataType) || continue
229
- tt = tt:: DataType
230
- if tt. name. name === s && supertype (tt). name == xt. name
231
- ti = typeintersect (t, x)
232
- ti != Bottom && push! (sts, ti)
215
+ sts = Vector {Any} ()
216
+ while ! isempty (mods)
217
+ m = pop! (mods)
218
+ xt = xt:: DataType
219
+ for s in names (m, all = true )
220
+ if isdefined (m, s) && ! isdeprecated (m, s)
221
+ t = getfield (m, s)
222
+ dt = isa (t, UnionAll) ? unwrap_unionall (t) : t
223
+ if isa (dt, DataType)
224
+ if dt. name. name === s && dt. name. module == m && supertype (dt). name == xt. name
225
+ ti = typeintersect (t, x)
226
+ ti != Bottom && push! (sts, ti)
227
+ end
228
+ elseif isa (t, Module) && nameof (t) === s && parentmodule (t) === m && t != = m
229
+ t === Base || push! (mods, t) # exclude Base, since it also parented by Main
233
230
end
234
- elseif isa (t, Module)
235
- t = t:: Module
236
- in (t, visited) || _subtypes (t, x, sts, visited)
237
231
end
238
232
end
239
233
end
240
- return sts
241
- end
242
-
243
- function _subtypes_in (mods:: Array , x:: Type )
244
- if ! isabstracttype (x)
245
- # Fast path
246
- return Type[]
247
- end
248
- sts = Base. IdSet {Any} ()
249
- visited = Base. IdSet {Module} ()
250
- for m in mods
251
- _subtypes (m, x, sts, visited)
252
- end
253
- return sort! (collect (sts), by= string)
234
+ return permute! (sts, sortperm (map (string, sts)))
254
235
end
255
236
256
- subtypes (m:: Module , x:: Type ) = _subtypes_in ([m], x)
237
+ subtypes (m:: Module , x:: Type ) = _subtypes_in! ([m], x)
257
238
258
239
"""
259
240
subtypes(T::DataType)
@@ -270,7 +251,7 @@ julia> subtypes(Integer)
270
251
Unsigned
271
252
```
272
253
"""
273
- subtypes (x:: Type ) = _subtypes_in (Base. loaded_modules_array (), x)
254
+ subtypes (x:: Type ) = _subtypes_in! (Base. loaded_modules_array (), x)
274
255
275
256
"""
276
257
supertypes(T::Type)
0 commit comments