@@ -28,7 +28,8 @@ struct TMP_API
2828 develop:: Vector{Symbol}
2929 define_public:: Vector{Symbol}
3030 define_develop:: Vector{Symbol}
31- TMP_API () = new (Symbol[], Symbol[], Symbol[], Symbol[], Symbol[])
31+ define_module:: Vector{Symbol}
32+ TMP_API () = new (Symbol[], Symbol[], Symbol[], Symbol[], Symbol[], Symbol[])
3233end
3334
3435const SymList = Tuple{Vararg{Symbol}}
@@ -40,11 +41,12 @@ struct API
4041 develop:: SymList
4142 define_public:: SymList
4243 define_develop:: SymList
44+ define_module:: SymList
4345
4446 API (mod, api:: TMP_API ) =
4547 new (mod,
4648 SymList (api. base), SymList (api. public), SymList (api. develop),
47- SymList (api. define_public), SymList (api. define_develop))
49+ SymList (api. define_public), SymList (api. define_develop), SymList (api . define_module) )
4850end
4951
5052const APIList = Tuple{Vararg{API}}
@@ -65,11 +67,12 @@ const APIList = Tuple{Vararg{API}}
6567 * @api develop <names...> # Add functions that are part of the development API
6668 * @api define_public <names...> # Add other symbols that are part of the public API (structs, consts)
6769 * @api define_develop <names...> # Add other symbols that are part of the development API
70+ * @api define_module <names...> # Add submodule names that are part of the API
6871"""
6972macro api (cmd:: Symbol )
7073 if cmd == :init
7174 quote
72- export @api
75+ export @api , APITools
7376 global __tmp_api__ = APITools. TMP_API ()
7477 global __tmp_chain__ = Vector{APITools. API}[]
7578 end
@@ -92,8 +95,9 @@ macro api(cmd::Symbol)
9295 end
9396end
9497
95- const _cmdadd = (:define_public , :define_develop , :public , :develop , :base , :maybe_public )
9698const _cmduse = (:use , :test , :extend , :export )
99+ const _cmdadd =
100+ (:define_module , :define_public , :define_develop , :public , :develop , :base , :maybe_public )
97101
98102@static V6_COMPAT && (const _ff = findfirst)
99103@static V6_COMPAT || (_ff (lst, val) = coalesce (findfirst (isequal (val), lst), 0 ))
@@ -168,24 +172,29 @@ macro api(cmd::Symbol, exprs...)
168172 ind == 0 || return _add_symbols (cmd, exprs)
169173
170174 ind = _ff (_cmduse, cmd)
171- ind == 0 && error (" @api unrecognized command: $cmd " )
172175
173176 lst, modules = _make_modules (exprs)
174177
175- if ind == 1 # use
178+ cmd == :export &&
179+ return esc (Expr (:toplevel , lst... ,
180+ [:(eval (Expr ( :export , $ mod. __api__.$ grp... )))
181+ for mod in modules, grp in (:define_module , :define_public , :public )]. .. ))
182+
183+ for mod in modules
184+ push! (lst, _make_module_exprs (mod))
185+ end
186+
187+ if cmd == :use
176188 grplst = (:public , :define_public )
177- elseif ind == 2 # test
178- grplst = (:public , :define_public , :develop , :define_develop )
179- elseif ind == 3 # extend
189+ elseif cmd == : test
190+ grplst = (:public , :develop , :define_public , :define_develop )
191+ elseif cmd == : extend
180192 grplst = (:define_public , :define_develop )
181193 for mod in modules, grp in (:base , :public , :develop )
182194 push! (lst, _make_exprs (:import , mod, grp))
183195 end
184- else # export
185- grplst = ()
186- for mod in modules, grp in (:public , :define_public )
187- push! (lst, :(eval (Expr ( :export , $ mod. __api__.$ grp... ))))
188- end
196+ else
197+ error (" @api unrecognized command: $cmd " )
189198 end
190199 for mod in modules, grp in grplst
191200 push! (lst, _make_exprs (:using , mod, grp))
195204
196205# We need Expr(:toplevel, (Expr($cmd, $mod, $sym) for sym in $mod.__api__.$grp)...)
197206
207+ function _make_module_list (mod, lst)
208+ isempty (lst) && return nothing
209+ length (lst) == 1 ? :(using $ mod.$ (lst[1 ])) :
210+ Expr (:toplevel , [:(using $ mod.$ nam) for nam in lst]. .. )
211+ end
212+
213+ _make_module_exprs (mod) =
214+ :(eval ($ (Meta. parse (" APITools._make_module_list($(QuoteNode (mod)) , $mod .__api__.define_module)" ))))
215+
198216function _make_list (cmd, mod, lst)
199217 isempty (lst) && return nothing
200218 @static if VERSION < v " 0.7.0-DEV"
0 commit comments