[ruby/prism] Frozen strings in the AST

8d9d429155
This commit is contained in:
Kevin Newton 2024-12-20 16:52:10 -05:00 committed by git
parent 48749afe61
commit 14b9098459
6 changed files with 42 additions and 9 deletions

View file

@ -2049,7 +2049,7 @@ module Prism
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

View file

@ -929,9 +929,9 @@ module Prism
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
@ -940,7 +940,7 @@ module Prism
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
@ -1440,6 +1440,7 @@ module Prism
unescaped = node.unescaped
if node.forced_binary_encoding?
unescaped = unescaped.dup
unescaped.force_encoding(Encoding::BINARY)
end

View file

@ -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

View file

@ -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

View file

@ -119,8 +119,8 @@ module Prism
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

View file

@ -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