Forum | Documentation | Website | Blog

Skip to content
Snippets Groups Projects
Commit 1c97cead authored by Ary Borenszweig's avatar Ary Borenszweig
Browse files

Say "wrong number of macro arguments" in some cases

parent 246c5189
Branches
Tags
No related merge requests found
...@@ -123,4 +123,14 @@ describe "Type inference: macro" do ...@@ -123,4 +123,14 @@ describe "Type inference: macro" do
bar bar
)) { int32 } )) { int32 }
end end
it "errors if find macros but wrong arguments" do
assert_error %(
macro foo
1
end
foo(1)
), "wrong number of arguments for macro 'foo' (1 for 0)"
end
end end
...@@ -708,14 +708,7 @@ module Crystal ...@@ -708,14 +708,7 @@ module Crystal
def expand_macro(node) def expand_macro(node)
return false if node.obj || node.name == "super" return false if node.obj || node.name == "super"
node_scope = node.scope the_macro = node.lookup_macro
node_scope = node_scope.metaclass unless node_scope.metaclass?
the_macro = node_scope.lookup_macro(node.name, node.args.length)
if !the_macro && node_scope.metaclass? && node.scope.instance_type.module?
the_macro = @mod.object.metaclass.lookup_macro(node.name, node.args.length)
end
the_macro ||= @mod.lookup_macro(node.name, node.args.length)
return false unless the_macro return false unless the_macro
generated_nodes = expand_macro(the_macro, node) do generated_nodes = expand_macro(the_macro, node) do
......
...@@ -311,6 +311,22 @@ module Crystal ...@@ -311,6 +311,22 @@ module Crystal
recalculate recalculate
end end
def lookup_macro
in_macro_target &.lookup_macro(name, args.length)
end
def in_macro_target
node_scope = scope
node_scope = node_scope.metaclass unless node_scope.metaclass?
macros = yield node_scope
if !macros && node_scope.metaclass? && node_scope.instance_type.module?
macros = yield mod.object.metaclass
end
macros ||= yield mod
macros
end
def match_block_arg(match) def match_block_arg(match)
yield_vars = nil yield_vars = nil
...@@ -527,6 +543,8 @@ module Crystal ...@@ -527,6 +543,8 @@ module Crystal
defs = owner.lookup_defs(def_name) defs = owner.lookup_defs(def_name)
obj = @obj obj = @obj
if defs.empty? if defs.empty?
check_macro_wrong_number_of_arguments(def_name)
owner_trace = find_owner_trace(obj, owner) if obj owner_trace = find_owner_trace(obj, owner) if obj
similar_name = owner.lookup_similar_def_name(def_name, self.args.length, !!block) similar_name = owner.lookup_similar_def_name(def_name, self.args.length, !!block)
...@@ -561,7 +579,7 @@ module Crystal ...@@ -561,7 +579,7 @@ module Crystal
defs_matching_args_length = defs.select { |a_def| a_def.args.length == self.args.length } defs_matching_args_length = defs.select { |a_def| a_def.args.length == self.args.length }
if defs_matching_args_length.empty? if defs_matching_args_length.empty?
all_arguments_lengths = defs.map { |a_def| a_def.args.length }.uniq! all_arguments_lengths = defs.map(&.args.length).uniq!
raise "wrong number of arguments for '#{full_name(owner, def_name)}' (#{args.length} for #{all_arguments_lengths.join ", "})" raise "wrong number of arguments for '#{full_name(owner, def_name)}' (#{args.length} for #{all_arguments_lengths.join ", "})"
end end
...@@ -637,6 +655,20 @@ module Crystal ...@@ -637,6 +655,20 @@ module Crystal
raise message, owner_trace raise message, owner_trace
end end
def check_macro_wrong_number_of_arguments(def_name)
macros = in_macro_target &.lookup_macros(def_name)
if macros
all_arguments_lengths = Set(Int32).new
macros.each do |macro|
min_length = macro.args.index(&.default_value) || macro.args.length
min_length.upto(macro.args.length) do |args_length|
all_arguments_lengths << args_length
end
end
raise "wrong number of arguments for macro '#{def_name}' (#{args.length} for #{all_arguments_lengths.join ", "})"
end
end
def full_name(owner, def_name = name) def full_name(owner, def_name = name)
owner.is_a?(Program) ? name : "#{owner}##{def_name}" owner.is_a?(Program) ? name : "#{owner}##{def_name}"
......
...@@ -305,6 +305,10 @@ module Crystal ...@@ -305,6 +305,10 @@ module Crystal
raise "Bug: #{self} doesn't implement lookup_macro" raise "Bug: #{self} doesn't implement lookup_macro"
end end
def lookup_macros(name)
raise "Bug: #{self} doesn't implement lookup_macros"
end
def include(mod) def include(mod)
raise "Bug: #{self} doesn't implement include" raise "Bug: #{self} doesn't implement include"
end end
...@@ -595,6 +599,19 @@ module Crystal ...@@ -595,6 +599,19 @@ module Crystal
nil nil
end end
def lookup_macros(name)
if (macros = self.macros) && (hash = macros[name]?)
return hash.values
end
parents.try &.each do |parent|
parent_macros = parent.lookup_macros(name)
return parent_macros if parent_macros
end
nil
end
end end
module DefContainer module DefContainer
...@@ -1759,6 +1776,10 @@ module Crystal ...@@ -1759,6 +1776,10 @@ module Crystal
@module.lookup_macro(name, args_length) @module.lookup_macro(name, args_length)
end end
def lookup_macros(name)
@module.lookup_macros(name)
end
def match_arg(arg_type, arg, owner, type_lookup, free_vars) def match_arg(arg_type, arg, owner, type_lookup, free_vars)
@module.match_arg(arg_type, arg, owner, type_lookup, free_vars) @module.match_arg(arg_type, arg, owner, type_lookup, free_vars)
end end
...@@ -1937,6 +1958,10 @@ module Crystal ...@@ -1937,6 +1958,10 @@ module Crystal
aliased_type.lookup_macro(name, args_length) aliased_type.lookup_macro(name, args_length)
end end
def lookup_macros(name)
aliased_type.lookup_macros(name)
end
def remove_alias def remove_alias
if aliased_type = @aliased_type if aliased_type = @aliased_type
aliased_type.remove_alias aliased_type.remove_alias
...@@ -2551,6 +2576,10 @@ module Crystal ...@@ -2551,6 +2576,10 @@ module Crystal
base_type.lookup_macro(name, args_length) base_type.lookup_macro(name, args_length)
end end
def lookup_macros(name)
base_type.lookup_macros(name)
end
def lookup_type(names : Array, already_looked_up = Set(Int32).new, lookup_in_container = true) def lookup_type(names : Array, already_looked_up = Set(Int32).new, lookup_in_container = true)
base_type.lookup_type(names, already_looked_up, lookup_in_container) base_type.lookup_type(names, already_looked_up, lookup_in_container)
end end
...@@ -2713,6 +2742,10 @@ module Crystal ...@@ -2713,6 +2742,10 @@ module Crystal
nil nil
end end
def lookup_macros(name)
nil
end
def metaclass? def metaclass?
true true
end end
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment