Skip to content

Commit 61e55bc

Browse files
committed
Add parent_layer id to ScopeLayer + minor fixes
1 parent 8d7e4ed commit 61e55bc

File tree

6 files changed

+33
-20
lines changed

6 files changed

+33
-20
lines changed

src/ast.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,8 @@ function to_symbol(ctx, ex)
662662
@ast ctx ex ex=>K"Symbol"
663663
end
664664

665-
function new_scope_layer(ctx, mod_ref::Module=ctx.mod; is_macro_expansion=true)
666-
new_layer = ScopeLayer(length(ctx.scope_layers)+1, ctx.mod, is_macro_expansion)
665+
function new_scope_layer(ctx, mod_ref::Module=ctx.mod)
666+
new_layer = ScopeLayer(length(ctx.scope_layers)+1, ctx.mod, 0, false)
667667
push!(ctx.scope_layers, new_layer)
668668
new_layer.id
669669
end

src/desugaring.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2555,7 +2555,7 @@ function keyword_function_defs(ctx, srcref, callex_srcref, name_str, typevar_nam
25552555
end
25562556
# TODO: Is the layer correct here? Which module should be the parent module
25572557
# of this body function?
2558-
layer = new_scope_layer(ctx; is_macro_expansion=false)
2558+
layer = new_scope_layer(ctx)
25592559
body_func_name = adopt_scope(@ast(ctx, callex_srcref, mangled_name::K"Identifier"), layer)
25602560

25612561
kwcall_arg_names = SyntaxList(ctx)

src/kinds.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,11 @@ function _register_kinds()
4848
# Internal initializer for struct types, for inner constructors/functions
4949
"new"
5050
"splatnew"
51-
# For expr-macro compatibility; gone after expansion
51+
# Used for converting `esc()`'d expressions arising from old macro
52+
# invocations during macro expansion (gone after macro expansion)
5253
"escape"
54+
# Used for converting the old-style macro hygienic-scope form (gone
55+
# after macro expansion)
5356
"hygienic_scope"
5457
# An expression which will eventually be evaluated "statically" in
5558
# the context of a CodeInfo and thus allows access only to globals

src/macro_expansion.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ generates a new layer.
1111
struct ScopeLayer
1212
id::LayerId
1313
mod::Module
14+
parent_layer::LayerId # Index of parent layer in a macro expansion. Equal to 0 for no parent
1415
is_macro_expansion::Bool # FIXME
1516
end
1617

@@ -21,6 +22,11 @@ struct MacroExpansionContext{GraphType} <: AbstractLoweringContext
2122
scope_layer_stack::Vector{LayerId}
2223
end
2324

25+
function MacroExpansionContext(graph::SyntaxGraph, mod::Module)
26+
layers = ScopeLayer[ScopeLayer(1, mod, 0, false)]
27+
MacroExpansionContext(graph, Bindings(), layers, LayerId[length(layers)])
28+
end
29+
2430
current_layer(ctx::MacroExpansionContext) = ctx.scope_layers[last(ctx.scope_layer_stack)]
2531
current_layer_id(ctx::MacroExpansionContext) = last(ctx.scope_layer_stack)
2632

@@ -254,7 +260,8 @@ function expand_macro(ctx, ex)
254260
# method was defined (may be different from `parentmodule(macfunc)`)
255261
mod_for_ast = lookup_method_instance(macfunc, macro_args,
256262
macro_world).def.module
257-
new_layer = ScopeLayer(length(ctx.scope_layers)+1, mod_for_ast, true)
263+
new_layer = ScopeLayer(length(ctx.scope_layers)+1, mod_for_ast,
264+
current_layer_id(ctx), true)
258265
push!(ctx.scope_layers, new_layer)
259266
push!(ctx.scope_layer_stack, new_layer.id)
260267
expanded = expand_forms_1(ctx, expanded)
@@ -324,8 +331,9 @@ function expand_forms_1(ctx::MacroExpansionContext, ex::SyntaxTree)
324331
push!(ctx.scope_layer_stack, top_layer)
325332
escaped_ex
326333
elseif k == K"hygienic_scope"
327-
@chk numchildren(ex) >= 2 && ex[2].value isa Module "`hygienic_scope` requires an AST and a module"
328-
new_layer = ScopeLayer(length(ctx.scope_layers)+1, ex[2].value, true)
334+
@chk numchildren(ex) >= 2 && ex[2].value isa Module (ex,"`hygienic_scope` requires an AST and a module")
335+
new_layer = ScopeLayer(length(ctx.scope_layers)+1, ex[2].value,
336+
current_layer_id(ctx), true)
329337
push!(ctx.scope_layers, new_layer)
330338
push!(ctx.scope_layer_stack, new_layer.id)
331339
hyg_ex = expand_forms_1(ctx, ex[1])
@@ -433,8 +441,7 @@ function expand_forms_1(mod::Module, ex::SyntaxTree)
433441
scope_layer=LayerId,
434442
__macro_ctx__=Nothing,
435443
meta=CompileHints)
436-
layers = ScopeLayer[ScopeLayer(1, mod, false)]
437-
ctx = MacroExpansionContext(graph, Bindings(), layers, LayerId[1])
444+
ctx = MacroExpansionContext(graph, mod)
438445
ex2 = expand_forms_1(ctx, reparent(ctx, ex))
439446
graph2 = delete_attributes(graph, :__macro_ctx__)
440447
# TODO: Returning the context with pass-specific mutable data is a bad way

