Skip to content

Commit 134d4ad

Browse files
authored
Adapt to JuliaSyntax MacroName change (#71)
Adapt to JuliaSyntax changes in how macro names are represented in the tree. This is a bit messy but is important to keep in sync for now until we figure out how the green tree relates to (or differs from) the AST seen by macros and lowering.
1 parent 397d41e commit 134d4ad

File tree

10 files changed

+70
-31
lines changed

10 files changed

+70
-31
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ version = "1.0.0-DEV"
77
JuliaSyntax = "70703baa-626e-46a2-a12c-08ffd08c73b4"
88

99
[sources]
10-
JuliaSyntax = {rev = "e02f29f", url = "https://github.com/JuliaLang/JuliaSyntax.jl"}
10+
JuliaSyntax = {rev = "99e975a7", url = "https://github.com/JuliaLang/JuliaSyntax.jl"}
1111

1212
[compat]
1313
julia = "1"

src/ast.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ end
142142
function makeleaf(ctx, srcref, k::Kind, value; kws...)
143143
graph = syntax_graph(ctx)
144144
if k == K"Identifier" || k == K"core" || k == K"top" || k == K"Symbol" ||
145-
k == K"globalref" || k == K"Placeholder" || k == K"MacroName" ||
146-
k == K"StringMacroName" || k == K"CmdMacroName"
145+
k == K"globalref" || k == K"Placeholder" ||
146+
k == K"StrMacroName" || k == K"CmdMacroName"
147147
makeleaf(graph, srcref, k; name_val=value, kws...)
148148
elseif k == K"BindingId"
149149
makeleaf(graph, srcref, k; var_id=value, kws...)

src/compat.jl

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -267,12 +267,12 @@ function _insert_convert_expr(@nospecialize(e), graph::SyntaxGraph, src::SourceA
267267
end
268268
deleteat!(child_exprs, 2)
269269
if a1 isa Symbol
270-
child_exprs[1] = a1_esc(Expr(:MacroName, a1))
270+
child_exprs[1] = a1_esc(Expr(:macro_name, a1))
271271
elseif a1 isa Expr && a1.head === :(.)
272272
a12,a12_esc = unwrap_esc(a1.args[2])
273273
if a12 isa QuoteNode
274274
child_exprs[1] = a1_esc(Expr(:(.), a1.args[1],
275-
Expr(:MacroName, a12_esc(a12.value))))
275+
Expr(:macro_name, a12_esc(a12.value))))
276276
end
277277
elseif a1 isa GlobalRef && a1.mod === Core
278278
# Syntax-introduced macrocalls are listed here for reference. We
@@ -415,7 +415,7 @@ function _insert_convert_expr(@nospecialize(e), graph::SyntaxGraph, src::SourceA
415415
end
416416
deleteat!(callargs, 2)
417417
c1,c1_esc = unwrap_esc(callargs[1])
418-
callargs[1] = c1_esc(Expr(:MacroName, c1))
418+
callargs[1] = c1_esc(Expr(:macro_name, c1))
419419
else
420420
st_k = K"call"
421421
end
@@ -523,13 +523,20 @@ function _insert_convert_expr(@nospecialize(e), graph::SyntaxGraph, src::SourceA
523523
end
524524

525525
#---------------------------------------------------------------------------
526-
# Temporary heads introduced by us converting the parent expr
527-
if e.head === :MacroName
526+
# Possibly-temporary heads introduced by us converting the parent expr
527+
if e.head === :macro_name
528528
@assert nargs === 1
529-
mac_name = string(e.args[1])
530-
mac_name = mac_name == "@__dot__" ? "@." : mac_name
531-
st_id = _insert_tree_node(graph, K"MacroName", src, st_flags; name_val=mac_name)
532-
return st_id, src
529+
# Trim `@` for a correct SyntaxTree, although we need to add it back
530+
# later for finding the macro
531+
if e.args[1] === :(.)
532+
mac_name = string(e.args[1][2])
533+
mac_name = mac_name == "@__dot__" ? "." : mac_name[2:end]
534+
child_exprs[1] = Expr(:(.), e.args[1][1], Symbol(mac_name))
535+
else
536+
mac_name = string(e.args[1])
537+
mac_name = mac_name == "@__dot__" ? "." : mac_name[2:end]
538+
child_exprs[1] = Symbol(mac_name)
539+
end
533540
elseif e.head === :catch_var_placeholder
534541
st_k = K"Placeholder"
535542
st_attrs[:name_val] = ""

src/macro_expansion.jl

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,12 @@ function Base.showerror(io::IO, exc::MacroExpansionError)
108108
print(io, "MacroExpansionError")
109109
ctx = exc.context
110110
if !isnothing(ctx)
111-
print(io, " while expanding ", ctx.macrocall[1],
111+
# Use `Expr` formatting to pretty print the macro name for now -
112+
# there's quite a lot of special cases. We could alternatively consider
113+
# calling sourcetext() though that won't work well if it's a
114+
# synthetically-generated macro name path.
115+
macname_str = string(Expr(:macrocall, Expr(ctx.macrocall[1]), nothing))
116+
print(io, " while expanding ", macname_str,
112117
" in module ", ctx.scope_layer.mod)
113118
end
114119
print(io, ":\n")
@@ -137,11 +142,31 @@ function Base.showerror(io::IO, exc::MacroExpansionError)
137142
end
138143
end
139144

145+
function fixup_macro_name(ctx::MacroExpansionContext, ex::SyntaxTree)
146+
k = kind(ex)
147+
if k == K"StrMacroName" || k == K"CmdMacroName"
148+
layerid = get(ex, :scope_layer, current_layer_id(ctx))
149+
newname = JuliaSyntax.lower_identifier_name(ex.name_val, k)
150+
makeleaf(ctx, ex, ex, kind=K"Identifier", scope_layer=layerid, name_val=newname)
151+
elseif k == K"macro_name"
152+
@chk numchildren(ex) === 1
153+
if kind(ex[1]) === K"."
154+
@ast ctx ex [K"." ex[1][1] [K"macro_name" ex[1][2]]]
155+
else
156+
layerid = get(ex, :scope_layer, current_layer_id(ctx))
157+
newname = JuliaSyntax.lower_identifier_name(ex[1].name_val, K"macro_name")
158+
makeleaf(ctx, ex[1], ex[1], kind=kind(ex[1]), name_val=newname)
159+
end
160+
else
161+
mapchildren(e->fixup_macro_name(ctx,e), ctx, ex)
162+
end
163+
end
164+
140165
function eval_macro_name(ctx::MacroExpansionContext, mctx::MacroContext, ex::SyntaxTree)
141166
# `ex1` might contain a nontrivial mix of scope layers so we can't just
142167
# `eval()` it, as it's already been partially lowered by this point.
143168
# Instead, we repeat the latter parts of `lower()` here.
144-
ex1 = expand_forms_1(ctx, ex)
169+
ex1 = expand_forms_1(ctx, fixup_macro_name(ctx, ex))
145170
ctx2, ex2 = expand_forms_2(ctx, ex1)
146171
ctx3, ex3 = resolve_scopes(ctx2, ex2)
147172
ctx4, ex4 = convert_closures(ctx3, ex3)
@@ -368,9 +393,10 @@ function expand_forms_1(ctx::MacroExpansionContext, ex::SyntaxTree)
368393
layerid = get(ex, :scope_layer, current_layer_id(ctx))
369394
makeleaf(ctx, ex, ex, kind=K"Identifier", scope_layer=layerid)
370395
end
371-
elseif k == K"Identifier" || k == K"MacroName" || k == K"StringMacroName" || k == K"CmdMacroName"
372-
layerid = get(ex, :scope_layer, current_layer_id(ctx))
373-
makeleaf(ctx, ex, ex, kind=K"Identifier", scope_layer=layerid)
396+
elseif k == K"StrMacroName" || k == K"CmdMacroName" || k == K"macro_name"
397+
# These can appear outside of a macrocall, e.g. in `import`
398+
e2 = fixup_macro_name(ctx, ex)
399+
expand_forms_1(ctx, e2)
374400
elseif k == K"var" || k == K"char" || k == K"parens"
375401
# Strip "container" nodes
376402
@chk numchildren(ex) == 1
@@ -431,7 +457,7 @@ function expand_forms_1(ctx::MacroExpansionContext, ex::SyntaxTree)
431457
@ast ctx ex [K"." expand_forms_1(ctx, ex[1]) e2]
432458
elseif k == K"cmdstring"
433459
@chk numchildren(ex) == 1
434-
e2 = @ast ctx ex [K"macrocall" "@cmd"::K"core" ex[1]]
460+
e2 = @ast ctx ex [K"macrocall" [K"macro_name" "cmd"::K"core"] ex[1]]
435461
expand_macro(ctx, e2)
436462
elseif (k == K"call" || k == K"dotcall")
437463
# Do some initial desugaring of call and dotcall here to simplify

src/syntax_graph.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ attrsummary(name, value::Number) = "$name=$value"
457457

458458
function _value_string(ex)
459459
k = kind(ex)
460-
str = k in KSet"Identifier MacroName StringMacroName CmdMacroName" || is_operator(k) ? ex.name_val :
460+
str = k in KSet"Identifier StrMacroName CmdMacroName" || is_operator(k) ? ex.name_val :
461461
k == K"Placeholder" ? ex.name_val :
462462
k == K"SSAValue" ? "%" :
463463
k == K"BindingId" ? "#" :
@@ -611,11 +611,17 @@ function _find_SyntaxTree_macro(ex, line)
611611
# We're in the line range. Either
612612
if firstline == line && kind(c) == K"macrocall" && begin
613613
name = c[1]
614+
if kind(name) == K"macro_name"
615+
name = name[1]
616+
end
614617
if kind(name) == K"."
615618
name = name[2]
619+
if kind(name) == K"macro_name"
620+
name = name[1]
621+
end
616622
end
617-
@assert kind(name) == K"MacroName"
618-
name.name_val == "@SyntaxTree"
623+
@assert kind(name) == K"Identifier"
624+
name.name_val == "SyntaxTree"
619625
end
620626
# We find the node we're looking for. NB: Currently assuming a max
621627
# of one @SyntaxTree invocation per line. Though we could relax

test/compat.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ const JL = JuliaLowering
494494
# `@mac x` with macro name escaped
495495
@test JuliaLowering.expr_to_syntaxtree(Expr(:macrocall, esc(Symbol("@mac")), nothing, :x))
496496
@ast_ [K"macrocall"
497-
[K"escape" "@mac"::K"MacroName"]
497+
[K"escape" [K"macro_name" "mac"::K"Identifier"]]
498498
"x"::K"Identifier"
499499
]
500500

@@ -505,7 +505,7 @@ const JL = JuliaLowering
505505
[K"escape"
506506
[K"."
507507
"A"::K"Identifier"
508-
"@mac"::K"MacroName"
508+
[K"macro_name" "mac"::K"Identifier"]
509509
]
510510
]
511511
"x"::K"Identifier"
@@ -577,7 +577,7 @@ const JL = JuliaLowering
577577
Expr(:macrocall, Expr(:var"hygienic-scope", Symbol("@mac"), :other, :args), nothing, :x))
578578
@ast_ [K"macrocall"
579579
[K"hygienic_scope"
580-
"@mac"::K"MacroName"
580+
[K"macro_name" "mac"::K"Identifier"]
581581
"other"::K"Identifier" # (<- normally a Module)
582582
"args"::K"Identifier" # (<- normally a LineNumberNode)
583583
]
@@ -587,7 +587,7 @@ const JL = JuliaLowering
587587
# One example of double escaping
588588
@test JuliaLowering.expr_to_syntaxtree(Expr(:macrocall, esc(esc(Symbol("@mac"))), nothing, :x))
589589
@ast_ [K"macrocall"
590-
[K"escape" [K"escape" "@mac"::K"MacroName"]]
590+
[K"escape" [K"escape" [K"macro_name" "mac"::K"Identifier"]]]
591591
"x"::K"Identifier"
592592
]
593593

@@ -600,7 +600,7 @@ const JL = JuliaLowering
600600
@ast_ [K"macrocall"
601601
[K"hygienic_scope"
602602
[K"escape"
603-
"@mac"::K"MacroName"
603+
[K"macro_name" "mac"::K"Identifier"]
604604
]
605605
"other"::K"Identifier" # (<- normally a Module)
606606
"args"::K"Identifier" # (<- normally a LineNumberNode)

0 commit comments

Comments
 (0)