From 3ebc62d2dad590e49f5ab3189ebc885c2f1825d3 Mon Sep 17 00:00:00 2001 From: Benoit de Chezelles Date: Wed, 21 Feb 2018 21:08:37 -0800 Subject: [PATCH 1/2] parser: Add spec for method def block argument with new lines --- spec/compiler/parser/parser_spec.cr | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/compiler/parser/parser_spec.cr b/spec/compiler/parser/parser_spec.cr index aa233a832358..aefa882b3005 100644 --- a/spec/compiler/parser/parser_spec.cr +++ b/spec/compiler/parser/parser_spec.cr @@ -222,6 +222,10 @@ describe "Parser" do it_parses "def foo(@@var = 1); 1; end", Def.new("foo", [Arg.new("var", 1.int32)], [Assign.new("@@var".class_var, "var".var), 1.int32] of ASTNode) it_parses "def foo(&@block); end", Def.new("foo", body: Assign.new("@block".instance_var, "block".var), block_arg: Arg.new("block"), yields: 0) + it_parses "def foo(\n&block\n); end", Def.new("foo", block_arg: Arg.new("block"), yields: 0) + it_parses "def foo(&block \n: Int ->); end", Def.new("foo", block_arg: Arg.new("block", restriction: ProcNotation.new(["Int".path] of ASTNode)), yields: 1) + it_parses "def foo(&block :\n Int ->); end", Def.new("foo", block_arg: Arg.new("block", restriction: ProcNotation.new(["Int".path] of ASTNode)), yields: 1) + it_parses "def foo(a, &block : *Int -> ); end", Def.new("foo", [Arg.new("a")], block_arg: Arg.new("block", restriction: ProcNotation.new(["Int".path.splat] of ASTNode)), yields: 1) it_parses "def foo(x, *args, y = 2); 1; end", Def.new("foo", args: ["x".arg, "args".arg, Arg.new("y", default_value: 2.int32)], body: 1.int32, splat_index: 1) From 3350775f7cc9cf703e9a0ef062c43ef30d72781d Mon Sep 17 00:00:00 2001 From: Benoit de Chezelles Date: Wed, 21 Feb 2018 21:09:42 -0800 Subject: [PATCH 2/2] parser: Handle space or newline after def's block arg's type --- spec/compiler/parser/parser_spec.cr | 1 + src/compiler/crystal/syntax/parser.cr | 1 + 2 files changed, 2 insertions(+) diff --git a/spec/compiler/parser/parser_spec.cr b/spec/compiler/parser/parser_spec.cr index aefa882b3005..3550a245553b 100644 --- a/spec/compiler/parser/parser_spec.cr +++ b/spec/compiler/parser/parser_spec.cr @@ -225,6 +225,7 @@ describe "Parser" do it_parses "def foo(\n&block\n); end", Def.new("foo", block_arg: Arg.new("block"), yields: 0) it_parses "def foo(&block \n: Int ->); end", Def.new("foo", block_arg: Arg.new("block", restriction: ProcNotation.new(["Int".path] of ASTNode)), yields: 1) it_parses "def foo(&block :\n Int ->); end", Def.new("foo", block_arg: Arg.new("block", restriction: ProcNotation.new(["Int".path] of ASTNode)), yields: 1) + it_parses "def foo(&block : Int ->\n); end", Def.new("foo", block_arg: Arg.new("block", restriction: ProcNotation.new(["Int".path] of ASTNode)), yields: 1) it_parses "def foo(a, &block : *Int -> ); end", Def.new("foo", [Arg.new("a")], block_arg: Arg.new("block", restriction: ProcNotation.new(["Int".path.splat] of ASTNode)), yields: 1) diff --git a/src/compiler/crystal/syntax/parser.cr b/src/compiler/crystal/syntax/parser.cr index 50ed8c184b40..21548ce44be5 100644 --- a/src/compiler/crystal/syntax/parser.cr +++ b/src/compiler/crystal/syntax/parser.cr @@ -3410,6 +3410,7 @@ module Crystal if @token.type == :"&" next_token_skip_space_or_newline block_arg = parse_block_arg(extra_assigns) + skip_space_or_newline if args.any?(&.name.==(block_arg.name)) || (found_double_splat && found_double_splat.name == block_arg.name) raise "duplicated argument name: #{block_arg.name}", block_arg.location.not_nil! end