Skip to content

Commit

Permalink
Check that def, macro, and block parameters don't end with ? or !
Browse files Browse the repository at this point in the history
Fix for #10917
  • Loading branch information
potomak committed Jul 4, 2022
1 parent b2dc03a commit a1793e4
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
19 changes: 19 additions & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,25 @@ module Crystal
assert_syntax_error "foo { |(#{kw}))| }", "cannot use '#{kw}' as a block parameter name", 1, 9
end

# #10917
%w(
bar? bar!
).each do |name|
assert_syntax_error "def foo(#{name}); end", "invalid param name", 1, 14
assert_syntax_error "def foo(foo #{name}); end", "invalid param name", 1, 17
it_parses "def foo(#{name} foo); end", Def.new("foo", [Arg.new("foo", external_name: name.to_s)])

assert_syntax_error "macro foo(#{name}); end", "invalid param name", 1, 16
assert_syntax_error "macro foo(foo #{name}); end", "invalid param name", 1, 19
it_parses "macro foo(#{name} foo); end", Macro.new("foo", [Arg.new("foo", external_name: name.to_s)], body: MacroLiteral.new(" "))

it_parses "foo(#{name})", Call.new(nil, "foo", [name.call] of ASTNode)
it_parses "foo #{name}", Call.new(nil, "foo", [name.call] of ASTNode)

assert_syntax_error "foo { |#{name})| }", "invalid param name", 1, 12
assert_syntax_error "foo { |(#{name}))| }", "invalid param name", 1, 13
end

it_parses "def self.foo\n1\nend", Def.new("foo", body: 1.int32, receiver: "self".var)
it_parses "def self.foo()\n1\nend", Def.new("foo", body: 1.int32, receiver: "self".var)
it_parses "def self.foo=\n1\nend", Def.new("foo=", body: 1.int32, receiver: "self".var)
Expand Down
11 changes: 11 additions & 0 deletions src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3938,6 +3938,8 @@ module Crystal
raise "when specified, external name must be different than internal name", @token
end

check_valid_param_name(arg_name)

uses_arg = false
do_next_token = true
when .instance_var?
Expand Down Expand Up @@ -4001,6 +4003,7 @@ module Crystal
raise "cannot use '#{invalid_internal_name}' as a parameter name", invalid_internal_name
end
arg_name = external_name
check_valid_param_name(arg_name)
else
unexpected_token
end
Expand Down Expand Up @@ -4050,6 +4053,12 @@ module Crystal
end
end

def check_valid_param_name(param_name)
if param_name.ends_with?(/\?|!/)
raise "invalid param name"
end
end

def parse_if(check_end = true)
location = @token.location

Expand Down Expand Up @@ -4368,6 +4377,7 @@ module Crystal
end

arg_name = @token.value.to_s
check_valid_param_name(arg_name)

if all_names.includes?(arg_name)
raise "duplicated block parameter name: #{arg_name}", @token
Expand All @@ -4389,6 +4399,7 @@ module Crystal
end

sub_arg_name = @token.value.to_s
check_valid_param_name(sub_arg_name)

if all_names.includes?(sub_arg_name)
raise "duplicated block parameter name: #{sub_arg_name}", @token
Expand Down

0 comments on commit a1793e4

Please sign in to comment.