Skip to content

Commit 53ca7b4

Browse files
committed
Add modules to list
1 parent 82cffbb commit 53ca7b4

File tree

1 file changed

+50
-33
lines changed

1 file changed

+50
-33
lines changed

src/APITools.jl

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ Licensed under MIT License, see LICENSE.md
1111
module APITools
1212

1313
const V6_COMPAT = VERSION < v"0.7.0-DEV"
14+
const BIG_ENDIAN = (ENDIAN_BOM == 0x01020304)
1415

15-
export @api, @def
16+
Base.parse(::Type{Expr}, args...; kwargs...) =
17+
Meta.parse(args...; kwargs...)
18+
19+
export @api, @def, V6_COMPAT, BIG_ENDIAN
1620

1721
macro def(name, definition)
1822
quote
@@ -75,29 +79,41 @@ const _cur_mod = V6_COMPAT ? :( current_module() ) : :( @__MODULE__ )
7579
* @api define_module <names...> # Add submodule names that are part of the API
7680
"""
7781
macro api(cmd::Symbol)
78-
if cmd == :init
79-
quote
80-
export @api, APITools
81-
global __tmp_api__ = APITools.TMP_API()
82-
global __tmp_chain__ = Vector{APITools.API}[]
83-
end
84-
elseif cmd == :freeze
85-
esc(quote
86-
const __api__ = APITools.API($_cur_mod, __tmp_api__)
87-
push!(__tmp_chain__, __api__)
88-
const __chain__ = APITools.APIList(__tmp_chain__)
89-
__tmp_chain__ = _tmp_api__ = nothing
90-
end)
91-
elseif cmd == :list
92-
quote
93-
show(__api__)
94-
show(__tmp_chain__)
95-
end
96-
else
97-
error("@api unrecognized command: $cmd")
82+
cmd == :init && return _api_init()
83+
cmd == :freeze && return _api_freeze()
84+
cmd == :list && return _api_list()
85+
error("@api unrecognized command: $cmd")
86+
end
87+
88+
function _api_display(mod)
89+
if isdefined(mod, :__api__)
90+
show(eval(mod, :__api__))
91+
show(eval(mod, :__chain__))
92+
end
93+
if isdefined(mod, :__tmp_api__)
94+
show(eval(mod, :__tmp_api__))
95+
show(eval(mod, :__tmp_chain__))
9896
end
97+
nothing
9998
end
10099

100+
_api_init() =
101+
quote
102+
export @api, APITools
103+
global __tmp_api__ = APITools.TMP_API()
104+
global __tmp_chain__ = APITools.API[]
105+
end
106+
107+
_api_freeze() =
108+
esc(quote
109+
const __api__ = APITools.API($_cur_mod, __tmp_api__)
110+
push!(__tmp_chain__, __api__)
111+
const __chain__ = APITools.APIList(__tmp_chain__)
112+
__tmp_chain__ = _tmp_api__ = nothing
113+
end)
114+
115+
_api_list(mod = _cur_mod) = :( _api_display($mod) )
116+
101117
const _cmduse = (:use, :test, :extend, :export)
102118
const _cmdadd =
103119
(:define_module, :define_public, :define_develop, :public, :develop, :base, :maybe_public)
@@ -111,7 +127,7 @@ _add_def!(deflst, explst, sym) = (push!(deflst, sym); push!(explst, esc(:(functi
111127
function _maybe_public(exprs)
112128
implst = Symbol[]
113129
deflst = Symbol[]
114-
explst = Expr[]
130+
explst = isdefined(eval(_cur_mod), :__tmp_api__) ? Expr[] : Expr[_api_init()]
115131
for ex in exprs
116132
if isa(ex, Expr) && ex.head == :tuple
117133
for sym in ex.args
@@ -124,13 +140,11 @@ function _maybe_public(exprs)
124140
error("@api $grp: syntax error $ex")
125141
end
126142
end
127-
lst = _add_symbols(:base, implst)
128-
isempty(deflst) && return lst
129-
Expr(:toplevel, lst, explst..., esc(:( append!(__tmp_api__.public, $deflst))))
143+
isempty(deflst) || push!(explst, esc(:( append!(__tmp_api__.public, $deflst))))
144+
Expr(:toplevel, _add_symbols(:base, implst)..., explst...)
130145
end
131146

132147
function _add_symbols(grp, exprs)
133-
grp == :maybe_public && return _maybe_public(exprs)
134148
symbols = Symbol[]
135149
for ex in exprs
136150
if isa(ex, Expr) && ex.head == :tuple
@@ -141,16 +155,13 @@ function _add_symbols(grp, exprs)
141155
error("@api $grp: syntax error $ex")
142156
end
143157
end
158+
lst = isdefined(eval(_cur_mod), :__tmp_api__) ? Expr[] : Expr[_api_init()]
144159
if grp == :base
145160
syms = SymList(symbols)
146161
expr = "APITools._make_list($(QuoteNode(:import)), $(QuoteNode(:Base)), $syms)"
147-
parsed = Meta.parse(expr)
148-
Expr(:toplevel,
149-
V6_COMPAT ? :(eval(current_module(), $parsed)) : :(eval(@__MODULE__, $parsed)),
150-
esc(:( append!(__tmp_api__.base, $symbols))))
151-
else
152-
esc(:( append!(__tmp_api__.$grp, $symbols) ))
162+
push!(lst, :(eval($_cur_mod, $(Meta.parse(expr)))))
153163
end
164+
Expr(:toplevel, lst..., esc(:( append!(__tmp_api__.$grp, $symbols) )))
154165
end
155166

156167
function _make_modules(exprs)
@@ -172,7 +183,7 @@ end
172183

173184
macro api(cmd::Symbol, exprs...)
174185
ind = _ff(_cmdadd, cmd)
175-
ind == 0 || return _add_symbols(cmd, exprs)
186+
ind == 0 || return cmd == :maybe_public ? _maybe_public(exprs) : _add_symbols(cmd, exprs)
176187

177188
ind = _ff(_cmduse, cmd)
178189

@@ -182,6 +193,8 @@ macro api(cmd::Symbol, exprs...)
182193
return esc(Expr(:toplevel, lst...,
183194
[:(eval(Expr( :export, $mod.__api__.$grp... )))
184195
for mod in modules, grp in (:define_module, :define_public, :public)]...))
196+
cmd == :list &&
197+
return Expr(:toplevel, [:(eval(Expr(:call, :_api_display, $mod))) for mod in modules]...)
185198

186199
for mod in modules
187200
push!(lst, _make_module_exprs(mod))
@@ -194,6 +207,10 @@ macro api(cmd::Symbol, exprs...)
194207
push!(lst, V6_COMPAT ? :(using Base.Test) : :(using Test))
195208
elseif cmd == :extend
196209
grplst = (:define_public, :define_develop)
210+
# should add unique modules to __tmp_chain__
211+
for mod in modules
212+
push!(lst, :(in($mod.__api__, __tmp_chain__) || push!(__tmp_chain__, $mod.__api__)))
213+
end
197214
for mod in modules, grp in (:base, :public, :develop)
198215
push!(lst, _make_exprs(:import, mod, grp))
199216
end

0 commit comments

Comments
 (0)