Skip to content

Commit da7f0de

Browse files
committed
Move @def to @api def
1 parent 0757f6b commit da7f0de

File tree

2 files changed

+66
-53
lines changed

2 files changed

+66
-53
lines changed

src/APITools.jl

+53-43
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@ const BIG_ENDIAN = (ENDIAN_BOM == 0x01020304)
1818
Base.parse(::Type{Expr}, args...; kwargs...) =
1919
Meta.parse(args...; kwargs...)
2020

21-
export @api, @def, V6_COMPAT, BIG_ENDIAN
21+
export @api, V6_COMPAT, BIG_ENDIAN
2222

23-
macro def(name, definition)
23+
_api_def(name, definition) =
2424
quote
2525
macro $(esc(name))()
2626
esc($(Expr(:quote, definition)))
2727
end
2828
end
29-
end
3029

3130
const SymSet = Set{Symbol}
3231

@@ -71,6 +70,9 @@ end
7170
"""Get current module"""
7271
cur_mod() = ccall(:jl_get_current_module, Ref{Module}, ())
7372

73+
m_eval(mod, expr) = Core.eval(mod, expr)
74+
m_eval(expr) = m_eval(cur_mod(), expr)
75+
7476
"""
7577
@api <cmd> [<symbols>...]
7678
@@ -89,6 +91,9 @@ cur_mod() = ccall(:jl_get_current_module, Ref{Module}, ())
8991
* @api public <names...> # Add functions that are part of the public API
9092
* @api develop <names...> # Add functions that are part of the development API
9193
* @api modules <names...> # Add submodule names that are part of the API
94+
95+
* @api def <name> <expr> # Same as the @def macro, creates a macro with the given name
96+
9297
"""
9398
macro api(cmd::Symbol)
9499
mod = @static V6_COMPAT ? current_module() : __module__
@@ -97,20 +102,14 @@ macro api(cmd::Symbol)
97102
error("@api unrecognized command: $cmd")
98103
end
99104

100-
function _api_display(api::AbstractAPI)
101-
show(api)
102-
println()
103-
end
105+
_api_display(mod, nam) =
106+
isdefined(mod, nam) && (api = m_eval(mod, nam)) !== nothing && (show(api) ; println())
104107

105-
function _api_list(mod::Module)
106-
isdefined(mod, :__api__) && _api_display(eval(mod, :__api__))
107-
isdefined(mod, :__tmp_api__) && _api_display(eval(mod, :__tmp_api__))
108-
nothing
109-
end
108+
_api_list(mod::Module) = (_api_display(mod, :__api__) ; _api_display(mod, :__tmp_api__))
110109

111110
function _api_freeze(mod::Module)
112111
ex = :( global const __api__ = APITools.API(__tmp_api__) ; __tmp_api__ = nothing )
113-
isdefined(mod, :__tmp_api__) && eval(mod, :( __tmp_api__ !== nothing ) ) && eval(mod, ex)
112+
isdefined(mod, :__tmp_api__) && m_eval(mod, :( __tmp_api__ !== nothing ) ) && m_eval(mod, ex)
114113
nothing
115114
end
116115

@@ -131,23 +130,23 @@ function _add_def!(curmod, grp, exp)
131130
error("@api $grp: syntax error $exp")
132131
end
133132
if isdefined(Base, sym)
134-
eval(curmod, :(import Base.$sym ))
135-
eval(curmod, :(push!(__tmp_api__.base, $(QuoteNode(sym)))))
133+
m_eval(curmod, :(import Base.$sym ))
134+
m_eval(curmod, :(push!(__tmp_api__.base, $(QuoteNode(sym)))))
136135
else
137-
eval(curmod, :(function $sym end))
138-
eval(curmod, :(push!(__tmp_api__.public!, $(QuoteNode(sym)))))
136+
m_eval(curmod, :(function $sym end))
137+
m_eval(curmod, :(push!(__tmp_api__.public!, $(QuoteNode(sym)))))
139138
end
140139
end
141140

