Skip to content

Tweak macro name representation #572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions src/integration/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,6 @@ function node_to_expr(cursor, source, txtbuf::Vector{UInt8}, txtbuf_offset::UInt
val isa UInt128 ? Symbol("@uint128_str") :
Symbol("@big_str")
return Expr(:macrocall, GlobalRef(Core, macname), nothing, str)
elseif k == K"MacroName" && val === Symbol("@.")
return Symbol("@__dot__")
else
return val
end
Expand Down Expand Up @@ -296,7 +294,31 @@ function node_to_expr(cursor, source, txtbuf::Vector{UInt8}, txtbuf_offset::UInt
nodehead, source)
end

# Split out from the above for codesize reasons, to avoid specialization on multiple
function adjust_macro_name!(retexpr::Union{Expr, Symbol}, k::Kind)
if !(retexpr isa Symbol)
retexpr::Expr
# can happen for incomplete or errors
(length(retexpr.args) < 2 || retexpr.head != :(.)) && return retexpr
arg2 = retexpr.args[2]
isa(arg2, QuoteNode) || return retexpr
retexpr.args[2] = QuoteNode(adjust_macro_name!(arg2.value, k))
return retexpr
end
if k == K"macro_name"
if retexpr === Symbol(".")
return Symbol("@__dot__")
else
return Symbol("@$retexpr")
end
elseif k == K"macro_name_cmd"
return Symbol("@$(retexpr)_cmd")
else
@assert k == K"macro_name_str"
return Symbol("@$(retexpr)_str")
end
end

# Split out from `node_to_expr` for codesize reasons, to avoid specialization on multiple
# tree types.
@noinline function _node_to_expr(retexpr::Expr, loc::LineNumberNode,
srcrange::UnitRange{UInt32},
Expand All @@ -312,6 +334,8 @@ end
# However, errors can add additional errors tokens which we represent
# as e.g. `Expr(:var, ..., Expr(:error))`.
return retexpr.args[1]
elseif k in KSet"macro_name macro_name_cmd macro_name_str"
return adjust_macro_name!(retexpr.args[1], k)
elseif k == K"?"
retexpr.head = :if
elseif k == K"op=" && length(args) == 3
Expand All @@ -331,7 +355,7 @@ end
elseif k == K"macrocall"
if length(args) >= 2
a2 = args[2]
if @isexpr(a2, :macrocall) && kind(firstchildhead) == K"CmdMacroName"
if @isexpr(a2, :macrocall) && kind(firstchildhead) == K"macro_name_cmd"
# Fix up for custom cmd macros like foo`x`
args[2] = a2.args[3]
end
Expand Down
18 changes: 4 additions & 14 deletions src/julia/kinds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,6 @@ register_kinds!(JuliaSyntax, 0, [
"BEGIN_IDENTIFIERS"
"Identifier"
"Placeholder" # Used for empty catch variables, and all-underscore identifiers in lowering
# Macro names are modelled as special kinds of identifiers because the full
# macro name may not appear as characters in the source: The `@` may be
# detached from the macro name as in `@A.x` (ugh!!), or have a _str or _cmd
# suffix appended.
"BEGIN_MACRO_NAMES"
"MacroName"
"StringMacroName"
"CmdMacroName"
"END_MACRO_NAMES"
"END_IDENTIFIERS"

"BEGIN_KEYWORDS"
Expand Down Expand Up @@ -1048,6 +1039,10 @@ register_kinds!(JuliaSyntax, 0, [
"iteration"
"comprehension"
"typed_comprehension"
# Macro names
"macro_name"
"macro_name_cmd"
"macro_name_str"
# Container for a single statement/atom plus any trivia and errors
"wrapper"
"END_SYNTAX_KINDS"
Expand Down Expand Up @@ -1111,10 +1106,6 @@ const _nonunique_kind_names = Set([
K"String"
K"Char"
K"CmdString"

K"MacroName"
K"StringMacroName"
K"CmdMacroName"
])

"""
Expand Down Expand Up @@ -1201,7 +1192,6 @@ is_prec_unicode_ops(x) = K"BEGIN_UNICODE_OPS" <= kind(x) <= K"END_UNICODE_OPS"
is_prec_pipe_lt(x) = kind(x) == K"<|"
is_prec_pipe_gt(x) = kind(x) == K"|>"
is_syntax_kind(x) = K"BEGIN_SYNTAX_KINDS"<= kind(x) <= K"END_SYNTAX_KINDS"
is_macro_name(x) = K"BEGIN_MACRO_NAMES" <= kind(x) <= K"END_MACRO_NAMES"
is_syntactic_assignment(x) = K"BEGIN_SYNTACTIC_ASSIGNMENTS" <= kind(x) <= K"END_SYNTACTIC_ASSIGNMENTS"

function is_string_delim(x)
Expand Down
6 changes: 0 additions & 6 deletions src/julia/literal_parsing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -430,12 +430,6 @@ function parse_julia_literal(txtbuf::Vector{UInt8}, head::SyntaxHead, srcrange)
Symbol(normalize_identifier(val_str))
elseif k == K"error"
ErrorVal()
elseif k == K"MacroName"
Symbol("@$(normalize_identifier(val_str))")
elseif k == K"StringMacroName"
Symbol("@$(normalize_identifier(val_str))_str")
elseif k == K"CmdMacroName"
Symbol("@$(normalize_identifier(val_str))_cmd")
elseif is_syntax_kind(head)
nothing
elseif is_keyword(k)
Expand Down
Loading
Loading