diff options
author | Kevin Newton <[email protected]> | 2024-12-20 16:52:10 -0500 |
---|---|---|
committer | git <[email protected]> | 2025-01-12 18:41:42 +0000 |
commit | 14b9098459b88f94e316ccc9274693e74565739e (patch) | |
tree | 3f0d66e89ab1e4599cc549159eee3db88fd5e0d7 | |
parent | 48749afe61fedcfd59cbd2fcc134c55f5ccef7f8 (diff) |
[ruby/prism] Frozen strings in the AST
https://github.com/ruby/prism/commit/8d9d429155
-rw-r--r-- | lib/prism/translation/parser/compiler.rb | 2 | ||||
-rw-r--r-- | lib/prism/translation/ruby_parser.rb | 7 | ||||
-rw-r--r-- | prism/templates/ext/prism/api_node.c.erb | 2 | ||||
-rw-r--r-- | prism/templates/lib/prism/serialize.rb.erb | 4 | ||||
-rw-r--r-- | test/prism/encoding/regular_expression_encoding_test.rb | 4 | ||||
-rw-r--r-- | test/prism/result/string_test.rb | 32 |
6 files changed, 42 insertions, 9 deletions
diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb index e6ffa39d9d..26c5c174f4 100644 --- a/lib/prism/translation/parser/compiler.rb +++ b/lib/prism/translation/parser/compiler.rb @@ -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 diff --git a/lib/prism/translation/ruby_parser.rb b/lib/prism/translation/ruby_parser.rb index 465b693470..7fb533048c 100644 --- a/lib/prism/translation/ruby_parser.rb +++ b/lib/prism/translation/ruby_parser.rb @@ -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 diff --git a/prism/templates/ext/prism/api_node.c.erb b/prism/templates/ext/prism/api_node.c.erb index 03615b0ae2..777ebfa8fc 100644 --- a/prism/templates/ext/prism/api_node.c.erb +++ b/prism/templates/ext/prism/api_node.c.erb @@ -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 diff --git a/prism/templates/lib/prism/serialize.rb.erb b/prism/templates/lib/prism/serialize.rb.erb index 01c0a6cb2d..d40aa881e7 100644 --- a/prism/templates/lib/prism/serialize.rb.erb +++ b/prism/templates/lib/prism/serialize.rb.erb @@ -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 diff --git a/test/prism/encoding/regular_expression_encoding_test.rb b/test/prism/encoding/regular_expression_encoding_test.rb index 5d062fe59a..e2daae1d7f 100644 --- a/test/prism/encoding/regular_expression_encoding_test.rb +++ b/test/prism/encoding/regular_expression_encoding_test.rb @@ -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 diff --git a/test/prism/result/string_test.rb b/test/prism/result/string_test.rb new file mode 100644 index 0000000000..48c7f592eb --- /dev/null +++ b/test/prism/result/string_test.rb @@ -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 |