Skip to content
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

Add macro methods for Primitive #14263

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions spec/compiler/macro/macro_methods_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2505,6 +2505,13 @@ module Crystal
end
end

describe Primitive do
it "executes name" do
assert_macro %({{x.name}}), %(:abc), {x: Primitive.new("abc")}
assert_macro %({{x.name}}), %(:"x.y.z"), {x: Primitive.new("x.y.z")}
end
end

describe "macro methods" do
it "executes name" do
assert_macro %({{x.name}}), "some_macro", {x: Macro.new("some_macro")}
Expand Down
21 changes: 21 additions & 0 deletions src/compiler/crystal/macros.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,27 @@ module Crystal::Macros
end
end

# A fictitious node representing the body of a `Def` marked with
# `@[Primitive]`.
class Primitive < ASTNode
# Returns the name of the primitive.
#
# This is identical to the argument to the associated `@[Primitive]`
# annotation.
#
# ```
# module Foo
# @[Primitive(:abc)]
# def foo
# end
# end
#
# {{ Foo.methods.first.body.name }} # => :abc
# ```
def name : SymbolLiteral
end
end

# A macro definition.
class Macro < ASTNode
# Returns the name of this macro.
Expand Down
11 changes: 11 additions & 0 deletions src/compiler/crystal/macros/methods.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,17 @@ module Crystal
end
end

class Primitive
def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
case method
when "name"
interpret_check_args { SymbolLiteral.new(@name) }
else
super
end
end
end

class Macro
def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
case method
Expand Down