src/runtime.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,11 @@ function (g::GeneratedFunctionStub)(world::UInt, source::Method, @nospecialize a
306306
)
307307

308308
# Macro expansion
309-
layers = ScopeLayer[ScopeLayer(1, mod, false)]
310-
ctx1 = MacroExpansionContext(graph, Bindings(), layers, LayerId[1])
309+
ctx1 = MacroExpansionContext(graph, mod)
311310

312311
# Run code generator - this acts like a macro expander and like a macro
313312
# expander it gets a MacroContext.
314-
mctx = MacroContext(syntax_graph(ctx1), g.srcref, layers[1])
313+
mctx = MacroContext(syntax_graph(ctx1), g.srcref, ctx1.scope_layers[end])
315314
ex0 = g.gen(mctx, args...)
316315
if ex0 isa SyntaxTree
317316
if !is_compatible_graph(ctx1, ex0)

test/macros.jl

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ module M
5454
end
5555
5656
macro inner()
57-
:(2)
57+
:(y)
5858
end
5959
6060
macro outer()
61-
:((1, @inner))
61+
:((x, @inner))
6262
end
6363
6464
macro recursive(N)
@@ -82,6 +82,7 @@ end
8282
""") == ("`x` from @foo", "global in module M", "`x` from outer scope")
8383
@test !isdefined(test_mod.M, :x)
8484

85+
8586
@test JuliaLowering.include_string(test_mod, """
8687
#line1
8788
(M.@__MODULE__(), M.@__FILE__(), M.@__LINE__())
@@ -108,15 +109,17 @@ JuliaLowering.include_string(test_mod, "M.@set_other_global global_in_test_mod 1
108109
M.@recursive 3
109110
""") == (3, (2, (1, 0)))
110111

111-
@test let
112-
ex = JuliaLowering.parsestmt(JuliaLowering.SyntaxTree, "M.@outer()", filename="foo.jl")
113-
expanded = JuliaLowering.macroexpand(test_mod, ex)
114-
JuliaLowering.sourcetext.(JuliaLowering.flattened_provenance(expanded[2]))
115-
end == [
112+
ex = JuliaLowering.parsestmt(JuliaLowering.SyntaxTree, "M.@outer()", filename="foo.jl")
113+
ctx, expanded = JuliaLowering.expand_forms_1(test_mod, ex)
114+
@test JuliaLowering.sourcetext.(JuliaLowering.flattened_provenance(expanded[2])) == [
116115
"M.@outer()"
117116
"@inner"
118-
"2"
117+
"y"
119118
]
119+
# Layer parenting
120+
@test expanded[1].scope_layer == 2
121+
@test expanded[2].scope_layer == 3
122+
@test getfield.(ctx.scope_layers, :parent_layer) == [0,1,2]
120123

121124
JuliaLowering.include_string(test_mod, """
122125
f_throw(x) = throw(x)
@@ -269,4 +272,5 @@ end
269272
MethodError: no method matching var"@sig_mismatch"(::LineNumberNode, ::Module, ::Int64, ::Int64, ::Int64, ::Int64)
270273
""")
271274
end
275+
272276
end # module macros

0 commit comments

Comments
 (0)