@@ -11,8 +11,12 @@ Licensed under MIT License, see LICENSE.md
1111module APITools
1212
1313const 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
1721macro 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"""
7781macro 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
9998end
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+
101117const _cmduse = (:use , :test , :extend , :export )
102118const _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
111127function _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... )
130145end
131146
132147function _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) )))
154165end
155166
156167function _make_modules (exprs)
172183
173184macro 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