142141
"""Add symbols"""
143142
function _add_symbols(curmod, grp, exprs)
144143
if debug[]
145144
print("_add_symbols($curmod, $grp, $exprs)")
146-
isdefined(curmod, :__tmp_api__) && print(" => ", eval(curmod, :__tmp_api__))
145+
isdefined(curmod, :__tmp_api__) && print(" => ", m_eval(curmod, :__tmp_api__))
147146
println()
148147
end
149148
ex = :( export @api, APITools ; global __tmp_api__ = APITools.TMP_API($curmod) )
150-
isdefined(curmod, :__tmp_api__) || eval(curmod, ex)
149+
isdefined(curmod, :__tmp_api__) || m_eval(curmod, ex)
151150
if grp == :base!
152151
for ex in exprs
153152
if isa(ex, Expr) && ex.head == :tuple
@@ -173,14 +172,14 @@ function _add_symbols(curmod, grp, exprs)
173172
end
174173
if grp == :base
175174
for sym in symbols
176-
eval(curmod, :( import Base.$sym ))
175+
m_eval(curmod, :( import Base.$sym ))
177176
end
178177
end
179178
for sym in symbols
180-
eval(curmod, :( push!(__tmp_api__.$grp, $(QuoteNode(sym)) )))
179+
m_eval(curmod, :( push!(__tmp_api__.$grp, $(QuoteNode(sym)) )))
181180
end
182181
end
183-
debug[] && println("after add symbols: ", eval(curmod, :__tmp_api__))
182+
debug[] && println("after add symbols: ", m_eval(curmod, :__tmp_api__))
184183
nothing
185184
end
186185

@@ -189,9 +188,9 @@ function _api_extend(curmod, modules)
189188
use = :using
190189

191190
for nam in modules
192-
mod = eval(curmod, nam)
191+
mod = m_eval(curmod, nam)
193192
if isdefined(mod, :__api__)
194-
api = eval(mod, :__api__)
193+
api = m_eval(mod, :__api__)
195194
_do_list(curmod, imp, api, :Base, :base)
196195
_do_list(curmod, imp, api, nam, :public!)
197196
_do_list(curmod, imp, api, nam, :develop!)
@@ -207,28 +206,39 @@ end
207206

208207
function _api_use(curmod, modules)
209208
for nam in modules
210-
mod = eval(curmod, nam)
209+
mod = m_eval(curmod, nam)
211210
if isdefined(mod, :__api__)
212-
api = eval(mod, :__api__)
211+
api = m_eval(mod, :__api__)
213212
_do_list(curmod, :using, api, nam, :public)
214213
_do_list(curmod, :using, api, nam, :public!)
215214
end
216215
end
217216
nothing
218217
end
219218

220-
_api_export(curmod, modules) =
221-
esc(Expr(:toplevel,
222-
[:(eval(Expr( :export, $mod.__api__.$grp... )))
223-
for mod in modules, grp in (:modules, :public, :public!)]...,
224-
nothing))
219+
function _api_export(curmod, modules)
220+
for nam in modules
221+
mod = m_eval(curmod, nam)
222+
if isdefined(mod, :__api__)
223+
api = m_eval(mod, :__api__)
224+
m_eval(curmod, Expr( :export, getfield(api, :modules)...))
225+
m_eval(curmod, Expr( :export, getfield(api, :public)...))
226+
m_eval(curmod, Expr( :export, getfield(api, :public!)...))
227+
end
228+
end
229+
nothing
230+
end
225231

226-
_api_list(curmod, modules) =
227-
Expr(:toplevel,
228-
[:(eval(APITools._api_display($mod))) for mod in modules]...,
229-
nothing)
232+
function _api_list(curmod, modules)
233+
for nam in modules
234+
_api_list(m_eval(curmod, nam))
235+
end
236+
nothing
237+
end
230238

