Skip to content

Commit

Permalink
add has_key? to NamedTupleLiteral
Browse files Browse the repository at this point in the history
  • Loading branch information
kamil-gwozdz committed Aug 11, 2024
1 parent 581f86c commit 0443c58
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
8 changes: 8 additions & 0 deletions spec/compiler/macro/macro_methods_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,14 @@ module Crystal
assert_macro %({% a = {a: 1}; a["a"] = 2 %}{{a["a"]}}), "2"
end

it "executes has_key?" do
assert_macro %({{{a: 1}.has_key?("a")}}), "true"
assert_macro %({{{a: 1}.has_key?(:a)}}), "true"
assert_macro %({{{a: nil}.has_key?("a")}}), "true"
assert_macro %({{{a: nil}.has_key?("b")}}), "false"
assert_macro_error %({{{a: 1}.has_key?(true)}}), "argument to has_key? must be a symbol or string, not BoolLiteral"
end

it "creates a named tuple literal with a var" do
assert_macro %({% a = {a: x} %}{{a[:a]}}), "1", {x: 1.int32}
end
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/crystal/macros.cr
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,9 @@ module Crystal::Macros
# Adds or replaces a key.
def []=(key : SymbolLiteral | StringLiteral | MacroId, value : ASTNode) : ASTNode
end

def has_key?(key : SymbolLiteral | StringLiteral | MacroId) ASTNode
end
end

# A range literal.
Expand Down
16 changes: 16 additions & 0 deletions src/compiler/crystal/macros/methods.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,22 @@ module Crystal

value
end
when "has_key?"
interpret_check_args do |key|
case key
when SymbolLiteral
key = key.value
when MacroId
key = key.value
when StringLiteral
key = key.value
else
raise "argument to has_key? must be a symbol or string, not #{key.class_desc}:\n\n#{key}"
end

entry = entries.find &.key.==(key)
BoolLiteral.new(entry != nil)
end
else
super
end
Expand Down

0 comments on commit 0443c58

Please sign in to comment.