Skip to content

Commit

Permalink
Support named arguments in macro methods (#8429)
Browse files Browse the repository at this point in the history
* Support named arguments in macro methods

* Make named_args nilable

* Some style updates

* Update src/compiler/crystal/macros/interpreter.cr

Co-Authored-By: Ary Borenszweig <[email protected]>

* Simplify named_args assignment
  • Loading branch information
Blacksmoke16 authored and asterite committed Nov 15, 2019
1 parent 1580298 commit 4559cd6
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 58 deletions.
10 changes: 10 additions & 0 deletions spec/compiler/macro/macro_methods_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,16 @@ module Crystal
assert_macro "", %({{"foo_bar".camelcase}}), [] of ASTNode, %("FooBar")
end

it "executes camelcase with lower" do
assert_macro "", %({{"foo_bar".camelcase(lower: true)}}), [] of ASTNode, %("fooBar")
end

it "executes camelcase with invalid lower arg type" do
expect_raises(Crystal::TypeException, "named argument 'lower' to StringLiteral#camelcase must be a bool, not NumberLiteral") do
assert_macro "", %({{"foo_bar".camelcase(lower: 99)}}), [] of ASTNode, ""
end
end

it "executes underscore" do
assert_macro "", %({{"FooBar".underscore}}), [] of ASTNode, %("foo_bar")
end
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/macros.cr
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ module Crystal::Macros
end

# Similar to `String#camelcase`.
def camelcase : StringLiteral
def camelcase(*, lower : BoolLiteral = false) : StringLiteral
end

# Similar to `String#capitalize`.
Expand Down
7 changes: 4 additions & 3 deletions src/compiler/crystal/macros/interpreter.cr
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,10 @@ module Crystal
end

args = node.args.map { |arg| accept arg }
named_args = node.named_args.try &.to_h { |arg| {arg.name, accept arg.value} }

begin
@last = receiver.interpret(node.name, args, node.block, self)
@last = receiver.interpret(node.name, args, named_args, node.block, self)
rescue ex : MacroRaiseException
raise ex
rescue ex : Crystal::Exception
Expand Down Expand Up @@ -511,13 +512,13 @@ module Crystal

def visit(node : Splat)
node.exp.accept self
@last = @last.interpret("splat", [] of ASTNode, nil, self)
@last = @last.interpret("splat", [] of ASTNode, nil, nil, self)
false
end

def visit(node : DoubleSplat)
node.exp.accept self
@last = @last.interpret("double_splat", [] of ASTNode, nil, self)
@last = @last.interpret("double_splat", [] of ASTNode, nil, nil, self)
false
end

Expand Down
Loading

0 comments on commit 4559cd6

Please sign in to comment.