231239
function _api(curmod::Module, cmd::Symbol, exprs)
240+
cmd == :def && return _api_def(exprs...)
241+
232242
ind = _ff(_cmdadd, cmd)
233243
ind == 0 || return _add_symbols(curmod, cmd, exprs)
234244

@@ -239,10 +249,10 @@ function _api(curmod::Module, cmd::Symbol, exprs)
239249
for ex in exprs
240250
if isa(ex, Expr) && ex.head == :tuple
241251
push!(modules, ex.args...)
242-
for sym in ex.args ; eval(curmod, :(import $sym)) ; end
252+
for sym in ex.args ; m_eval(curmod, :(import $sym)) ; end
243253
elseif isa(ex, Symbol)
244254
push!(modules, ex)
245-
eval(curmod, :(import $ex))
255+
m_eval(curmod, :(import $ex))
246256
else
247257
error("@api $cmd: syntax error $ex")
248258
end
@@ -253,14 +263,14 @@ function _api(curmod::Module, cmd::Symbol, exprs)
253263
cmd == :list && return _api_list(curmod, modules)
254264

255265
for nam in modules
256-
mod = eval(curmod, nam)
257-
for sym in getfield(eval(mod, :__api__), :modules)
258-
eval(curmod, :(using $nam.$sym))
266+
mod = m_eval(curmod, nam)
267+
for sym in getfield(m_eval(mod, :__api__), :modules)
268+
m_eval(curmod, :(using $nam.$sym))
259269
end
260270
end
261271

262272
# Be nice and set up standard Test
263-
cmd == :test && eval(curmod, V6_COMPAT ? :(using Base.Test) : :(using Test))
273+
cmd == :test && m_eval(curmod, V6_COMPAT ? :(using Base.Test) : :(using Test))
264274

265275
cmd == :use ? _api_use(curmod, modules) : _api_extend(curmod, modules)
266276
end
@@ -274,13 +284,13 @@ function _do_list(curmod, cmd, api, mod, grp)
274284
for nam in lst
275285
exp = Expr(cmd, mod, nam)
276286
debug[] && println("V6: $cmd, $mod, $mod, $exp")
277-
eval(curmod, exp)
287+
m_eval(curmod, exp)
278288
end
279289
else
280290
exp = Expr(cmd, Expr(:(:), _dot_name(mod), _dot_name.(lst)...))
281291
debug[] && println("V7: $cmd, $mod, $mod, $exp")
282292
try
283-
eval(curmod, exp)
293+
m_eval(curmod, exp)
284294
catch ex
285295
println("APITools: Error evaluating $exp")
286296
dump(exp)

test/runtests.jl

+13-10
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,31 @@ using APITools
55

66
@static V6_COMPAT ? (using Base.Test) : (using Test)
77

8-
@def testcase begin
8+
# Pick up APITest from the test directory
9+
push!(LOAD_PATH, @__DIR__)
10+
11+
@api extend APITest
12+
13+
@api list APITest
14+
15+
@api def testcase begin
916
myname = "Scott Paul Jones"
1017
end
1118

12-
@testset "@def macro" begin
19+
@testset "@api def <name> <expr>" begin
1320
@testcase
1421
@test myname == "Scott Paul Jones"
1522
end
1623

17-
# Pick up APITest from the test directory
18-
push!(LOAD_PATH, @__DIR__)
19-
20-
@api extend APITest
21-
22-
@api list
23-
2424
myfunc(::AbstractFloat) = 3
2525

26-
@testset "@api macro" begin
26+
@testset "Function extension" begin
2727
@test myfunc(1) == 1
2828
@test myfunc("foo") == 2
2929
@test myfunc(2.0) == 3
30+
end
31+
32+
@testset "API lists" begin
3033
@test APITest.__api__.mod == APITest
3134
@test Set(APITest.__api__.base) == Set([:nextind, :getindex, :setindex!])
3235
@test Set(APITest.__api__.public) == Set([:Foo])

0 commit comments

Comments
 (0)