Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0c3c3d4694b6
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5af6fb75c172
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Jun 3, 2017

  1. Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    7c51424 View commit details

Commits on Jun 4, 2017

  1. Another way to fix #4311

    asterite committed Jun 4, 2017
    Copy the full SHA
    91f1035 View commit details
  2. Copy the full SHA
    5af6fb7 View commit details
Showing with 25 additions and 19 deletions.
  1. +4 −3 spec/compiler/parser/parser_spec.cr
  2. +2 −2 src/char/reader.cr
  3. +19 −14 src/compiler/crystal/syntax/parser.cr
7 changes: 4 additions & 3 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
@@ -1047,6 +1047,7 @@ describe "Parser" do
it_parses "{\n1,\n2\n}", TupleLiteral.new([1.int32, 2.int32] of ASTNode)
it_parses "{\n1\n}", TupleLiteral.new([1.int32] of ASTNode)
it_parses "{\n{1}\n}", TupleLiteral.new([TupleLiteral.new([1.int32] of ASTNode)] of ASTNode)
it_parses %({"".id}), TupleLiteral.new([Call.new("".string, "id")] of ASTNode)

it_parses "foo { a = 1 }; a", [Call.new(nil, "foo", block: Block.new(body: Assign.new("a".var, 1.int32))), "a".call] of ASTNode

@@ -1475,9 +1476,6 @@ describe "Parser" do

assert_syntax_error %(def foo("bar");end), "expected argument internal name"

assert_syntax_error %({"a" : 1})
assert_syntax_error %({"a": 1, "b" : 2})

describe "end locations" do
assert_end_location "nil"
assert_end_location "false"
@@ -1535,6 +1533,9 @@ describe "Parser" do
assert_end_location "1.as(Int32)"
assert_end_location "puts obj.foo"

assert_syntax_error %({"a" : 1}), "space not allowed between named argument name and ':'"
assert_syntax_error %({"a": 1, "b" : 2}), "space not allowed between named argument name and ':'"

it "gets corrects of ~" do
node = Parser.parse("\n ~1")
loc = node.location.not_nil!
4 changes: 2 additions & 2 deletions src/char/reader.cr
Original file line number Diff line number Diff line change
@@ -134,12 +134,12 @@ struct Char
# is decremented.
# Raises `IndexError` if the reader is at the begining of
# the `#string`
def previous_char
def previous_char : Char
unless has_previous?
raise IndexError.new
end

decode_previous_char
decode_previous_char.as(Char)
end

# Sets `#pos` to *pos*.
33 changes: 19 additions & 14 deletions src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
@@ -1761,7 +1761,7 @@ module Crystal

delimiter_state, has_interpolation, options, token_end_location = consume_delimiter pieces, delimiter_state, has_interpolation

if delimiter_state.kind == :string && want_skip_space
if want_skip_space && delimiter_state.kind == :string
while true
passed_backslash_newline = @token.passed_backslash_newline
skip_space
@@ -2096,22 +2096,23 @@ module Crystal
end
return parse_named_tuple(location)
else
if string_literal_start?
first_key = parse_delimiter(want_skip_space: false)
if first_key.is_a?(StringLiteral) && @token.type == :":"
first_key = parse_op_assign_no_control
case @token.type
when :":"
# Check that there's no space before the ':'
if @token.column_number != first_key.end_location.not_nil!.column_number + 1
raise "space not allowed between named argument name and ':'"
end

if first_key.is_a?(StringLiteral)
# It's a named tuple
unless allow_of
raise "can't use named tuple syntax for Hash-like literal, use '=>'", @token
end
return parse_named_tuple(location, first_key.value)
else
check :"=>"
end
else
first_key = parse_op_assign_no_control
end

skip_space

case @token.type
when :","
slash_is_regex!
next_token_skip_space_or_newline
@@ -2125,10 +2126,10 @@ module Crystal
else
check :"=>"
end
slash_is_regex!
next_token_skip_space
parse_hash_literal first_key, location, allow_of
end
slash_is_regex!
next_token_skip_space
parse_hash_literal first_key, location, allow_of
end
end

@@ -2274,6 +2275,10 @@ module Crystal
raise "expected '}' or named tuple name, not #{@token}", @token
end

if @token.type == :SPACE
raise "space not allowed between named argument name and ':'"
end

check :":"

if entries.any? { |entry| entry.key == key }