Skip to content

Commit

Permalink
Don't use heredoc inside interpolation
Browse files Browse the repository at this point in the history
heredoc inside interpolation is buggy and it is unuseful.
It is a bit hard to fix this, so I'd like to forbid.
  • Loading branch information
makenowjust authored and ysbaddaden committed Mar 14, 2018
1 parent 077e0da commit 52fa3b2
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 0 deletions.
1 change: 1 addition & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,7 @@ describe "Parser" do
assert_syntax_error "<<-HERE\n One\n \#{1}\n wrong\n HERE", "heredoc line must have an indent greater or equal than 2", 4, 1
assert_syntax_error "<<-HERE\n One\n \#{1}\n wrong\#{1}\n HERE", "heredoc line must have an indent greater or equal than 2", 4, 1
assert_syntax_error "<<-HERE\n One\n \#{1}\n HERE", "heredoc line must have an indent greater or equal than 2", 2, 1
assert_syntax_error %("\#{<<-HERE}"\nHERE), "heredoc cannot be used inside interpolation"
assert_syntax_error %("foo" "bar")

it_parses "<<-'HERE'\n hello \\n world\n \#{1}\n HERE", "hello \\n world\n\#{1}".string_interpolation
Expand Down
7 changes: 7 additions & 0 deletions src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module Crystal
@doc_enabled = false
@no_type_declaration = 0
@consuming_heredocs = false
@inside_interpolation = false

# This flags tells the parser where it has to consider a "do"
# as belonging to the current parsed call. For example when writing
Expand Down Expand Up @@ -1795,6 +1796,9 @@ module Crystal
check :DELIMITER_START

if delimiter_state.kind == :heredoc
if @inside_interpolation
raise "heredoc cannot be used inside interpolation", location
end
node = StringInterpolation.new([] of ASTNode).at(location)
@heredocs << {delimiter_state, node}
next_token
Expand Down Expand Up @@ -1900,6 +1904,8 @@ module Crystal
line_number = @token.line_number
delimiter_state = @token.delimiter_state
next_token_skip_space_or_newline
old_inside_interpolation = @inside_interpolation
@inside_interpolation = true
exp = preserve_stop_on_do { parse_expression }

if exp.is_a?(StringLiteral)
Expand All @@ -1916,6 +1922,7 @@ module Crystal

@token.delimiter_state = delimiter_state
next_string_token(delimiter_state)
@inside_interpolation = old_inside_interpolation
delimiter_state = @token.delimiter_state
end
end
Expand Down

0 comments on commit 52fa3b2

Please sign in to comment.