Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/prism/translation/parser/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2049,7 +2049,7 @@ def visit_heredoc(node)
location = appendee.loc
location = location.with_expression(location.expression.join(child.loc.expression))

children[-1] = appendee.updated(:str, [appendee.children.first << child.children.first], location: location)
children[-1] = appendee.updated(:str, ["#{appendee.children.first}#{child.children.first}"], location: location)
else
children << child
end
Expand Down
7 changes: 4 additions & 3 deletions lib/prism/translation/ruby_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -929,9 +929,9 @@ def visit_interpolated_x_string_node(node)
if result == :space
# continue
elsif result.is_a?(String)
results[0] << result
results[0] = "#{results[0]}#{result}"
elsif result.is_a?(Array) && result[0] == :str
results[0] << result[1]
results[0] = "#{results[0]}#{result[1]}"
else
results << result
state = :interpolated_content
Expand All @@ -940,7 +940,7 @@ def visit_interpolated_x_string_node(node)
if result == :space
# continue
elsif visited[index - 1] != :space && result.is_a?(Array) && result[0] == :str && results[-1][0] == :str && (results[-1].line_max == result.line)
results[-1][1] << result[1]
results[-1][1] = "#{results[-1][1]}#{result[1]}"
results[-1].line_max = result.line_max
else
results << result
Expand Down Expand Up @@ -1440,6 +1440,7 @@ def visit_string_node(node)
unescaped = node.unescaped

if node.forced_binary_encoding?
unescaped = unescaped.dup
unescaped.force_encoding(Encoding::BINARY)
end

Expand Down
2 changes: 1 addition & 1 deletion templates/ext/prism/api_node.c.erb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pm_token_new(const pm_parser_t *parser, const pm_token_t *token, rb_encoding *en

static VALUE
pm_string_new(const pm_string_t *string, rb_encoding *encoding) {
return rb_enc_str_new((const char *) pm_string_source(string), pm_string_length(string), encoding);
return rb_obj_freeze(rb_enc_str_new((const char *) pm_string_source(string), pm_string_length(string), encoding));
}

VALUE
Expand Down
4 changes: 2 additions & 2 deletions templates/lib/prism/serialize.rb.erb
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,14 @@ module Prism
end

def load_embedded_string
io.read(load_varuint).force_encoding(encoding)
io.read(load_varuint).force_encoding(encoding).freeze
end

def load_string
type = io.getbyte
case type
when 1
input.byteslice(load_varuint, load_varuint).force_encoding(encoding)
input.byteslice(load_varuint, load_varuint).force_encoding(encoding).freeze
when 2
load_embedded_string
else
Expand Down
4 changes: 2 additions & 2 deletions test/prism/encoding/regular_expression_encoding_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ def assert_regular_expression_encoding_flags(encoding, regexps)
if expected.is_a?(Array) && actual.is_a?(Array)
if expected.last.start_with?("/.../n has a non escaped non ASCII character in non ASCII-8BIT script:") &&
actual.last.start_with?("/.../n has a non escaped non ASCII character in non ASCII-8BIT script:")
expected.last.clear
actual.last.clear
expected.pop
actual.pop
end
end

Expand Down
32 changes: 32 additions & 0 deletions test/prism/result/string_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

require_relative "../test_helper"

module Prism
class StringTest < TestCase
def test_regular_expression_node_unescaped_frozen
node = Prism.parse_statement("/foo/")
assert_predicate node.unescaped, :frozen?
end

def test_source_file_node_filepath_frozen
node = Prism.parse_statement("__FILE__")
assert_predicate node.filepath, :frozen?
end

def test_string_node_unescaped_frozen
node = Prism.parse_statement('"foo"')
assert_predicate node.unescaped, :frozen?
end

def test_symbol_node_unescaped_frozen
node = Prism.parse_statement(":foo")
assert_predicate node.unescaped, :frozen?
end

def test_xstring_node_unescaped_frozen
node = Prism.parse_statement("`foo`")
assert_predicate node.unescaped, :frozen?
end
end
end
Loading