diff options
Diffstat (limited to 'test')
196 files changed, 2501 insertions, 1230 deletions
diff --git a/test/-ext-/thread/test_instrumentation_api.rb b/test/-ext-/thread/test_instrumentation_api.rb index 9a3b67fa10..663e41be53 100644 --- a/test/-ext-/thread/test_instrumentation_api.rb +++ b/test/-ext-/thread/test_instrumentation_api.rb @@ -54,7 +54,7 @@ class TestThreadInstrumentation < Test::Unit::TestCase thread&.join end - def test_muti_thread_timeline + def test_multi_thread_timeline threads = nil full_timeline = record do threads = threaded_cpu_bound_work(1.0) @@ -68,7 +68,7 @@ class TestThreadInstrumentation < Test::Unit::TestCase threads.each do |thread| timeline = timeline_for(thread, full_timeline) assert_consistent_timeline(timeline) - assert timeline.count(:suspended) > 1, "Expected threads to yield suspended at least once: #{timeline.inspect}" + assert_operator timeline.count(:suspended), :>=, 1, "Expected threads to yield suspended at least once: #{timeline.inspect}" end timeline = timeline_for(Thread.current, full_timeline) diff --git a/test/.excludes-prism/TestAssignment.rb b/test/.excludes-prism/TestAssignment.rb deleted file mode 100644 index 23a1b4c5e7..0000000000 --- a/test/.excludes-prism/TestAssignment.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_massign_order, "https://github.com/ruby/prism/issues/2370") diff --git a/test/.excludes-prism/TestAssignmentGen.rb b/test/.excludes-prism/TestAssignmentGen.rb deleted file mode 100644 index 5f3bb12ef7..0000000000 --- a/test/.excludes-prism/TestAssignmentGen.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_assignment, "https://github.com/ruby/prism/issues/2370") diff --git a/test/.excludes-prism/TestCall.rb b/test/.excludes-prism/TestCall.rb deleted file mode 100644 index 969e32ea5a..0000000000 --- a/test/.excludes-prism/TestCall.rb +++ /dev/null @@ -1,3 +0,0 @@ -exclude(:test_call_op_asgn_keywords, "https://github.com/ruby/prism/issues/2438") -exclude(:test_call_op_asgn_keywords_mutable, "https://github.com/ruby/prism/issues/2438") -exclude(:test_kwsplat_block_order_op_asgn, "https://github.com/ruby/prism/issues/2438") diff --git a/test/.excludes-prism/TestCoverage.rb b/test/.excludes-prism/TestCoverage.rb deleted file mode 100644 index 20f9972f89..0000000000 --- a/test/.excludes-prism/TestCoverage.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_eval, "unknown") diff --git a/test/.excludes-prism/TestIRB/RubyLexTest.rb b/test/.excludes-prism/TestIRB/RubyLexTest.rb deleted file mode 100644 index 2274ae62cf..0000000000 --- a/test/.excludes-prism/TestIRB/RubyLexTest.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_code_block_open_with_should_continue, "symbol encoding") diff --git a/test/.excludes-prism/TestISeq.rb b/test/.excludes-prism/TestISeq.rb deleted file mode 100644 index 3768d8fc05..0000000000 --- a/test/.excludes-prism/TestISeq.rb +++ /dev/null @@ -1,3 +0,0 @@ -exclude(:test_each_child, "https://github.com/ruby/prism/issues/2660") -exclude(:test_syntax_error_message, "Assertion checks against specific error format") -exclude(:test_trace_points, "https://github.com/ruby/prism/issues/2660") diff --git a/test/.excludes-prism/TestM17N.rb b/test/.excludes-prism/TestM17N.rb index 15ed504fc9..7f8c44d02a 100644 --- a/test/.excludes-prism/TestM17N.rb +++ b/test/.excludes-prism/TestM17N.rb @@ -1,7 +1 @@ -exclude(:test_dynamic_eucjp_regexp, "https://github.com/ruby/prism/issues/2664") -exclude(:test_dynamic_sjis_regexp, "https://github.com/ruby/prism/issues/2664") -exclude(:test_dynamic_utf8_regexp, "https://github.com/ruby/prism/issues/2664") -exclude(:test_regexp_ascii, "https://github.com/ruby/prism/issues/2664") -exclude(:test_regexp_embed, "https://github.com/ruby/prism/issues/2664") -exclude(:test_regexp_usascii, "unknown") -exclude(:test_string_mixed_unicode, "unknown") +exclude(:test_regexp_usascii, "https://bugs.ruby-lang.org/issues/20504") diff --git a/test/.excludes-prism/TestMixedUnicodeEscape.rb b/test/.excludes-prism/TestMixedUnicodeEscape.rb index 09e3cc168b..7bf964ebf1 100644 --- a/test/.excludes-prism/TestMixedUnicodeEscape.rb +++ b/test/.excludes-prism/TestMixedUnicodeEscape.rb @@ -1 +1 @@ -exclude(:test_basic, "unknown") +exclude(:test_basic, "https://bugs.ruby-lang.org/issues/20504") diff --git a/test/.excludes-prism/TestParse.rb b/test/.excludes-prism/TestParse.rb deleted file mode 100644 index 83af593b15..0000000000 --- a/test/.excludes-prism/TestParse.rb +++ /dev/null @@ -1,28 +0,0 @@ -exclude(:test_dynamic_constant_assignment, "unknown") -exclude(:test_else_without_rescue, "unknown") -exclude(:test_error_def_in_argument, "unknown") -exclude(:test_float, "unknown") -exclude(:test_global_variable, "unknown") -exclude(:test_here_document, "unknown") -exclude(:test_heredoc_unterminated_interpolation, "unknown") -exclude(:test_invalid_char, "unknown") -exclude(:test_location_of_invalid_token, "unknown") -exclude(:test_op_asgn1_with_block, "unknown") -exclude(:test_parse_string, "unknown") -exclude(:test_percent, "unknown") -exclude(:test_question, "unknown") -exclude(:test_shareable_constant_value_ignored, "unknown") -exclude(:test_shareable_constant_value_nested, "ractor support") -exclude(:test_shareable_constant_value_nonliteral, "ractor support") -exclude(:test_shareable_constant_value_simple, "ractor support") -exclude(:test_shareable_constant_value_unfrozen, "ractor support") -exclude(:test_shareable_constant_value_unshareable_literal, "ractor support") -exclude(:test_string, "unknown") -exclude(:test_truncated_source_line, "unknown") -exclude(:test_unassignable, "unknown") -exclude(:test_unexpected_eof, "unknown") -exclude(:test_unexpected_token_after_numeric, "unknown") -exclude(:test_unterminated_regexp_error, "unknown") -exclude(:test_unused_variable, "missing warning") -exclude(:test_void_value_in_rhs, "unknown") -exclude(:test_words, "unknown") diff --git a/test/.excludes-prism/TestPatternMatching.rb b/test/.excludes-prism/TestPatternMatching.rb deleted file mode 100644 index cfd0c6bed9..0000000000 --- a/test/.excludes-prism/TestPatternMatching.rb +++ /dev/null @@ -1,2 +0,0 @@ -exclude(:test_hash_pattern, "useless literal warning missing") -exclude(:test_invalid_syntax, "[a:] is disallowed") diff --git a/test/.excludes-prism/TestRegexp.rb b/test/.excludes-prism/TestRegexp.rb deleted file mode 100644 index 68ad1414a9..0000000000 --- a/test/.excludes-prism/TestRegexp.rb +++ /dev/null @@ -1,6 +0,0 @@ -exclude(:test_invalid_escape_error, "unknown") -exclude(:test_invalid_fragment, "https://github.com/ruby/prism/issues/2664") -exclude(:test_unescape, "unknown") -exclude(:test_unicode_age_14_0, "https://github.com/ruby/prism/issues/2664") -exclude(:test_unicode_age_15_0, "https://github.com/ruby/prism/issues/2664") -exclude(:test_unicode_age, "https://github.com/ruby/prism/issues/2664") diff --git a/test/.excludes-prism/TestRequire.rb b/test/.excludes-prism/TestRequire.rb deleted file mode 100644 index a7f66c5d80..0000000000 --- a/test/.excludes-prism/TestRequire.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_require_nonascii_path_shift_jis, "encoding") diff --git a/test/.excludes-prism/TestRubyLiteral.rb b/test/.excludes-prism/TestRubyLiteral.rb index 926f0c5a5e..853f23a3b9 100644 --- a/test/.excludes-prism/TestRubyLiteral.rb +++ b/test/.excludes-prism/TestRubyLiteral.rb @@ -1,5 +1 @@ -exclude(:test_debug_frozen_string_in_array_literal, "unknown") -exclude(:test_debug_frozen_string, "unknown") -exclude(:test_dregexp, "https://github.com/ruby/prism/issues/2664") -exclude(:test_hash_value_omission, "unknown") -exclude(:test_string, "https://github.com/ruby/prism/issues/2331") +exclude(:test_dregexp, "https://bugs.ruby-lang.org/issues/20504") diff --git a/test/.excludes-prism/TestRubyOptimization.rb b/test/.excludes-prism/TestRubyOptimization.rb deleted file mode 100644 index df22ca4f71..0000000000 --- a/test/.excludes-prism/TestRubyOptimization.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_peephole_string_literal_range, "unknown") diff --git a/test/.excludes-prism/TestRubyVM.rb b/test/.excludes-prism/TestRubyVM.rb deleted file mode 100644 index 6d4c3ca6fe..0000000000 --- a/test/.excludes-prism/TestRubyVM.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_keep_script_lines, "unknown") diff --git a/test/.excludes-prism/TestSetTraceFunc.rb b/test/.excludes-prism/TestSetTraceFunc.rb deleted file mode 100644 index 036faef650..0000000000 --- a/test/.excludes-prism/TestSetTraceFunc.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_return, "unknown") diff --git a/test/.excludes-prism/TestSyntax.rb b/test/.excludes-prism/TestSyntax.rb index 61051e2f37..926d2681d8 100644 --- a/test/.excludes-prism/TestSyntax.rb +++ b/test/.excludes-prism/TestSyntax.rb @@ -1,29 +1,2 @@ -exclude(:test__END___cr, "unknown") -exclude(:test_anonymous_block_forwarding, "unknown") -exclude(:test_anonymous_keyword_rest_forwarding, "unknown") -exclude(:test_anonymous_rest_forwarding, "unknown") -exclude(:test_argument_forwarding_with_super, "unknown") -exclude(:test_argument_forwarding, "unknown") -exclude(:test_brace_after_literal_argument, "unknown") -exclude(:test_dedented_heredoc_concatenation, "unknown") -exclude(:test_dedented_heredoc_continued_line, "unknown") -exclude(:test_dedented_heredoc_invalid_identifer, "unknown") -exclude(:test_duplicated_when, "unknown") -exclude(:test_error_message_encoding, "unknown") -exclude(:test_heredoc_cr, "unknown") -exclude(:test_heredoc_no_terminator, "unknown") -exclude(:test_invalid_encoding_symbol, "unknown") -exclude(:test_it, "https://github.com/ruby/prism/issues/2323") -exclude(:test_keyword_invalid_name, "unknown") -exclude(:test_keyword_self_reference, "unknown") -exclude(:test_keywords_specified_and_not_accepted, "unknown") -exclude(:test_methoddef_endless_command, "unknown") -exclude(:test_numbered_parameter, "unknown") -exclude(:test_optional_self_reference, "unknown") -exclude(:test_safe_call_in_massign_lhs, "unknown") -exclude(:test_syntax_error_at_newline, "unknown") -exclude(:test_unexpected_fraction, "unknown") -exclude(:test_unterminated_heredoc_cr, "unknown") -exclude(:test_unterminated_heredoc, "unknown") -exclude(:test_warn_balanced, "unknown") -exclude(:test_warn_unreachable, "unknown") +exclude(:test_optional_self_reference, "https://bugs.ruby-lang.org/issues/20478") +exclude(:test_keyword_self_reference, "https://bugs.ruby-lang.org/issues/20478") diff --git a/test/.excludes-prism/TestUnicodeEscape.rb b/test/.excludes-prism/TestUnicodeEscape.rb deleted file mode 100644 index add4911bc2..0000000000 --- a/test/.excludes-prism/TestUnicodeEscape.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_fail, "unknown") diff --git a/test/error_highlight/test_error_highlight.rb b/test/error_highlight/test_error_highlight.rb index 2095970af1..69aef31339 100644 --- a/test/error_highlight/test_error_highlight.rb +++ b/test/error_highlight/test_error_highlight.rb @@ -1,6 +1,7 @@ require "test/unit" require "error_highlight" +require "did_you_mean" require "tempfile" class ErrorHighlightTest < Test::Unit::TestCase diff --git a/test/irb/command/test_custom_command.rb b/test/irb/command/test_custom_command.rb index 6642d2b160..3a3ad11d5a 100644 --- a/test/irb/command/test_custom_command.rb +++ b/test/irb/command/test_custom_command.rb @@ -5,7 +5,7 @@ require_relative "../helper" module TestIRB class CustomCommandIntegrationTest < TestIRB::IntegrationTestCase - def test_command_regsitration_can_happen_after_irb_require + def test_command_registration_can_happen_after_irb_require write_ruby <<~RUBY require "irb" require "irb/command" @@ -15,7 +15,6 @@ module TestIRB description 'print_command' def execute(*) puts "Hello from PrintCommand" - nil end end @@ -25,14 +24,14 @@ module TestIRB RUBY output = run_ruby_file do - type "print!\n" + type "print!" type "exit" end assert_include(output, "Hello from PrintCommand") end - def test_command_regsitration_accepts_string_too + def test_command_registration_accepts_string_too write_ruby <<~RUBY require "irb/command" @@ -41,7 +40,6 @@ module TestIRB description 'print_command' def execute(*) puts "Hello from PrintCommand" - nil end end @@ -51,14 +49,14 @@ module TestIRB RUBY output = run_ruby_file do - type "print!\n" + type "print!" type "exit" end assert_include(output, "Hello from PrintCommand") end - def test_arguments_propogation + def test_arguments_propagation write_ruby <<~RUBY require "irb/command" @@ -69,7 +67,6 @@ module TestIRB $nth_execution ||= 0 puts "\#{$nth_execution} arg=\#{arg.inspect}" $nth_execution += 1 - nil end end @@ -79,9 +76,9 @@ module TestIRB RUBY output = run_ruby_file do - type "print_arg\n" + type "print_arg" type "print_arg \n" - type "print_arg a r g\n" + type "print_arg a r g" type "print_arg a r g \n" type "exit" end @@ -103,7 +100,6 @@ module TestIRB $nth_execution ||= 1 puts "\#{$nth_execution} FooBar executed" $nth_execution += 1 - nil end end @@ -123,5 +119,31 @@ module TestIRB assert_include(output, "2 FooBar executed") assert_include(output, "foobar_description") end + + def test_no_meta_command_also_works + write_ruby <<~RUBY + require "irb/command" + + class NoMetaCommand < IRB::Command::Base + def execute(*) + puts "This command does not override meta attributes" + end + end + + IRB::Command.register(:no_meta, NoMetaCommand) + + binding.irb + RUBY + + output = run_ruby_file do + type "no_meta" + type "help no_meta" + type "exit" + end + + assert_include(output, "This command does not override meta attributes") + assert_include(output, "No description provided.") + assert_not_include(output, "Maybe IRB bug") + end end end diff --git a/test/irb/command/test_help.rb b/test/irb/command/test_help.rb index df3753dae7..b34832b022 100644 --- a/test/irb/command/test_help.rb +++ b/test/irb/command/test_help.rb @@ -69,7 +69,7 @@ module TestIRB type "exit" end - assert_match(/Helper methods\s+conf\s+Returns the current context/, out) + assert_match(/Helper methods\s+conf\s+Returns the current IRB context/, out) end end end diff --git a/test/irb/helper.rb b/test/irb/helper.rb index 1614b42adb..acaf6277f3 100644 --- a/test/irb/helper.rb +++ b/test/irb/helper.rb @@ -121,7 +121,9 @@ module TestIRB @envs["XDG_CONFIG_HOME"] ||= tmp_dir @envs["IRBRC"] = nil unless @envs.key?("IRBRC") - PTY.spawn(@envs.merge("TERM" => "dumb"), *cmd) do |read, write, pid| + envs_for_spawn = @envs.merge('TERM' => 'dumb', 'TEST_IRB_FORCE_INTERACTIVE' => 'true') + + PTY.spawn(envs_for_spawn, *cmd) do |read, write, pid| Timeout.timeout(TIMEOUT_SEC) do while line = safe_gets(read) lines << line @@ -196,7 +198,7 @@ module TestIRB end def write_ruby(program) - @ruby_file = Tempfile.create(%w{irb- .rb}) + @ruby_file = Tempfile.create(%w{irbtest- .rb}) @tmpfiles << @ruby_file @ruby_file.write(program) @ruby_file.close diff --git a/test/irb/test_debugger_integration.rb b/test/irb/test_debugger_integration.rb index eca40c5702..8b1bddea17 100644 --- a/test/irb/test_debugger_integration.rb +++ b/test/irb/test_debugger_integration.rb @@ -67,6 +67,22 @@ module TestIRB assert_match(/IRB is already running with a debug session/, output) end + def test_debug_command_can_only_be_called_from_binding_irb + write_ruby <<~'ruby' + require "irb" + # trick test framework + puts "binding.irb" + IRB.start + ruby + + output = run_ruby_file do + type "debug" + type "exit" + end + + assert_include(output, "Debugging commands are only available when IRB is started with binding.irb") + end + def test_next write_ruby <<~'ruby' binding.irb diff --git a/test/irb/test_init.rb b/test/irb/test_init.rb index f11d7398c8..3207c2898b 100644 --- a/test/irb/test_init.rb +++ b/test/irb/test_init.rb @@ -268,15 +268,95 @@ module TestIRB end end + class ConfigValidationTest < TestCase + def setup + @original_home = ENV["HOME"] + @original_irbrc = ENV["IRBRC"] + # To prevent the test from using the user's .irbrc file + ENV["HOME"] = @home = Dir.mktmpdir + IRB.instance_variable_set(:@existing_rc_name_generators, nil) + super + end + + def teardown + super + ENV["IRBRC"] = @original_irbrc + ENV["HOME"] = @original_home + File.unlink(@irbrc) + Dir.rmdir(@home) + end + + def test_irb_name_converts_non_string_values_to_string + assert_no_irb_validation_error(<<~'RUBY') + IRB.conf[:IRB_NAME] = :foo + RUBY + + assert_equal "foo", IRB.conf[:IRB_NAME] + end + + def test_irb_rc_name_only_takes_callable_objects + assert_irb_validation_error(<<~'RUBY', "IRB.conf[:IRB_RC] should be a callable object. Got :foo.") + IRB.conf[:IRB_RC] = :foo + RUBY + end + + def test_back_trace_limit_only_accepts_integers + assert_irb_validation_error(<<~'RUBY', "IRB.conf[:BACK_TRACE_LIMIT] should be an integer. Got \"foo\".") + IRB.conf[:BACK_TRACE_LIMIT] = "foo" + RUBY + end + + def test_prompt_only_accepts_hash + assert_irb_validation_error(<<~'RUBY', "IRB.conf[:PROMPT] should be a Hash. Got \"foo\".") + IRB.conf[:PROMPT] = "foo" + RUBY + end + + def test_eval_history_only_accepts_integers + assert_irb_validation_error(<<~'RUBY', "IRB.conf[:EVAL_HISTORY] should be an integer. Got \"foo\".") + IRB.conf[:EVAL_HISTORY] = "foo" + RUBY + end + + private + + def assert_irb_validation_error(rc_content, error_message) + write_rc rc_content + + assert_raise_with_message(TypeError, error_message) do + IRB.setup(__FILE__) + end + end + + def assert_no_irb_validation_error(rc_content) + write_rc rc_content + + assert_nothing_raised do + IRB.setup(__FILE__) + end + end + + def write_rc(content) + @irbrc = Tempfile.new('irbrc') + @irbrc.write(content) + @irbrc.close + ENV['IRBRC'] = @irbrc.path + end + end + class InitIntegrationTest < IntegrationTestCase - def test_load_error_in_rc_file_is_warned - write_rc <<~'IRBRC' - require "file_that_does_not_exist" - IRBRC + def setup + super write_ruby <<~'RUBY' binding.irb RUBY + end + + def test_load_error_in_rc_file_is_warned + write_rc <<~'IRBRC' + require "file_that_does_not_exist" + IRBRC output = run_ruby_file do type "'foobar'" @@ -293,10 +373,6 @@ module TestIRB raise "I'm an error" IRBRC - write_ruby <<~'RUBY' - binding.irb - RUBY - output = run_ruby_file do type "'foobar'" type "exit" diff --git a/test/irb/test_irb.rb b/test/irb/test_irb.rb index 84b9ee3644..28be744088 100644 --- a/test/irb/test_irb.rb +++ b/test/irb/test_irb.rb @@ -125,6 +125,26 @@ module TestIRB end end + class NestedBindingIrbTest < IntegrationTestCase + def test_current_context_restore + write_ruby <<~'RUBY' + binding.irb + RUBY + + output = run_ruby_file do + type '$ctx = IRB.CurrentContext' + type 'binding.irb' + type 'p context_changed: IRB.CurrentContext != $ctx' + type 'exit' + type 'p context_restored: IRB.CurrentContext == $ctx' + type 'exit' + end + + assert_include output, '{:context_changed=>true}' + assert_include output, '{:context_restored=>true}' + end + end + class IrbIOConfigurationTest < TestCase Row = Struct.new(:content, :current_line_spaces, :new_line_spaces, :indent_level) @@ -803,4 +823,95 @@ module TestIRB IRB::Irb.new(workspace, TestInputMethod.new) end end + + class BacktraceFilteringTest < TestIRB::IntegrationTestCase + def test_backtrace_filtering + write_ruby <<~'RUBY' + def foo + raise "error" + end + + def bar + foo + end + + binding.irb + RUBY + + output = run_ruby_file do + type "bar" + type "exit" + end + + assert_match(/irbtest-.*\.rb:2:in (`|'Object#)foo': error \(RuntimeError\)/, output) + frame_traces = output.split("\n").select { |line| line.strip.match?(/from /) }.map(&:strip) + + expected_traces = if RUBY_VERSION >= "3.3.0" + [ + /from .*\/irbtest-.*.rb:6:in (`|'Object#)bar'/, + /from .*\/irbtest-.*.rb\(irb\):1:in [`']<main>'/, + /from <internal:kernel>:\d+:in (`|'Kernel#)loop'/, + /from <internal:prelude>:\d+:in (`|'Binding#)irb'/, + /from .*\/irbtest-.*.rb:9:in [`']<main>'/ + ] + else + [ + /from .*\/irbtest-.*.rb:6:in (`|'Object#)bar'/, + /from .*\/irbtest-.*.rb\(irb\):1:in [`']<main>'/, + /from <internal:prelude>:\d+:in (`|'Binding#)irb'/, + /from .*\/irbtest-.*.rb:9:in [`']<main>'/ + ] + end + + expected_traces.reverse! if RUBY_VERSION < "3.0.0" + + expected_traces.each_with_index do |expected_trace, index| + assert_match(expected_trace, frame_traces[index]) + end + end + + def test_backtrace_filtering_with_backtrace_filter + write_rc <<~'RUBY' + class TestBacktraceFilter + def self.call(backtrace) + backtrace.reject { |line| line.include?("internal") } + end + end + + IRB.conf[:BACKTRACE_FILTER] = TestBacktraceFilter + RUBY + + write_ruby <<~'RUBY' + def foo + raise "error" + end + + def bar + foo + end + + binding.irb + RUBY + + output = run_ruby_file do + type "bar" + type "exit" + end + + assert_match(/irbtest-.*\.rb:2:in (`|'Object#)foo': error \(RuntimeError\)/, output) + frame_traces = output.split("\n").select { |line| line.strip.match?(/from /) }.map(&:strip) + + expected_traces = [ + /from .*\/irbtest-.*.rb:6:in (`|'Object#)bar'/, + /from .*\/irbtest-.*.rb\(irb\):1:in [`']<main>'/, + /from .*\/irbtest-.*.rb:9:in [`']<main>'/ + ] + + expected_traces.reverse! if RUBY_VERSION < "3.0.0" + + expected_traces.each_with_index do |expected_trace, index| + assert_match(expected_trace, frame_traces[index]) + end + end + end end diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb index b798b897b4..17f73e4433 100644 --- a/test/objspace/test_objspace.rb +++ b/test/objspace/test_objspace.rb @@ -416,7 +416,7 @@ class TestObjSpace < Test::Unit::TestCase assert_equal('true', ObjectSpace.dump(true)) assert_equal('false', ObjectSpace.dump(false)) assert_equal('0', ObjectSpace.dump(0)) - assert_equal('{"type":"SYMBOL", "value":"foo"}', ObjectSpace.dump(:foo)) + assert_equal('{"type":"SYMBOL", "value":"test_dump_special_consts"}', ObjectSpace.dump(:test_dump_special_consts)) end def test_dump_singleton_class diff --git a/test/objspace/test_ractor.rb b/test/objspace/test_ractor.rb index b7008ea731..4901eeae2e 100644 --- a/test/objspace/test_ractor.rb +++ b/test/objspace/test_ractor.rb @@ -1,17 +1,17 @@ require "test/unit" class TestObjSpaceRactor < Test::Unit::TestCase - def test_tracing_does_not_crash - assert_ractor(<<~RUBY, require: 'objspace') - ObjectSpace.trace_object_allocations do - r = Ractor.new do - obj = 'a' * 1024 - Ractor.yield obj - end + def test_tracing_does_not_crash + assert_ractor(<<~RUBY, require: 'objspace') + ObjectSpace.trace_object_allocations do + r = Ractor.new do + obj = 'a' * 1024 + Ractor.yield obj + end - r.take - r.take - end - RUBY - end + r.take + r.take + end + RUBY + end end diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb index 8faa570648..41885fd59b 100644 --- a/test/openssl/test_cipher.rb +++ b/test/openssl/test_cipher.rb @@ -331,6 +331,22 @@ class OpenSSL::TestCipher < OpenSSL::TestCase assert_equal tag1, tag2 end + def test_aes_keywrap_pad + # RFC 5649 Section 6; The second example + kek = ["5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8"].pack("H*") + key = ["466f7250617369"].pack("H*") + wrap = ["afbeb0f07dfbf5419200f2ccb50bb24f"].pack("H*") + + begin + cipher = OpenSSL::Cipher.new("id-aes192-wrap-pad").encrypt + rescue OpenSSL::Cipher::CipherError, RuntimeError + omit "id-aes192-wrap-pad is not supported: #$!" + end + cipher.key = kek + ct = cipher.update(key) << cipher.final + assert_equal wrap, ct + end + def test_non_aead_cipher_set_auth_data assert_raise(OpenSSL::Cipher::CipherError) { cipher = OpenSSL::Cipher.new("aes-128-cfb").encrypt diff --git a/test/openssl/test_digest.rb b/test/openssl/test_digest.rb index b0b5b9bed1..988330e405 100644 --- a/test/openssl/test_digest.rb +++ b/test/openssl/test_digest.rb @@ -88,7 +88,7 @@ class OpenSSL::TestDigest < OpenSSL::TestCase end def test_sha512_truncate - pend "SHA512_224 is not implemented" unless digest_available?('SHA512-224') + pend "SHA512_224 is not implemented" unless digest_available?('sha512-224') sha512_224_a = "d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327" sha512_256_a = "455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8" @@ -100,7 +100,7 @@ class OpenSSL::TestDigest < OpenSSL::TestCase end def test_sha3 - pend "SHA3 is not implemented" unless digest_available?('SHA3-224') + pend "SHA3 is not implemented" unless digest_available?('sha3-224') s224 = '6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7' s256 = 'a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a' s384 = '0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004' @@ -126,6 +126,15 @@ class OpenSSL::TestDigest < OpenSSL::TestCase end end + def test_digests + digests = OpenSSL::Digest.digests + assert_kind_of Array, digests + assert_include digests, "md5" + assert_include digests, "sha1" + assert_include digests, "sha256" + assert_include digests, "sha512" + end + private def check_digest(oid) @@ -138,11 +147,8 @@ class OpenSSL::TestDigest < OpenSSL::TestCase end def digest_available?(name) - begin - OpenSSL::Digest.new(name) - rescue RuntimeError - false - end + @digests ||= OpenSSL::Digest.digests + @digests.include?(name) end end diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb index b616883925..66e36a7ab4 100644 --- a/test/openssl/test_pair.rb +++ b/test/openssl/test_pair.rb @@ -250,12 +250,17 @@ module OpenSSL::TestPairM buf = +"garbage" assert_equal :wait_readable, s2.read_nonblock(100, buf, exception: false) - assert_equal "", buf + assert_equal "garbage", buf s1.close buf = +"garbage" - assert_equal nil, s2.read(100, buf) + assert_nil s2.read(100, buf) assert_equal "", buf + + buf = +"garbage" + ret = s2.read(0, buf) + assert_same buf, ret + assert_equal "", ret } end diff --git a/test/openssl/test_pkcs7.rb b/test/openssl/test_pkcs7.rb index ba8b93d034..c049ed444a 100644 --- a/test/openssl/test_pkcs7.rb +++ b/test/openssl/test_pkcs7.rb @@ -155,6 +155,21 @@ class OpenSSL::TestPKCS7 < OpenSSL::TestCase assert_equal(data, p7.decrypt(@rsa1024)) end + def test_empty_signed_data_ruby_bug_19974 + data = "-----BEGIN PKCS7-----\nMAsGCSqGSIb3DQEHAg==\n-----END PKCS7-----\n" + assert_raise(ArgumentError) { OpenSSL::PKCS7.new(data) } + + data = <<END +MIME-Version: 1.0 +Content-Disposition: attachment; filename="smime.p7m" +Content-Type: application/x-pkcs7-mime; smime-type=signed-data; name="smime.p7m" +Content-Transfer-Encoding: base64 + +#{data} +END + assert_raise(OpenSSL::PKCS7::PKCS7Error) { OpenSSL::PKCS7.read_smime(data) } + end + def test_graceful_parsing_failure #[ruby-core:43250] contents = File.read(__FILE__) assert_raise(ArgumentError) { OpenSSL::PKCS7.new(contents) } @@ -212,6 +227,12 @@ END assert_equal(p7.to_der, OpenSSL::PKCS7.read_smime(smime).to_der) end + def test_to_text + p7 = OpenSSL::PKCS7.new + p7.type = "signed" + assert_match(/signed/, p7.to_text) + end + def test_degenerate_pkcs7 ca_cert_pem = <<END -----BEGIN CERTIFICATE----- diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb index 66d63a981d..1471b0cb36 100644 --- a/test/openssl/test_ssl.rb +++ b/test/openssl/test_ssl.rb @@ -117,6 +117,30 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase } end + def test_socket_close_write + server_proc = proc do |ctx, ssl| + message = ssl.read + ssl.write(message) + ssl.close_write + ensure + ssl.close + end + + start_server(server_proc: server_proc) do |port| + ctx = OpenSSL::SSL::SSLContext.new + ssl = OpenSSL::SSL::SSLSocket.open("127.0.0.1", port, context: ctx) + ssl.sync_close = true + ssl.connect + + message = "abc"*1024 + ssl.write message + ssl.close_write + assert_equal message, ssl.read + ensure + ssl&.close + end + end + def test_add_certificate ctx_proc = -> ctx { # Unset values set by start_server diff --git a/test/openssl/test_ts.rb b/test/openssl/test_ts.rb index 7cb1a1fe8e..ac0469ad56 100644 --- a/test/openssl/test_ts.rb +++ b/test/openssl/test_ts.rb @@ -323,6 +323,8 @@ _end_of_pem_ resp = fac.create_timestamp(ee_key, ts_cert_ee, req) assert_equal(OpenSSL::Timestamp::Response::GRANTED, resp.status) assert_equal("1.2.3.4.6", resp.token_info.policy_id) + + assert_match(/1\.2\.3\.4\.6/, resp.to_text) end def test_response_bad_purpose diff --git a/test/prism/comments_test.rb b/test/prism/comments_test.rb index b99c00268c..952d03239c 100644 --- a/test/prism/comments_test.rb +++ b/test/prism/comments_test.rb @@ -6,7 +6,7 @@ module Prism class CommentsTest < TestCase def test_comment_inline source = "# comment" - assert_equal [0], Debug.newlines(source) + assert_equal [0], Prism.parse(source).source.offsets assert_comment( source, diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb index f989daa361..5f4acb0120 100644 --- a/test/prism/errors_test.rb +++ b/test/prism/errors_test.rb @@ -99,7 +99,7 @@ module Prism ) assert_errors expected, "BEGIN { 1 + }", [ - ["expected an expression after the operator", 10..11], + ["unexpected '}'; expected an expression after the operator", 12..13], ["unexpected '}', assuming it is closing the parent 'BEGIN' block", 12..13] ] end @@ -117,25 +117,25 @@ module Prism def test_unterminated_i_list assert_errors expression("%i["), "%i[", [ - ["expected a closing delimiter for the `%i` list", 0..3] + ["unterminated list; expected a closing delimiter for the `%i`", 0..3] ] end def test_unterminated_w_list assert_errors expression("%w["), "%w[", [ - ["expected a closing delimiter for the `%w` list", 0..3] + ["unterminated list; expected a closing delimiter for the `%w`", 0..3] ] end def test_unterminated_W_list assert_errors expression("%W["), "%W[", [ - ["expected a closing delimiter for the `%W` list", 0..3] + ["unterminated list; expected a closing delimiter for the `%W`", 0..3] ] end def test_unterminated_regular_expression assert_errors expression("/hello"), "/hello", [ - ["expected a closing delimiter for the regular expression", 0..1] + ["unterminated regexp meets end of file; expected a closing delimiter", 0..1] ] end @@ -143,7 +143,7 @@ module Prism source = "<<-END + /b\nEND\n" assert_errors expression(source), source, [ - ["expected a closing delimiter for the regular expression", 9..10] + ["unterminated regexp meets end of file; expected a closing delimiter", 9..10] ] end @@ -189,14 +189,13 @@ module Prism def test_unterminated_s_symbol assert_errors expression("%s[abc"), "%s[abc", [ - ["expected a closing delimiter for the dynamic symbol", 0..3] + ["unterminated quoted string; expected a closing delimiter for the dynamic symbol", 0..3] ] end def test_unterminated_parenthesized_expression assert_errors expression('(1 + 2'), '(1 + 2', [ - ["unexpected end of file, expecting end-of-input", 6..6], - ["unexpected end of file, assuming it is closing the parent top level context", 6..6], + ["unexpected end-of-input, assuming it is closing the parent top level context", 6..6], ["expected a matching `)`", 6..6] ] end @@ -209,21 +208,21 @@ module Prism def test_unterminated_argument_expression assert_errors expression('a %'), 'a %', [ - ["invalid `%` token", 2..3], - ["expected an expression after the operator", 2..3], - ["unexpected end of file, assuming it is closing the parent top level context", 3..3] + ["unterminated quoted string meets end of file", 2..3], + ["unexpected end-of-input; expected an expression after the operator", 3..3], + ["unexpected end-of-input, assuming it is closing the parent top level context", 3..3] ] end def test_unterminated_interpolated_symbol assert_error_messages ":\"#", [ - "expected a closing delimiter for the interpolated symbol" + "unterminated symbol; expected a closing delimiter for the interpolated symbol" ] end def test_cr_without_lf_in_percent_expression assert_errors expression("%\r"), "%\r", [ - ["invalid `%` token", 0..2], + ["unterminated string meets end of file", 2..2], ] end @@ -365,7 +364,7 @@ module Prism assert_error_messages "x.each { x end", [ "unexpected 'end', expecting end-of-input", "unexpected 'end', ignoring it", - "unexpected end of file, assuming it is closing the parent top level context", + "unexpected end-of-input, assuming it is closing the parent top level context", "expected a block beginning with `{` to end with `}`" ] end @@ -378,10 +377,13 @@ module Prism :a, Location(), Location(), - ArgumentsNode(1, [ - KeywordHashNode(0, [AssocSplatNode(expression("kwargs"), Location())]), - SplatNode(Location(), expression("args")) - ]), + ArgumentsNode( + ArgumentsNodeFlags::CONTAINS_KEYWORDS | ArgumentsNodeFlags::CONTAINS_KEYWORD_SPLAT, + [ + KeywordHashNode(0, [AssocSplatNode(expression("kwargs"), Location())]), + SplatNode(Location(), expression("args")) + ] + ), Location(), nil ) @@ -425,7 +427,7 @@ module Prism :a, Location(), Location(), - ArgumentsNode(0, [ + ArgumentsNode(ArgumentsNodeFlags::CONTAINS_KEYWORDS, [ KeywordHashNode(1, [ AssocNode( SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, nil, Location(), Location(), "foo"), @@ -690,13 +692,13 @@ module Prism expected = StringNode(StringFlags::FORCED_UTF8_ENCODING, Location(), Location(), nil, "\u0001\u0002") assert_errors expected, '?\u{0001 0002}', [ - ["invalid Unicode escape sequence; multiple codepoints are not allowed in a character literal", 9..12] + ["invalid Unicode escape sequence; Multiple codepoints at single character literal are disallowed", 9..12] ] end def test_invalid_hex_escape assert_errors expression('"\\xx"'), '"\\xx"', [ - ["invalid hexadecimal escape sequence", 1..3], + ["invalid hex escape sequence", 1..3], ] end @@ -713,12 +715,13 @@ module Prism assert_errors expected, '"\u{000z}"', [ ["invalid Unicode escape sequence", 7..7], + ["unterminated Unicode escape", 7..7] ] end def test_unterminated_unicode_brackets_should_be_a_syntax_error assert_errors expression('?\\u{3'), '?\\u{3', [ - ["invalid Unicode escape sequence; needs closing `}`", 1..5], + ["unterminated Unicode escape", 1..5], ] end @@ -861,7 +864,7 @@ module Prism :foo, Location(), nil, - ParametersNode([], [], nil, [], [], ForwardingParameterNode(), nil), + ParametersNode([], [], nil, [ForwardingParameterNode()], [], ForwardingParameterNode(), nil), nil, [], Location(), @@ -1238,7 +1241,7 @@ module Prism expected = CallNode(0, receiver, Location(), :foo, Location(), nil, nil, nil, nil) assert_errors expected, "<<~FOO.foo\n", [ - ["could not find a terminator for the heredoc", 11..11] + ["unterminated heredoc; can't find string \"FOO\" anywhere before EOF", 3..6] ] end @@ -1353,14 +1356,14 @@ module Prism if RUBY_VERSION >= "3.0" def test_writing_numbered_parameter - assert_errors expression("-> { _1 = 0 }"), "-> { _1 = 0 }", [ - ["_1 is reserved for numbered parameters", 5..7] + assert_error_messages "-> { _1 = 0 }", [ + "_1 is reserved for numbered parameters" ] end def test_targeting_numbered_parameter - assert_errors expression("-> { _1, = 0 }"), "-> { _1, = 0 }", [ - ["_1 is reserved for numbered parameters", 5..7] + assert_error_messages "-> { _1, = 0 }", [ + "_1 is reserved for numbered parameters" ] end @@ -1374,14 +1377,13 @@ module Prism def test_double_scope_numbered_parameters source = "-> { _1 + -> { _2 } }" - errors = [["numbered parameter is already used in outer scope", 15..17]] + errors = [["numbered parameter is already used in outer block", 15..17]] assert_errors expression(source), source, errors end def test_invalid_number_underscores error_messages = ["invalid underscore placement in number"] - assert_error_messages "1__1", error_messages assert_error_messages "0b1__1", error_messages assert_error_messages "0o1__1", error_messages @@ -1389,6 +1391,7 @@ module Prism assert_error_messages "0d1__1", error_messages assert_error_messages "0x1__1", error_messages + error_messages = ["trailing '_' in number"] assert_error_messages "1_1_", error_messages assert_error_messages "0b1_1_", error_messages assert_error_messages "0o1_1_", error_messages @@ -1398,7 +1401,7 @@ module Prism end def test_alnum_delimiters - error_messages = ["invalid `%` token"] + error_messages = ["unknown type of %string"] assert_error_messages "%qXfooX", error_messages assert_error_messages "%QXfooX", error_messages @@ -1463,7 +1466,7 @@ module Prism def test_forwarding_arg_after_keyword_rest source = "def f(**,...);end" assert_errors expression(source), source, [ - ["unexpected `...` in parameters", 9..12], + ["unexpected parameter order", 9..12] ] end @@ -1479,8 +1482,7 @@ module Prism assert_errors expression(source), source, [ ["expected a `do` keyword or a `{` to open the lambda block", 3..3], - ["unexpected end of file, expecting end-of-input", 7..7], - ["unexpected end of file, assuming it is closing the parent top level context", 7..7], + ["unexpected end-of-input, assuming it is closing the parent top level context", 7..7], ["expected a lambda block beginning with `do` to end with `end`", 7..7] ] end @@ -1538,7 +1540,7 @@ module Prism assert_errors expression(source), source, [ ["expected a predicate expression for the `while` statement", 22..22], - ["unexpected end of file, assuming it is closing the parent top level context", 22..22], + ["unexpected end-of-input, assuming it is closing the parent top level context", 22..22], ["expected an `end` to close the `while` statement", 22..22] ] end @@ -1628,6 +1630,41 @@ module Prism ] end + def test_void_value_expression_in_begin_statement + source = <<~RUBY + x = return 1 + x = return, 1 + x = 1, return + x, y = return + x = begin return ensure end + x = begin ensure return end + x = begin return ensure return end + x = begin return; rescue; return end + x = begin return; rescue; return; else return end + x = begin; return; rescue; retry; end + RUBY + + message = 'unexpected void value expression' + assert_errors expression(source), source, [ + [message, 4..12], + [message, 17..23], + [message, 34..40], + [message, 48..54], + [message, 65..71], + [message, 100..106], + [message, 121..127], + [message, 156..162], + [message, 222..228], + [message, 244..250], + ] + + refute_error_messages("x = begin return; rescue; end") + refute_error_messages("x = begin return; rescue; return; else end") + refute_error_messages("x = begin; rescue; retry; end") + refute_error_messages("x = begin 1; rescue; retry; ensure; end") + refute_error_messages("x = begin 1; rescue; return; end") + end + def test_void_value_expression_in_def source = <<~RUBY def (return).x @@ -1939,10 +1976,10 @@ module Prism RUBY assert_errors expression(source), source, [ - ["unexpected '..', expecting end-of-input", 3..5], - ["unexpected '..', ignoring it", 3..5], - ["unexpected '..', expecting end-of-input", 10..12], - ["unexpected '..', ignoring it", 10..12] + ["unexpected .., expecting end-of-input", 3..5], + ["unexpected .., ignoring it", 3..5], + ["unexpected .., expecting end-of-input", 10..12], + ["unexpected .., ignoring it", 10..12] ] end @@ -2079,7 +2116,7 @@ module Prism def test_forwarding_arg_and_block source = 'def foo(...) = foo(...) { }' assert_errors expression(source), source, [ - ['both a block argument and a forwarding argument; only one block is allowed', 24..27] + ['both block arg and actual block given; only one block is allowed', 24..27] ] end diff --git a/test/prism/format_errors_test.rb b/test/prism/format_errors_test.rb deleted file mode 100644 index a1edbef2e8..0000000000 --- a/test/prism/format_errors_test.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -require_relative "test_helper" - -return if Prism::BACKEND == :FFI - -module Prism - class FormatErrorsTest < TestCase - def test_format_errors - assert_equal <<~ERROR, Debug.format_errors("<>", false) - > 1 | <> - | ^ unexpected '<', ignoring it - | ^ unexpected '>', ignoring it - ERROR - - assert_equal <<~'ERROR', Debug.format_errors('"%W"\u"', false) - > 1 | "%W"\u" - | ^ unexpected backslash, ignoring it - | ^ unexpected local variable or method, expecting end-of-input - | ^ unterminated string meets end of file - ERROR - end - end -end diff --git a/test/prism/index_write_test.rb b/test/prism/index_write_test.rb index 1c6f7bce89..cf90eb082f 100644 --- a/test/prism/index_write_test.rb +++ b/test/prism/index_write_test.rb @@ -4,7 +4,7 @@ require_relative "test_helper" module Prism class IndexWriteTest < TestCase - def test_keywords_3_3_0 + def test_keywords_3_3 assert_parse_success(<<~RUBY, "3.3.0") foo[bar: 1] = 1 foo[bar: 1] &&= 1 @@ -22,7 +22,7 @@ module Prism RUBY end - def test_block_3_3_0 + def test_block_3_3 assert_parse_success(<<~RUBY, "3.3.0") foo[&bar] = 1 foo[&bar] &&= 1 @@ -40,41 +40,41 @@ module Prism RUBY end - # def test_keywords_latest - # assert_parse_failure(<<~RUBY) - # foo[bar: 1] = 1 - # foo[bar: 1] &&= 1 - # foo[bar: 1] ||= 1 - # foo[bar: 1] += 1 - # RUBY + def test_keywords_latest + assert_parse_failure(<<~RUBY) + foo[bar: 1] = 1 + foo[bar: 1] &&= 1 + foo[bar: 1] ||= 1 + foo[bar: 1] += 1 + RUBY - # assert_parse_failure(<<~RUBY) - # def foo(**) - # bar[**] = 1 - # bar[**] &&= 1 - # bar[**] ||= 1 - # bar[**] += 1 - # end - # RUBY - # end + assert_parse_failure(<<~RUBY) + def foo(**) + bar[**] = 1 + bar[**] &&= 1 + bar[**] ||= 1 + bar[**] += 1 + end + RUBY + end - # def test_block_latest - # assert_parse_failure(<<~RUBY) - # foo[&bar] = 1 - # foo[&bar] &&= 1 - # foo[&bar] ||= 1 - # foo[&bar] += 1 - # RUBY + def test_block_latest + assert_parse_failure(<<~RUBY) + foo[&bar] = 1 + foo[&bar] &&= 1 + foo[&bar] ||= 1 + foo[&bar] += 1 + RUBY - # assert_parse_failure(<<~RUBY) - # def foo(&) - # bar[&] = 1 - # bar[&] &&= 1 - # bar[&] ||= 1 - # bar[&] += 1 - # end - # RUBY - # end + assert_parse_failure(<<~RUBY) + def foo(&) + bar[&] = 1 + bar[&] &&= 1 + bar[&] ||= 1 + bar[&] += 1 + end + RUBY + end private diff --git a/test/prism/integer_parse_test.rb b/test/prism/integer_parse_test.rb index f42e817e79..11aee174c5 100644 --- a/test/prism/integer_parse_test.rb +++ b/test/prism/integer_parse_test.rb @@ -2,8 +2,6 @@ require_relative "test_helper" -return if Prism::BACKEND == :FFI - module Prism class IntegerParseTest < TestCase def test_integer_parse @@ -37,9 +35,7 @@ module Prism private def assert_integer_parse(expected, source = expected.to_s) - integer, string = Debug.integer_parse(source) - assert_equal expected, integer - assert_equal expected.to_s, string + assert_equal expected, Prism.parse(source).value.statements.body.first.value end end end diff --git a/test/prism/locals_test.rb b/test/prism/locals_test.rb index 0eb73f1b9c..0e57a9a80c 100644 --- a/test/prism/locals_test.rb +++ b/test/prism/locals_test.rb @@ -41,8 +41,8 @@ module Prism def assert_locals(filepath) source = File.read(filepath) - expected = Debug.cruby_locals(source) - actual = Debug.prism_locals(source) + expected = cruby_locals(source) + actual = prism_locals(source) assert_equal(expected, actual) end @@ -54,5 +54,186 @@ module Prism ensure $VERBOSE = previous_verbosity end + + # A wrapper around a RubyVM::InstructionSequence that provides a more + # convenient interface for accessing parts of the iseq. + class ISeq + attr_reader :parts + + def initialize(parts) + @parts = parts + end + + def type + parts[0] + end + + def local_table + parts[10] + end + + def instructions + parts[13] + end + + def each_child + instructions.each do |instruction| + # Only look at arrays. Other instructions are line numbers or + # tracepoint events. + next unless instruction.is_a?(Array) + + instruction.each do |opnd| + # Only look at arrays. Other operands are literals. + next unless opnd.is_a?(Array) + + # Only look at instruction sequences. Other operands are literals. + next unless opnd[0] == "YARVInstructionSequence/SimpleDataFormat" + + yield ISeq.new(opnd) + end + end + end + end + + # Used to hold the place of a local that will be in the local table but + # cannot be accessed directly from the source code. For example, the + # iteration variable in a for loop or the positional parameter on a method + # definition that is destructured. + AnonymousLocal = Object.new + + # For the given source, compiles with CRuby and returns a list of all of the + # sets of local variables that were encountered. + def cruby_locals(source) + verbose, $VERBOSE = $VERBOSE, nil + + begin + locals = [] #: Array[Array[Symbol | Integer]] + stack = [ISeq.new(RubyVM::InstructionSequence.compile(source).to_a)] + + while (iseq = stack.pop) + names = [*iseq.local_table] + names.map!.with_index do |name, index| + # When an anonymous local variable is present in the iseq's local + # table, it is represented as the stack offset from the top. + # However, when these are dumped to binary and read back in, they + # are replaced with the symbol :#arg_rest. To consistently handle + # this, we replace them here with their index. + if name == :"#arg_rest" + names.length - index + 1 + else + name + end + end + + locals << names + iseq.each_child { |child| stack << child } + end + + locals + ensure + $VERBOSE = verbose + end + end + + # For the given source, parses with prism and returns a list of all of the + # sets of local variables that were encountered. + def prism_locals(source) + locals = [] #: Array[Array[Symbol | Integer]] + stack = [Prism.parse(source).value] #: Array[Prism::node] + + while (node = stack.pop) + case node + when BlockNode, DefNode, LambdaNode + names = node.locals + params = + if node.is_a?(DefNode) + node.parameters + elsif node.parameters.is_a?(NumberedParametersNode) + nil + else + node.parameters&.parameters + end + + # prism places parameters in the same order that they appear in the + # source. CRuby places them in the order that they need to appear + # according to their own internal calling convention. We mimic that + # order here so that we can compare properly. + if params + sorted = [ + *params.requireds.map do |required| + if required.is_a?(RequiredParameterNode) + required.name + else + AnonymousLocal + end + end, + *params.optionals.map(&:name), + *((params.rest.name || :*) if params.rest && !params.rest.is_a?(ImplicitRestNode)), + *params.posts.map do |post| + if post.is_a?(RequiredParameterNode) + post.name + else + AnonymousLocal + end + end, + *params.keywords.grep(RequiredKeywordParameterNode).map(&:name), + *params.keywords.grep(OptionalKeywordParameterNode).map(&:name), + ] + + sorted << AnonymousLocal if params.keywords.any? + + if params.keyword_rest.is_a?(ForwardingParameterNode) + sorted.push(:*, :**, :&, :"...") + elsif params.keyword_rest.is_a?(KeywordRestParameterNode) + sorted << (params.keyword_rest.name || :**) + end + + # Recurse down the parameter tree to find any destructured + # parameters and add them after the other parameters. + param_stack = params.requireds.concat(params.posts).grep(MultiTargetNode).reverse + while (param = param_stack.pop) + case param + when MultiTargetNode + param_stack.concat(param.rights.reverse) + param_stack << param.rest if param.rest&.expression && !sorted.include?(param.rest.expression.name) + param_stack.concat(param.lefts.reverse) + when RequiredParameterNode + sorted << param.name + when SplatNode + sorted << param.expression.name + end + end + + if params.block + sorted << (params.block.name || :&) + end + + names = sorted.concat(names - sorted) + end + + names.map!.with_index do |name, index| + if name == AnonymousLocal + names.length - index + 1 + else + name + end + end + + locals << names + when ClassNode, ModuleNode, ProgramNode, SingletonClassNode + locals << node.locals + when ForNode + locals << [2] + when PostExecutionNode + locals.push([], []) + when InterpolatedRegularExpressionNode + locals << [] if node.once? + end + + stack.concat(node.compact_child_nodes) + end + + locals + end end end diff --git a/test/prism/location_test.rb b/test/prism/location_test.rb index 81417fbcb3..256e5b41e4 100644 --- a/test/prism/location_test.rb +++ b/test/prism/location_test.rb @@ -175,14 +175,6 @@ module Prism assert_location(CallNode, "foo bar baz") assert_location(CallNode, "foo bar('baz')") - - assert_location(CallNode, "-> { it }", 5...7, version: "3.3.0") do |node| - node.body.body.first - end - - assert_location(LocalVariableReadNode, "-> { it }", 5...7, version: "3.4.0") do |node| - node.body.body.first - end end def test_CallAndWriteNode @@ -298,7 +290,6 @@ module Prism def test_ConstantReadNode assert_location(ConstantReadNode, "Foo") - assert_location(ConstantReadNode, "Foo::Bar", 5...8, &:child) end def test_ConstantTargetNode @@ -478,7 +469,7 @@ module Prism end def test_IndexTargetNode - assert_location(IndexTargetNode, "foo[bar, &baz], = qux", 0...14) do |node| + assert_location(IndexTargetNode, "foo[bar], = qux", 0...8) do |node| node.lefts.first end end @@ -544,6 +535,24 @@ module Prism assert_location(InterpolatedXStringNode, '`foo #{bar} baz`') end + def test_ItLocalVariableReadNode + assert_location(ItLocalVariableReadNode, "-> { it }", 5...7) do |node| + node.body.body.first + end + + assert_location(ItLocalVariableReadNode, "foo { it }", 6...8) do |node| + node.block.body.body.first + end + + assert_location(CallNode, "-> { it }", 5...7, version: "3.3.0") do |node| + node.body.body.first + end + + assert_location(ItLocalVariableReadNode, "-> { it }", 5...7, version: "3.4.0") do |node| + node.body.body.first + end + end + def test_ItParametersNode assert_location(ItParametersNode, "-> { it }", &:parameters) end @@ -584,12 +593,6 @@ module Prism def test_LocalVariableReadNode assert_location(LocalVariableReadNode, "foo = 1; foo", 9...12) - assert_location(LocalVariableReadNode, "-> { it }", 5...7) do |node| - node.body.body.first - end - assert_location(LocalVariableReadNode, "foo { it }", 6...8) do |node| - node.block.body.body.first - end end def test_LocalVariableTargetNode diff --git a/test/prism/memsize_test.rb b/test/prism/memsize_test.rb deleted file mode 100644 index d7e1448dbc..0000000000 --- a/test/prism/memsize_test.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require_relative "test_helper" - -return if Prism::BACKEND == :FFI - -module Prism - class MemsizeTest < TestCase - def test_memsize - result = Debug.memsize("2 + 3") - - assert_equal 5, result[:length] - assert_kind_of Integer, result[:memsize] - assert_equal 6, result[:node_count] - end - end -end diff --git a/test/prism/newline_test.rb b/test/prism/newline_test.rb index e9975b346e..75593d34bf 100644 --- a/test/prism/newline_test.rb +++ b/test/prism/newline_test.rb @@ -7,7 +7,16 @@ return unless defined?(RubyVM::InstructionSequence) module Prism class NewlineTest < TestCase base = File.expand_path("../", __FILE__) - filepaths = Dir["*.rb", base: base] - %w[encoding_test.rb errors_test.rb parser_test.rb static_literals_test.rb unescape_test.rb] + filepaths = Dir["*.rb", base: base] - %w[ + encoding_test.rb + errors_test.rb + locals_test.rb + parser_test.rb + regexp_test.rb + static_literals_test.rb + unescape_test.rb + warnings_test.rb + ] filepaths.each do |relative| define_method("test_newline_flags_#{relative}") do diff --git a/test/prism/parse_test.rb b/test/prism/parse_test.rb index afb53e0668..5c66caebb9 100644 --- a/test/prism/parse_test.rb +++ b/test/prism/parse_test.rb @@ -265,7 +265,7 @@ module Prism # Next, assert that the newlines are in the expected places. expected_newlines = [0] source.b.scan("\n") { expected_newlines << $~.offset(0)[0] + 1 } - assert_equal expected_newlines, Debug.newlines(source) + assert_equal expected_newlines, Prism.parse(source).source.offsets if ripper_should_match # Finally, assert that we can lex the source and get the same tokens as diff --git a/test/prism/regexp_test.rb b/test/prism/regexp_test.rb index 0a5fc2b4fc..35be217f79 100644 --- a/test/prism/regexp_test.rb +++ b/test/prism/regexp_test.rb @@ -2,78 +2,84 @@ require_relative "test_helper" -return if Prism::BACKEND == :FFI - module Prism class RegexpTest < TestCase - ############################################################################## + ############################################################################ # These tests test the actual use case of extracting named capture groups - ############################################################################## + ############################################################################ def test_named_captures_with_arrows - assert_equal(["foo"], named_captures("(?<foo>bar)")) + assert_equal([:foo], named_captures("(?<foo>bar)")) end def test_named_captures_with_single_quotes - assert_equal(["foo"], named_captures("(?'foo'bar)")) + assert_equal([:foo], named_captures("(?'foo'bar)")) end def test_nested_named_captures_with_arrows - assert_equal(["foo", "bar"], named_captures("(?<foo>(?<bar>baz))")) + assert_equal([:foo, :bar], named_captures("(?<foo>(?<bar>baz))")) end def test_nested_named_captures_with_single_quotes - assert_equal(["foo", "bar"], named_captures("(?'foo'(?'bar'baz))")) + assert_equal([:foo, :bar], named_captures("(?'foo'(?'bar'baz))")) end def test_allows_duplicate_named_captures - assert_equal(["foo", "foo"], named_captures("(?<foo>bar)(?<foo>baz)")) + assert_equal([:foo], named_captures("(?<foo>bar)(?<foo>baz)")) end def test_named_capture_inside_fake_range_quantifier - assert_equal(["foo"], named_captures("foo{1, (?<foo>2)}")) + assert_equal([:foo], named_captures("foo{1, (?<foo>2)}")) + end + + def test_fake_named_captures_inside_character_sets + assert_equal([], named_captures("[a-z(?<foo>)]")) end - ############################################################################## + def test_fake_named_capture_inside_character_set_with_escaped_ending + assert_equal([], named_captures("[a-z\\](?<foo>)]")) + end + + ############################################################################ # These tests test the rest of the AST. They are not exhaustive, but they # should cover the most common cases. We test these to make sure we don't # accidentally regress and stop being able to extract named captures. - ############################################################################## + ############################################################################ def test_alternation - refute_nil(named_captures("foo|bar")) + assert_valid_regexp("foo|bar") end def test_anchors - refute_nil(named_captures("^foo$")) + assert_valid_regexp("^foo$") end def test_any - refute_nil(named_captures(".")) + assert_valid_regexp(".") end def test_posix_character_classes - refute_nil(named_captures("[[:digit:]]")) + assert_valid_regexp("[[:digit:]]") end def test_negated_posix_character_classes - refute_nil(named_captures("[[:^digit:]]")) + assert_valid_regexp("[[:^digit:]]") end def test_invalid_posix_character_classes_should_fall_back_to_regular_classes - refute_nil(named_captures("[[:foo]]")) + assert_valid_regexp("[[:foo]]") end def test_character_sets - refute_nil(named_captures("[abc]")) + assert_valid_regexp("[abc]") end def test_nested_character_sets - refute_nil(named_captures("[[abc]]")) + assert_valid_regexp("[[abc]]") end def test_nested_character_sets_with_operators - refute_nil(named_captures("[[abc] && [def]]")) + assert_valid_regexp("[[abc] && [def]]") end def test_named_capture_inside_nested_character_set @@ -81,120 +87,108 @@ module Prism end def test_negated_character_sets - refute_nil(named_captures("[^abc]")) + assert_valid_regexp("[^abc]") end def test_character_ranges - refute_nil(named_captures("[a-z]")) + assert_valid_regexp("[a-z]") end def test_negated_character_ranges - refute_nil(named_captures("[^a-z]")) - end - - def test_fake_named_captures_inside_character_sets - assert_equal([], named_captures("[a-z(?<foo>)]")) - end - - def test_fake_named_capture_inside_character_set_with_escaped_ending - assert_equal([], named_captures("[a-z\\](?<foo>)]")) + assert_valid_regexp("[^a-z]") end def test_comments - refute_nil(named_captures("(?#foo)")) + assert_valid_regexp("(?#foo)") end def test_comments_with_escaped_parentheses - refute_nil(named_captures("(?#foo\\)\\))")) + assert_valid_regexp("(?#foo\\)\\))") end def test_non_capturing_groups - refute_nil(named_captures("(?:foo)")) + assert_valid_regexp("(?:foo)") end def test_positive_lookaheads - refute_nil(named_captures("(?=foo)")) + assert_valid_regexp("(?=foo)") end def test_negative_lookaheads - refute_nil(named_captures("(?!foo)")) + assert_valid_regexp("(?!foo)") end def test_positive_lookbehinds - refute_nil(named_captures("(?<=foo)")) + assert_valid_regexp("(?<=foo)") end def test_negative_lookbehinds - refute_nil(named_captures("(?<!foo)")) + assert_valid_regexp("(?<!foo)") end def test_atomic_groups - refute_nil(named_captures("(?>foo)")) + assert_valid_regexp("(?>foo)") end def test_absence_operator - refute_nil(named_captures("(?~foo)")) + assert_valid_regexp("(?~foo)") end def test_conditional_expression_with_index - refute_nil(named_captures("(?(1)foo)")) + assert_valid_regexp("(?(1)foo)") end def test_conditional_expression_with_name - refute_nil(named_captures("(?(foo)bar)")) + assert_valid_regexp("(?(foo)bar)") end def test_conditional_expression_with_group - refute_nil(named_captures("(?(<foo>)bar)")) + assert_valid_regexp("(?(<foo>)bar)") end def test_options_on_groups - refute_nil(named_captures("(?imxdau:foo)")) - end - - def test_options_on_groups_with_invalid_options - assert_nil(named_captures("(?z:bar)")) + assert_valid_regexp("(?imxdau:foo)") end def test_options_on_groups_getting_turned_off - refute_nil(named_captures("(?-imx:foo)")) + assert_valid_regexp("(?-imx:foo)") end def test_options_on_groups_some_getting_turned_on_some_getting_turned_off - refute_nil(named_captures("(?im-x:foo)")) + assert_valid_regexp("(?im-x:foo)") end def test_star_quantifier - refute_nil(named_captures("foo*")) + assert_valid_regexp("foo*") end def test_plus_quantifier - refute_nil(named_captures("foo+")) + assert_valid_regexp("foo+") end def test_question_mark_quantifier - refute_nil(named_captures("foo?")) + assert_valid_regexp("foo?") end def test_endless_range_quantifier - refute_nil(named_captures("foo{1,}")) + assert_valid_regexp("foo{1,}") end def test_beginless_range_quantifier - refute_nil(named_captures("foo{,1}")) + assert_valid_regexp("foo{,1}") end def test_range_quantifier - refute_nil(named_captures("foo{1,2}")) + assert_valid_regexp("foo{1,2}") end def test_fake_range_quantifier_because_of_spaces - refute_nil(named_captures("foo{1, 2}")) + assert_valid_regexp("foo{1, 2}") end - ############################################################################## + ############################################################################ # These test that flag values are correct. - ############################################################################## + ############################################################################ def test_flag_ignorecase assert_equal(Regexp::IGNORECASE, options("i")) @@ -241,8 +235,12 @@ module Prism private + def assert_valid_regexp(source) + assert Prism.parse_success?("/#{source}/ =~ \"\"") + end + def named_captures(source) - Debug.named_captures(source) + Prism.parse("/#{source}/ =~ \"\"").value.locals end def options(flags) diff --git a/test/prism/ruby_api_test.rb b/test/prism/ruby_api_test.rb index 9e408d1edd..a1e2592d3d 100644 --- a/test/prism/ruby_api_test.rb +++ b/test/prism/ruby_api_test.rb @@ -266,6 +266,38 @@ module Prism refute_operator parse_expression(complex_source_1), :===, parse_expression(complex_source_2) end + def test_node_tunnel + program = Prism.parse("foo(1) +\n bar(2, 3) +\n baz(3, 4, 5)").value + + tunnel = program.tunnel(1, 4).last + assert_kind_of IntegerNode, tunnel + assert_equal 1, tunnel.value + + tunnel = program.tunnel(2, 6).last + assert_kind_of IntegerNode, tunnel + assert_equal 2, tunnel.value + + tunnel = program.tunnel(3, 9).last + assert_kind_of IntegerNode, tunnel + assert_equal 4, tunnel.value + + tunnel = program.tunnel(3, 8) + assert_equal [ProgramNode, StatementsNode, CallNode, ArgumentsNode, CallNode, ArgumentsNode], tunnel.map(&:class) + end + + def test_location_adjoin + program = Prism.parse("foo.bar = 1").value + + location = program.statements.body.first.message_loc + adjoined = location.adjoin("=") + + assert_kind_of Location, adjoined + refute_equal location, adjoined + + assert_equal 4, adjoined.start_offset + assert_equal 9, adjoined.end_offset + end + private def parse_expression(source) diff --git a/test/prism/ruby_parser_test.rb b/test/prism/ruby_parser_test.rb index 8edeac4b4f..0fd96d42b5 100644 --- a/test/prism/ruby_parser_test.rb +++ b/test/prism/ruby_parser_test.rb @@ -28,28 +28,21 @@ module Prism base = File.join(__dir__, "fixtures") todos = %w[ - heredocs_nested.txt newline_terminated.txt regex_char_width.txt seattlerb/bug169.txt - seattlerb/dstr_evstr.txt - seattlerb/heredoc_squiggly_interp.txt seattlerb/masgn_colon3.txt seattlerb/messy_op_asgn_lineno.txt seattlerb/op_asgn_primary_colon_const_command_call.txt - seattlerb/parse_line_evstr_after_break.txt seattlerb/regexp_esc_C_slash.txt seattlerb/str_lit_concat_bad_encodings.txt - seattlerb/str_pct_nested_nested.txt unescaping.txt unparser/corpus/literal/kwbegin.txt unparser/corpus/literal/send.txt - unparser/corpus/semantic/dstr.txt whitequark/masgn_const.txt whitequark/ruby_bug_12402.txt whitequark/ruby_bug_14690.txt whitequark/space_args_block.txt - whitequark/string_concat.txt ] # https://github.com/seattlerb/ruby_parser/issues/344 @@ -76,12 +69,10 @@ module Prism tilde_heredocs.txt unparser/corpus/literal/literal.txt while.txt - whitequark/class_definition_in_while_cond.txt whitequark/cond_eflipflop.txt whitequark/cond_iflipflop.txt whitequark/cond_match_current_line.txt whitequark/dedenting_heredoc.txt - whitequark/if_while_after_class__since_32.txt whitequark/lvar_injecting_match.txt whitequark/not.txt whitequark/numparam_ruby_bug_19025.txt diff --git a/test/prism/snapshots/arrays.txt b/test/prism/snapshots/arrays.txt index e8e53aacb9..90a4d8f3bb 100644 --- a/test/prism/snapshots/arrays.txt +++ b/test/prism/snapshots/arrays.txt @@ -960,8 +960,8 @@ │ ├── arguments: ∅ │ ├── closing_loc: (84,4)-(84,5) = "]" │ ├── block: ∅ - │ ├── operator: :+ - │ ├── operator_loc: (84,6)-(84,8) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (84,6)-(84,8) = "+=" │ └── value: │ @ IntegerNode (location: (84,9)-(84,10)) │ ├── flags: decimal @@ -1040,8 +1040,8 @@ │ ├── arguments: ∅ │ ├── closing_loc: (90,8)-(90,9) = "]" │ ├── block: ∅ - │ ├── operator: :+ - │ ├── operator_loc: (90,10)-(90,12) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (90,10)-(90,12) = "+=" │ └── value: │ @ IntegerNode (location: (90,13)-(90,14)) │ ├── flags: decimal @@ -1143,8 +1143,8 @@ │ │ └── block: ∅ │ ├── closing_loc: (96,7)-(96,8) = "]" │ ├── block: ∅ - │ ├── operator: :+ - │ ├── operator_loc: (96,9)-(96,11) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (96,9)-(96,11) = "+=" │ └── value: │ @ IntegerNode (location: (96,12)-(96,13)) │ ├── flags: decimal @@ -1262,8 +1262,8 @@ │ │ └── block: ∅ │ ├── closing_loc: (102,11)-(102,12) = "]" │ ├── block: ∅ - │ ├── operator: :+ - │ ├── operator_loc: (102,13)-(102,15) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (102,13)-(102,15) = "+=" │ └── value: │ @ IntegerNode (location: (102,16)-(102,17)) │ ├── flags: decimal @@ -1633,8 +1633,8 @@ │ │ │ └── expression: ∅ │ │ ├── closing_loc: (116,13)-(116,14) = "]" │ │ ├── block: ∅ - │ │ ├── operator: :+ - │ │ ├── operator_loc: (116,15)-(116,17) = "+=" + │ │ ├── binary_operator: :+ + │ │ ├── binary_operator_loc: (116,15)-(116,17) = "+=" │ │ └── value: │ │ @ IntegerNode (location: (116,18)-(116,19)) │ │ ├── flags: decimal diff --git a/test/prism/snapshots/blocks.txt b/test/prism/snapshots/blocks.txt index 0b1ec52e38..1c996ebd09 100644 --- a/test/prism/snapshots/blocks.txt +++ b/test/prism/snapshots/blocks.txt @@ -158,13 +158,13 @@ │ │ └── body: (length: 1) │ │ └── @ LocalVariableOperatorWriteNode (location: (7,24)-(7,33)) │ │ ├── name_loc: (7,24)-(7,28) = "memo" - │ │ ├── operator_loc: (7,29)-(7,31) = "+=" + │ │ ├── binary_operator_loc: (7,29)-(7,31) = "+=" │ │ ├── value: │ │ │ @ LocalVariableReadNode (location: (7,32)-(7,33)) │ │ │ ├── name: :x │ │ │ └── depth: 0 │ │ ├── name: :memo - │ │ ├── operator: :+ + │ │ ├── binary_operator: :+ │ │ └── depth: 0 │ ├── opening_loc: (7,12)-(7,13) = "{" │ └── closing_loc: (7,34)-(7,35) = "}" diff --git a/test/prism/snapshots/boolean_operators.txt b/test/prism/snapshots/boolean_operators.txt index ace8047e18..3bf33430c9 100644 --- a/test/prism/snapshots/boolean_operators.txt +++ b/test/prism/snapshots/boolean_operators.txt @@ -21,7 +21,7 @@ │ └── depth: 0 ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,6)) │ ├── name_loc: (3,0)-(3,1) = "a" - │ ├── operator_loc: (3,2)-(3,4) = "+=" + │ ├── binary_operator_loc: (3,2)-(3,4) = "+=" │ ├── value: │ │ @ CallNode (location: (3,5)-(3,6)) │ │ ├── flags: variable_call, ignore_visibility @@ -34,7 +34,7 @@ │ │ ├── closing_loc: ∅ │ │ └── block: ∅ │ ├── name: :a - │ ├── operator: :+ + │ ├── binary_operator: :+ │ └── depth: 0 └── @ LocalVariableOrWriteNode (location: (5,0)-(5,7)) ├── name_loc: (5,0)-(5,1) = "a" diff --git a/test/prism/snapshots/constants.txt b/test/prism/snapshots/constants.txt index 59e234148a..1251833663 100644 --- a/test/prism/snapshots/constants.txt +++ b/test/prism/snapshots/constants.txt @@ -7,24 +7,21 @@ │ ├── parent: │ │ @ ConstantReadNode (location: (1,0)-(1,1)) │ │ └── name: :A - │ ├── child: - │ │ @ ConstantReadNode (location: (1,3)-(1,4)) - │ │ └── name: :B - │ └── delimiter_loc: (1,1)-(1,3) = "::" + │ ├── name: :B + │ ├── delimiter_loc: (1,1)-(1,3) = "::" + │ └── name_loc: (1,3)-(1,4) = "B" ├── @ ConstantPathNode (location: (3,0)-(3,7)) │ ├── parent: │ │ @ ConstantPathNode (location: (3,0)-(3,4)) │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (3,0)-(3,1)) │ │ │ └── name: :A - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (3,3)-(3,4)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (3,1)-(3,3) = "::" - │ ├── child: - │ │ @ ConstantReadNode (location: (3,6)-(3,7)) - │ │ └── name: :C - │ └── delimiter_loc: (3,4)-(3,6) = "::" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (3,1)-(3,3) = "::" + │ │ └── name_loc: (3,3)-(3,4) = "B" + │ ├── name: :C + │ ├── delimiter_loc: (3,4)-(3,6) = "::" + │ └── name_loc: (3,6)-(3,7) = "C" ├── @ ConstantPathNode (location: (5,0)-(5,4)) │ ├── parent: │ │ @ CallNode (location: (5,0)-(5,1)) @@ -37,20 +34,18 @@ │ │ ├── arguments: ∅ │ │ ├── closing_loc: ∅ │ │ └── block: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (5,3)-(5,4)) - │ │ └── name: :B - │ └── delimiter_loc: (5,1)-(5,3) = "::" + │ ├── name: :B + │ ├── delimiter_loc: (5,1)-(5,3) = "::" + │ └── name_loc: (5,3)-(5,4) = "B" ├── @ ConstantPathWriteNode (location: (7,0)-(7,8)) │ ├── target: │ │ @ ConstantPathNode (location: (7,0)-(7,4)) │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (7,0)-(7,1)) │ │ │ └── name: :A - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (7,3)-(7,4)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (7,1)-(7,3) = "::" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (7,1)-(7,3) = "::" + │ │ └── name_loc: (7,3)-(7,4) = "B" │ ├── operator_loc: (7,5)-(7,6) = "=" │ └── value: │ @ IntegerNode (location: (7,7)-(7,8)) @@ -117,7 +112,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (17,4)-(17,9)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (17,4)-(17,9)) │ │ ├── flags: ∅ @@ -199,7 +194,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (23,9)-(23,14)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (23,9)-(23,14)) │ │ ├── flags: ∅ @@ -249,10 +244,9 @@ │ ├── receiver: │ │ @ ConstantPathNode (location: (27,0)-(27,3)) │ │ ├── parent: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (27,2)-(27,3)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (27,0)-(27,2) = "::" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (27,0)-(27,2) = "::" + │ │ └── name_loc: (27,2)-(27,3) = "A" │ ├── call_operator_loc: (27,3)-(27,5) = "::" │ ├── name: :foo │ ├── message_loc: (27,5)-(27,8) = "foo" @@ -264,10 +258,9 @@ │ ├── target: │ │ @ ConstantPathNode (location: (29,0)-(29,3)) │ │ ├── parent: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (29,2)-(29,3)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (29,0)-(29,2) = "::" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (29,0)-(29,2) = "::" + │ │ └── name_loc: (29,2)-(29,3) = "A" │ ├── operator_loc: (29,4)-(29,5) = "=" │ └── value: │ @ IntegerNode (location: (29,6)-(29,7)) @@ -279,14 +272,12 @@ │ │ ├── parent: │ │ │ @ ConstantPathNode (location: (31,0)-(31,3)) │ │ │ ├── parent: ∅ - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (31,2)-(31,3)) - │ │ │ │ └── name: :A - │ │ │ └── delimiter_loc: (31,0)-(31,2) = "::" - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (31,5)-(31,6)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (31,3)-(31,5) = "::" + │ │ │ ├── name: :A + │ │ │ ├── delimiter_loc: (31,0)-(31,2) = "::" + │ │ │ └── name_loc: (31,2)-(31,3) = "A" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (31,3)-(31,5) = "::" + │ │ └── name_loc: (31,5)-(31,6) = "B" │ ├── operator_loc: (31,7)-(31,8) = "=" │ └── value: │ @ IntegerNode (location: (31,9)-(31,10)) @@ -296,20 +287,17 @@ │ ├── parent: │ │ @ ConstantPathNode (location: (33,0)-(33,3)) │ │ ├── parent: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (33,2)-(33,3)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (33,0)-(33,2) = "::" - │ ├── child: - │ │ @ ConstantReadNode (location: (33,5)-(33,6)) - │ │ └── name: :B - │ └── delimiter_loc: (33,3)-(33,5) = "::" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (33,0)-(33,2) = "::" + │ │ └── name_loc: (33,2)-(33,3) = "A" + │ ├── name: :B + │ ├── delimiter_loc: (33,3)-(33,5) = "::" + │ └── name_loc: (33,5)-(33,6) = "B" ├── @ ConstantPathNode (location: (35,0)-(35,3)) │ ├── parent: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (35,2)-(35,3)) - │ │ └── name: :A - │ └── delimiter_loc: (35,0)-(35,2) = "::" + │ ├── name: :A + │ ├── delimiter_loc: (35,0)-(35,2) = "::" + │ └── name_loc: (35,2)-(35,3) = "A" ├── @ CallNode (location: (37,0)-(37,8)) │ ├── flags: ∅ │ ├── receiver: @@ -329,10 +317,9 @@ │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (39,0)-(39,1)) │ │ │ └── name: :A - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (39,3)-(39,4)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (39,1)-(39,3) = "::" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (39,1)-(39,3) = "::" + │ │ └── name_loc: (39,3)-(39,4) = "B" │ ├── call_operator_loc: (39,4)-(39,6) = "::" │ ├── name: :true │ ├── message_loc: (39,6)-(39,10) = "true" @@ -488,10 +475,9 @@ │ ├── parent: │ │ @ ConstantReadNode (location: (65,0)-(65,1)) │ │ └── name: :A - │ ├── child: - │ │ @ ConstantReadNode (location: (67,0)-(67,1)) - │ │ └── name: :C - │ └── delimiter_loc: (65,1)-(65,3) = "::" + │ ├── name: :C + │ ├── delimiter_loc: (65,1)-(65,3) = "::" + │ └── name_loc: (67,0)-(67,1) = "C" ├── @ CallNode (location: (69,0)-(69,8)) │ ├── flags: ∅ │ ├── receiver: @@ -532,10 +518,9 @@ │ ├── parent: │ │ @ ConstantReadNode (location: (75,0)-(75,1)) │ │ └── name: :A - │ ├── child: - │ │ @ ConstantReadNode (location: (75,3)-(75,8)) - │ │ └── name: :BEGIN - │ └── delimiter_loc: (75,1)-(75,3) = "::" + │ ├── name: :BEGIN + │ ├── delimiter_loc: (75,1)-(75,3) = "::" + │ └── name_loc: (75,3)-(75,8) = "BEGIN" ├── @ CallNode (location: (77,0)-(77,8)) │ ├── flags: ∅ │ ├── receiver: @@ -636,10 +621,9 @@ │ ├── parent: │ │ @ ConstantReadNode (location: (93,0)-(93,1)) │ │ └── name: :A - │ ├── child: - │ │ @ ConstantReadNode (location: (93,3)-(93,6)) - │ │ └── name: :END - │ └── delimiter_loc: (93,1)-(93,3) = "::" + │ ├── name: :END + │ ├── delimiter_loc: (93,1)-(93,3) = "::" + │ └── name_loc: (93,3)-(93,6) = "END" ├── @ CallNode (location: (95,0)-(95,9)) │ ├── flags: ∅ │ ├── receiver: @@ -1207,10 +1191,9 @@ │ │ ├── arguments: ∅ │ │ ├── closing_loc: ∅ │ │ └── block: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (180,0)-(180,1)) - │ │ └── name: :C - │ └── delimiter_loc: (179,4)-(179,6) = "::" + │ ├── name: :C + │ ├── delimiter_loc: (179,4)-(179,6) = "::" + │ └── name_loc: (180,0)-(180,1) = "C" └── @ RangeNode (location: (182,0)-(184,10)) ├── flags: ∅ ├── left: diff --git a/test/prism/snapshots/defined.txt b/test/prism/snapshots/defined.txt index 53a5081811..c60173ff37 100644 --- a/test/prism/snapshots/defined.txt +++ b/test/prism/snapshots/defined.txt @@ -28,13 +28,13 @@ │ ├── value: │ │ @ LocalVariableOperatorWriteNode (location: (3,9)-(3,15)) │ │ ├── name_loc: (3,9)-(3,10) = "x" - │ │ ├── operator_loc: (3,11)-(3,13) = "%=" + │ │ ├── binary_operator_loc: (3,11)-(3,13) = "%=" │ │ ├── value: │ │ │ @ IntegerNode (location: (3,14)-(3,15)) │ │ │ ├── flags: decimal │ │ │ └── value: 2 │ │ ├── name: :x - │ │ ├── operator: :% + │ │ ├── binary_operator: :% │ │ └── depth: 0 │ ├── rparen_loc: (3,15)-(3,16) = ")" │ └── keyword_loc: (3,0)-(3,8) = "defined?" diff --git a/test/prism/snapshots/heredocs_nested.txt b/test/prism/snapshots/heredocs_nested.txt index f830b028c7..da13e48c51 100644 --- a/test/prism/snapshots/heredocs_nested.txt +++ b/test/prism/snapshots/heredocs_nested.txt @@ -4,7 +4,7 @@ @ StatementsNode (location: (1,0)-(12,4)) └── body: (length: 2) ├── @ InterpolatedStringNode (location: (1,0)-(1,7)) - │ ├── flags: ∅ + │ ├── flags: mutable │ ├── opening_loc: (1,0)-(1,7) = "<<~RUBY" │ ├── parts: (length: 4) │ │ ├── @ StringNode (location: (2,0)-(3,0)) @@ -19,7 +19,7 @@ │ │ │ │ @ StatementsNode (location: (4,0)-(4,6)) │ │ │ │ └── body: (length: 1) │ │ │ │ └── @ StringNode (location: (4,0)-(4,6)) - │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── flags: frozen │ │ │ │ ├── opening_loc: (4,0)-(4,6) = "<<RUBY" │ │ │ │ ├── content_loc: (5,0)-(6,0) = " hello\n" │ │ │ │ ├── closing_loc: (6,0)-(7,0) = "RUBY\n" diff --git a/test/prism/snapshots/if.txt b/test/prism/snapshots/if.txt index 31c33d368f..4114d22722 100644 --- a/test/prism/snapshots/if.txt +++ b/test/prism/snapshots/if.txt @@ -307,7 +307,7 @@ │ │ ├── opening_loc: ∅ │ │ ├── arguments: │ │ │ @ ArgumentsNode (location: (25,4)-(25,6)) - │ │ │ ├── flags: ∅ + │ │ │ ├── flags: contains_keywords │ │ │ └── arguments: (length: 1) │ │ │ └── @ KeywordHashNode (location: (25,4)-(25,6)) │ │ │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/method_calls.txt b/test/prism/snapshots/method_calls.txt index de9ba71ae0..6082b567f7 100644 --- a/test/prism/snapshots/method_calls.txt +++ b/test/prism/snapshots/method_calls.txt @@ -308,7 +308,7 @@ │ ├── opening_loc: (27,1)-(27,2) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (27,2)-(27,10)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (27,2)-(27,10)) │ │ ├── flags: ∅ @@ -779,7 +779,7 @@ │ ├── opening_loc: (60,3)-(60,4) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (60,4)-(60,32)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 2) │ │ ├── @ SymbolNode (location: (60,4)-(60,6)) │ │ │ ├── flags: forced_us_ascii_encoding @@ -912,7 +912,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (64,4)-(64,15)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 2) │ │ ├── @ SymbolNode (location: (64,4)-(64,6)) │ │ │ ├── flags: forced_us_ascii_encoding @@ -988,7 +988,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (66,3)-(66,17)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (66,3)-(66,17)) │ │ ├── flags: symbol_keys @@ -1020,7 +1020,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (68,3)-(68,40)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (68,3)-(68,40)) │ │ ├── flags: ∅ @@ -1075,7 +1075,7 @@ │ ├── opening_loc: (70,2)-(70,3) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (70,3)-(70,40)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (70,3)-(70,40)) │ │ ├── flags: ∅ @@ -1178,7 +1178,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (74,3)-(74,20)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (74,3)-(74,20)) │ │ ├── flags: symbol_keys @@ -1235,7 +1235,7 @@ │ ├── opening_loc: (80,3)-(80,4) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (81,0)-(82,5)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 2) │ │ ├── @ SymbolNode (location: (81,0)-(81,2)) │ │ │ ├── flags: forced_us_ascii_encoding @@ -1292,7 +1292,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (87,4)-(87,21)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (87,4)-(87,21)) │ │ ├── flags: symbol_keys @@ -1339,7 +1339,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (89,10)-(89,21)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 2) │ │ ├── @ IntegerNode (location: (89,10)-(89,11)) │ │ │ ├── flags: decimal @@ -1443,10 +1443,9 @@ │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (97,0)-(97,1)) │ │ │ └── name: :A - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (97,3)-(97,4)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (97,1)-(97,3) = "::" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (97,1)-(97,3) = "::" + │ │ └── name_loc: (97,3)-(97,4) = "B" │ ├── call_operator_loc: (97,4)-(97,6) = "::" │ ├── name: :C │ ├── message_loc: (97,6)-(97,7) = "C" @@ -1470,10 +1469,9 @@ │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (99,0)-(99,1)) │ │ │ └── name: :A - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (99,3)-(99,4)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (99,1)-(99,3) = "::" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (99,1)-(99,3) = "::" + │ │ └── name_loc: (99,3)-(99,4) = "B" │ ├── call_operator_loc: (99,4)-(99,6) = "::" │ ├── name: :C │ ├── message_loc: (99,6)-(99,7) = "C" @@ -1497,10 +1495,9 @@ │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (101,0)-(101,1)) │ │ │ └── name: :A - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (101,3)-(101,4)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (101,1)-(101,3) = "::" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (101,1)-(101,3) = "::" + │ │ └── name_loc: (101,3)-(101,4) = "B" │ ├── call_operator_loc: (101,4)-(101,6) = "::" │ ├── name: :C │ ├── message_loc: (101,6)-(101,7) = "C" @@ -1532,7 +1529,7 @@ │ ├── opening_loc: (103,3)-(103,4) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (103,4)-(103,11)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (103,4)-(103,11)) │ │ ├── flags: symbol_keys @@ -1561,7 +1558,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (105,4)-(105,28)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (105,4)-(105,28)) │ │ ├── flags: symbol_keys @@ -1617,7 +1614,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (107,4)-(107,24)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (107,4)-(107,24)) │ │ ├── flags: symbol_keys @@ -2417,7 +2414,7 @@ ├── opening_loc: ∅ ├── arguments: │ @ ArgumentsNode (location: (156,5)-(156,19)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (156,5)-(156,19)) │ ├── flags: ∅ diff --git a/test/prism/snapshots/methods.txt b/test/prism/snapshots/methods.txt index 76c0361827..b38640399b 100644 --- a/test/prism/snapshots/methods.txt +++ b/test/prism/snapshots/methods.txt @@ -1296,7 +1296,7 @@ │ │ ├── opening_loc: ∅ │ │ ├── arguments: │ │ │ @ ArgumentsNode (location: (139,11)-(139,30)) - │ │ │ ├── flags: contains_keyword_splat + │ │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ │ └── arguments: (length: 1) │ │ │ └── @ KeywordHashNode (location: (139,11)-(139,30)) │ │ │ ├── flags: ∅ diff --git a/test/prism/snapshots/modules.txt b/test/prism/snapshots/modules.txt index 1a0eb6328a..de1ea8feeb 100644 --- a/test/prism/snapshots/modules.txt +++ b/test/prism/snapshots/modules.txt @@ -72,10 +72,9 @@ │ │ │ ├── arguments: ∅ │ │ │ ├── closing_loc: ∅ │ │ │ └── block: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (5,10)-(5,11)) - │ │ │ └── name: :M - │ │ └── delimiter_loc: (5,8)-(5,10) = "::" + │ │ ├── name: :M + │ │ ├── delimiter_loc: (5,8)-(5,10) = "::" + │ │ └── name_loc: (5,10)-(5,11) = "M" │ ├── body: ∅ │ ├── end_keyword_loc: (6,0)-(6,3) = "end" │ └── name: :M @@ -119,10 +118,9 @@ │ ├── constant_path: │ │ @ ConstantPathNode (location: (11,7)-(11,10)) │ │ ├── parent: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (11,9)-(11,10)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (11,7)-(11,9) = "::" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (11,7)-(11,9) = "::" + │ │ └── name_loc: (11,9)-(11,10) = "A" │ ├── body: ∅ │ ├── end_keyword_loc: (12,0)-(12,3) = "end" │ └── name: :A @@ -144,10 +142,9 @@ │ │ │ ├── arguments: ∅ │ │ │ ├── closing_loc: (14,9)-(14,10) = "]" │ │ │ └── block: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (14,12)-(14,13)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (14,10)-(14,12) = "::" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (14,10)-(14,12) = "::" + │ │ └── name_loc: (14,12)-(14,13) = "B" │ ├── body: ∅ │ ├── end_keyword_loc: (15,0)-(15,3) = "end" │ └── name: :B @@ -175,10 +172,9 @@ │ │ │ └── value: 1 │ │ ├── closing_loc: (17,10)-(17,11) = "]" │ │ └── block: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (17,13)-(17,14)) - │ │ └── name: :B - │ └── delimiter_loc: (17,11)-(17,13) = "::" + │ ├── name: :B + │ ├── delimiter_loc: (17,11)-(17,13) = "::" + │ └── name_loc: (17,13)-(17,14) = "B" ├── body: ∅ ├── end_keyword_loc: (18,0)-(18,3) = "end" └── name: :B diff --git a/test/prism/snapshots/numbers.txt b/test/prism/snapshots/numbers.txt index 740f3f5a2a..58aea454fa 100644 --- a/test/prism/snapshots/numbers.txt +++ b/test/prism/snapshots/numbers.txt @@ -65,52 +65,48 @@ │ ├── flags: decimal │ └── value: 1 ├── @ RationalNode (location: (41,0)-(41,2)) - │ └── numeric: - │ @ IntegerNode (location: (41,0)-(41,1)) - │ ├── flags: decimal - │ └── value: 1 + │ ├── flags: decimal + │ ├── numerator: 1 + │ └── denominator: 1 ├── @ IntegerNode (location: (43,0)-(43,2)) │ ├── flags: decimal │ └── value: -1 ├── @ ImaginaryNode (location: (45,0)-(45,3)) │ └── numeric: │ @ RationalNode (location: (45,0)-(45,2)) - │ └── numeric: - │ @ IntegerNode (location: (45,0)-(45,1)) - │ ├── flags: decimal - │ └── value: 1 + │ ├── flags: decimal + │ ├── numerator: 1 + │ └── denominator: 1 ├── @ RationalNode (location: (47,0)-(47,4)) - │ └── numeric: - │ @ FloatNode (location: (47,0)-(47,3)) - │ └── value: 1.2 + │ ├── flags: decimal + │ ├── numerator: 6 + │ └── denominator: 5 ├── @ ImaginaryNode (location: (49,0)-(49,5)) │ └── numeric: │ @ RationalNode (location: (49,0)-(49,4)) - │ └── numeric: - │ @ FloatNode (location: (49,0)-(49,3)) - │ └── value: 1.2 + │ ├── flags: decimal + │ ├── numerator: 6 + │ └── denominator: 5 ├── @ ImaginaryNode (location: (51,0)-(51,4)) │ └── numeric: │ @ RationalNode (location: (51,0)-(51,3)) - │ └── numeric: - │ @ IntegerNode (location: (51,0)-(51,2)) - │ ├── flags: decimal - │ └── value: -1 + │ ├── flags: decimal + │ ├── numerator: -1 + │ └── denominator: 1 ├── @ RationalNode (location: (53,0)-(53,5)) - │ └── numeric: - │ @ FloatNode (location: (53,0)-(53,4)) - │ └── value: -1.2 + │ ├── flags: decimal + │ ├── numerator: -6 + │ └── denominator: 5 ├── @ ImaginaryNode (location: (55,0)-(55,6)) │ └── numeric: │ @ RationalNode (location: (55,0)-(55,5)) - │ └── numeric: - │ @ FloatNode (location: (55,0)-(55,4)) - │ └── value: -1.2 + │ ├── flags: decimal + │ ├── numerator: -6 + │ └── denominator: 5 ├── @ RationalNode (location: (57,0)-(57,4)) - │ └── numeric: - │ @ IntegerNode (location: (57,0)-(57,3)) - │ ├── flags: octal - │ └── value: 1 + │ ├── flags: octal + │ ├── numerator: 1 + │ └── denominator: 1 ├── @ ImaginaryNode (location: (59,0)-(59,4)) │ └── numeric: │ @ IntegerNode (location: (59,0)-(59,3)) @@ -119,15 +115,13 @@ ├── @ ImaginaryNode (location: (61,0)-(61,5)) │ └── numeric: │ @ RationalNode (location: (61,0)-(61,4)) - │ └── numeric: - │ @ IntegerNode (location: (61,0)-(61,3)) - │ ├── flags: octal - │ └── value: 1 + │ ├── flags: octal + │ ├── numerator: 1 + │ └── denominator: 1 ├── @ RationalNode (location: (63,0)-(63,4)) - │ └── numeric: - │ @ IntegerNode (location: (63,0)-(63,3)) - │ ├── flags: decimal - │ └── value: 1 + │ ├── flags: decimal + │ ├── numerator: 1 + │ └── denominator: 1 ├── @ ImaginaryNode (location: (65,0)-(65,4)) │ └── numeric: │ @ IntegerNode (location: (65,0)-(65,3)) @@ -136,7 +130,6 @@ └── @ ImaginaryNode (location: (67,0)-(67,5)) └── numeric: @ RationalNode (location: (67,0)-(67,4)) - └── numeric: - @ IntegerNode (location: (67,0)-(67,3)) - ├── flags: binary - └── value: 1 + ├── flags: binary + ├── numerator: 1 + └── denominator: 1 diff --git a/test/prism/snapshots/patterns.txt b/test/prism/snapshots/patterns.txt index 5662129dae..17aa23b4b9 100644 --- a/test/prism/snapshots/patterns.txt +++ b/test/prism/snapshots/patterns.txt @@ -86,10 +86,9 @@ │ │ └── block: ∅ │ ├── pattern: │ │ @ RationalNode (location: (5,7)-(5,9)) - │ │ └── numeric: - │ │ @ IntegerNode (location: (5,7)-(5,8)) - │ │ ├── flags: decimal - │ │ └── value: 1 + │ │ ├── flags: decimal + │ │ ├── numerator: 1 + │ │ └── denominator: 1 │ └── operator_loc: (5,4)-(5,6) = "=>" ├── @ MatchRequiredNode (location: (6,0)-(6,11)) │ ├── value: @@ -598,16 +597,14 @@ │ │ ├── flags: ∅ │ │ ├── left: │ │ │ @ RationalNode (location: (31,7)-(31,9)) - │ │ │ └── numeric: - │ │ │ @ IntegerNode (location: (31,7)-(31,8)) - │ │ │ ├── flags: decimal - │ │ │ └── value: 1 + │ │ │ ├── flags: decimal + │ │ │ ├── numerator: 1 + │ │ │ └── denominator: 1 │ │ ├── right: │ │ │ @ RationalNode (location: (31,13)-(31,15)) - │ │ │ └── numeric: - │ │ │ @ IntegerNode (location: (31,13)-(31,14)) - │ │ │ ├── flags: decimal - │ │ │ └── value: 1 + │ │ │ ├── flags: decimal + │ │ │ ├── numerator: 1 + │ │ │ └── denominator: 1 │ │ └── operator_loc: (31,10)-(31,12) = ".." │ └── operator_loc: (31,4)-(31,6) = "=>" ├── @ MatchRequiredNode (location: (32,0)-(32,19)) @@ -1454,14 +1451,12 @@ │ │ │ ├── parent: │ │ │ │ @ ConstantReadNode (location: (64,7)-(64,10)) │ │ │ │ └── name: :Foo - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (64,12)-(64,15)) - │ │ │ │ └── name: :Bar - │ │ │ └── delimiter_loc: (64,10)-(64,12) = "::" - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (64,17)-(64,20)) - │ │ │ └── name: :Baz - │ │ └── delimiter_loc: (64,15)-(64,17) = "::" + │ │ │ ├── name: :Bar + │ │ │ ├── delimiter_loc: (64,10)-(64,12) = "::" + │ │ │ └── name_loc: (64,12)-(64,15) = "Bar" + │ │ ├── name: :Baz + │ │ ├── delimiter_loc: (64,15)-(64,17) = "::" + │ │ └── name_loc: (64,17)-(64,20) = "Baz" │ └── operator_loc: (64,4)-(64,6) = "=>" ├── @ MatchRequiredNode (location: (65,0)-(65,12)) │ ├── value: @@ -1478,10 +1473,9 @@ │ ├── pattern: │ │ @ ConstantPathNode (location: (65,7)-(65,12)) │ │ ├── parent: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (65,9)-(65,12)) - │ │ │ └── name: :Foo - │ │ └── delimiter_loc: (65,7)-(65,9) = "::" + │ │ ├── name: :Foo + │ │ ├── delimiter_loc: (65,7)-(65,9) = "::" + │ │ └── name_loc: (65,9)-(65,12) = "Foo" │ └── operator_loc: (65,4)-(65,6) = "=>" ├── @ MatchRequiredNode (location: (66,0)-(66,22)) │ ├── value: @@ -1502,18 +1496,15 @@ │ │ │ ├── parent: │ │ │ │ @ ConstantPathNode (location: (66,7)-(66,12)) │ │ │ │ ├── parent: ∅ - │ │ │ │ ├── child: - │ │ │ │ │ @ ConstantReadNode (location: (66,9)-(66,12)) - │ │ │ │ │ └── name: :Foo - │ │ │ │ └── delimiter_loc: (66,7)-(66,9) = "::" - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (66,14)-(66,17)) - │ │ │ │ └── name: :Bar - │ │ │ └── delimiter_loc: (66,12)-(66,14) = "::" - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (66,19)-(66,22)) - │ │ │ └── name: :Baz - │ │ └── delimiter_loc: (66,17)-(66,19) = "::" + │ │ │ │ ├── name: :Foo + │ │ │ │ ├── delimiter_loc: (66,7)-(66,9) = "::" + │ │ │ │ └── name_loc: (66,9)-(66,12) = "Foo" + │ │ │ ├── name: :Bar + │ │ │ ├── delimiter_loc: (66,12)-(66,14) = "::" + │ │ │ └── name_loc: (66,14)-(66,17) = "Bar" + │ │ ├── name: :Baz + │ │ ├── delimiter_loc: (66,17)-(66,19) = "::" + │ │ └── name_loc: (66,19)-(66,22) = "Baz" │ └── operator_loc: (66,4)-(66,6) = "=>" ├── @ MatchRequiredNode (location: (68,0)-(68,12)) │ ├── value: @@ -2467,10 +2458,9 @@ │ │ └── block: ∅ │ ├── pattern: │ │ @ RationalNode (location: (108,7)-(108,9)) - │ │ └── numeric: - │ │ @ IntegerNode (location: (108,7)-(108,8)) - │ │ ├── flags: decimal - │ │ └── value: 1 + │ │ ├── flags: decimal + │ │ ├── numerator: 1 + │ │ └── denominator: 1 │ └── operator_loc: (108,4)-(108,6) = "in" ├── @ MatchPredicateNode (location: (109,0)-(109,11)) │ ├── value: @@ -3023,10 +3013,9 @@ │ │ └── @ InNode (location: (139,10)-(139,20)) │ │ ├── pattern: │ │ │ @ RationalNode (location: (139,13)-(139,15)) - │ │ │ └── numeric: - │ │ │ @ IntegerNode (location: (139,13)-(139,14)) - │ │ │ ├── flags: decimal - │ │ │ └── value: 1 + │ │ │ ├── flags: decimal + │ │ │ ├── numerator: 1 + │ │ │ └── denominator: 1 │ │ ├── statements: ∅ │ │ ├── in_loc: (139,10)-(139,12) = "in" │ │ └── then_loc: (139,16)-(139,20) = "then" @@ -3764,10 +3753,9 @@ │ │ │ │ @ StatementsNode (location: (166,13)-(166,15)) │ │ │ │ └── body: (length: 1) │ │ │ │ └── @ RationalNode (location: (166,13)-(166,15)) - │ │ │ │ └── numeric: - │ │ │ │ @ IntegerNode (location: (166,13)-(166,14)) - │ │ │ │ ├── flags: decimal - │ │ │ │ └── value: 1 + │ │ │ │ ├── flags: decimal + │ │ │ │ ├── numerator: 1 + │ │ │ │ └── denominator: 1 │ │ │ ├── consequent: ∅ │ │ │ └── end_keyword_loc: ∅ │ │ ├── statements: ∅ diff --git a/test/prism/snapshots/rescue.txt b/test/prism/snapshots/rescue.txt index 2bdbfdaff3..390b08ae0e 100644 --- a/test/prism/snapshots/rescue.txt +++ b/test/prism/snapshots/rescue.txt @@ -380,7 +380,7 @@ │ │ │ ├── opening_loc: ∅ │ │ │ ├── arguments: │ │ │ │ @ ArgumentsNode (location: (29,4)-(29,6)) - │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── flags: contains_keywords │ │ │ │ └── arguments: (length: 1) │ │ │ │ └── @ KeywordHashNode (location: (29,4)-(29,6)) │ │ │ │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/seattlerb/assoc_label.txt b/test/prism/snapshots/seattlerb/assoc_label.txt index 923f5450f4..70490c0da4 100644 --- a/test/prism/snapshots/seattlerb/assoc_label.txt +++ b/test/prism/snapshots/seattlerb/assoc_label.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,1)-(1,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,5)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,2)-(1,5)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/seattlerb/bug_249.txt b/test/prism/snapshots/seattlerb/bug_249.txt index 569bea14c5..ad61501a07 100644 --- a/test/prism/snapshots/seattlerb/bug_249.txt +++ b/test/prism/snapshots/seattlerb/bug_249.txt @@ -12,7 +12,7 @@ ├── opening_loc: ∅ ├── arguments: │ @ ArgumentsNode (location: (1,6)-(4,28)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 2) │ ├── @ CallNode (location: (1,6)-(4,9)) │ │ ├── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/bug_hash_args.txt b/test/prism/snapshots/seattlerb/bug_hash_args.txt index 6f17e88714..e138db4d49 100644 --- a/test/prism/snapshots/seattlerb/bug_hash_args.txt +++ b/test/prism/snapshots/seattlerb/bug_hash_args.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,3)-(1,4) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,4)-(1,18)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 2) │ ├── @ SymbolNode (location: (1,4)-(1,8)) │ │ ├── flags: forced_us_ascii_encoding diff --git a/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt b/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt index e7256b337b..fe2d7f73c9 100644 --- a/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt +++ b/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,3)-(1,4) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,4)-(1,18)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 2) │ ├── @ SymbolNode (location: (1,4)-(1,8)) │ │ ├── flags: forced_us_ascii_encoding diff --git a/test/prism/snapshots/seattlerb/call_arg_assoc.txt b/test/prism/snapshots/seattlerb/call_arg_assoc.txt index 27c19fd339..f489bc7f19 100644 --- a/test/prism/snapshots/seattlerb/call_arg_assoc.txt +++ b/test/prism/snapshots/seattlerb/call_arg_assoc.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,1)-(1,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,9)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 2) │ ├── @ IntegerNode (location: (1,2)-(1,3)) │ │ ├── flags: decimal diff --git a/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt b/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt index 0193eb1dfc..5b191396de 100644 --- a/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt +++ b/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,1)-(1,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,15)) - │ ├── flags: contains_keyword_splat + │ ├── flags: contains_keywords, contains_keyword_splat │ └── arguments: (length: 2) │ ├── @ IntegerNode (location: (1,2)-(1,3)) │ │ ├── flags: decimal diff --git a/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt b/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt index 91c7725525..f95b80cf7d 100644 --- a/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt +++ b/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,1)-(1,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,8)) - │ ├── flags: contains_keyword_splat + │ ├── flags: contains_keywords, contains_keyword_splat │ └── arguments: (length: 2) │ ├── @ CallNode (location: (1,2)-(1,3)) │ │ ├── flags: variable_call, ignore_visibility diff --git a/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt b/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt index 2d6f81c818..8946206a3f 100644 --- a/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt +++ b/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt @@ -12,7 +12,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (1,2)-(1,11)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (1,2)-(1,11)) │ │ ├── flags: ∅ @@ -55,7 +55,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (3,2)-(3,8)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (3,2)-(3,8)) │ │ ├── flags: symbol_keys @@ -84,7 +84,7 @@ ├── opening_loc: ∅ ├── arguments: │ @ ArgumentsNode (location: (5,2)-(5,8)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (5,2)-(5,8)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt index 312a1981a0..0ba5891cf6 100644 --- a/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt +++ b/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,1)-(1,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,9)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 2) │ ├── @ IntegerNode (location: (1,2)-(1,3)) │ │ ├── flags: decimal diff --git a/test/prism/snapshots/seattlerb/call_assoc.txt b/test/prism/snapshots/seattlerb/call_assoc.txt index 438c256553..60784e6095 100644 --- a/test/prism/snapshots/seattlerb/call_assoc.txt +++ b/test/prism/snapshots/seattlerb/call_assoc.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,1)-(1,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,6)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,2)-(1,6)) │ ├── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/call_assoc_new.txt b/test/prism/snapshots/seattlerb/call_assoc_new.txt index b4d7e0bf83..dc25fb2493 100644 --- a/test/prism/snapshots/seattlerb/call_assoc_new.txt +++ b/test/prism/snapshots/seattlerb/call_assoc_new.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,1)-(1,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,5)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,2)-(1,5)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt b/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt index 9587e2e074..b3d652e879 100644 --- a/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt +++ b/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,1)-(1,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(5,3)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,2)-(5,3)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt index 8d0b285172..b2012f0f75 100644 --- a/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt +++ b/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,1)-(1,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,6)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,2)-(1,6)) │ ├── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/call_kwsplat.txt b/test/prism/snapshots/seattlerb/call_kwsplat.txt index 4199e97a44..e0620dc5f0 100644 --- a/test/prism/snapshots/seattlerb/call_kwsplat.txt +++ b/test/prism/snapshots/seattlerb/call_kwsplat.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,1)-(1,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,5)) - │ ├── flags: contains_keyword_splat + │ ├── flags: contains_keywords, contains_keyword_splat │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,2)-(1,5)) │ ├── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/case_in_86.txt b/test/prism/snapshots/seattlerb/case_in_86.txt index 5889137844..082aa74eca 100644 --- a/test/prism/snapshots/seattlerb/case_in_86.txt +++ b/test/prism/snapshots/seattlerb/case_in_86.txt @@ -30,10 +30,9 @@ │ │ ├── requireds: (length: 1) │ │ │ └── @ ConstantPathNode (location: (2,3)-(2,13)) │ │ │ ├── parent: ∅ - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (2,5)-(2,13)) - │ │ │ │ └── name: :NilClass - │ │ │ └── delimiter_loc: (2,3)-(2,5) = "::" + │ │ │ ├── name: :NilClass + │ │ │ ├── delimiter_loc: (2,3)-(2,5) = "::" + │ │ │ └── name_loc: (2,5)-(2,13) = "NilClass" │ │ ├── rest: │ │ │ @ SplatNode (location: (2,15)-(2,16)) │ │ │ ├── operator_loc: (2,15)-(2,16) = "*" diff --git a/test/prism/snapshots/seattlerb/case_in_86_2.txt b/test/prism/snapshots/seattlerb/case_in_86_2.txt index 18ce70ae93..346264f907 100644 --- a/test/prism/snapshots/seattlerb/case_in_86_2.txt +++ b/test/prism/snapshots/seattlerb/case_in_86_2.txt @@ -35,10 +35,9 @@ │ │ ├── posts: (length: 1) │ │ │ └── @ ConstantPathNode (location: (2,6)-(2,16)) │ │ │ ├── parent: ∅ - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (2,8)-(2,16)) - │ │ │ │ └── name: :NilClass - │ │ │ └── delimiter_loc: (2,6)-(2,8) = "::" + │ │ │ ├── name: :NilClass + │ │ │ ├── delimiter_loc: (2,6)-(2,8) = "::" + │ │ │ └── name_loc: (2,8)-(2,16) = "NilClass" │ │ ├── opening_loc: ∅ │ │ └── closing_loc: ∅ │ ├── statements: diff --git a/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt b/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt index c783af9ce5..d6fb80ef90 100644 --- a/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt +++ b/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt @@ -20,10 +20,9 @@ │ │ │ ├── parent: │ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4)) │ │ │ │ └── name: :B - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (2,6)-(2,7)) - │ │ │ │ └── name: :C - │ │ │ └── delimiter_loc: (2,4)-(2,6) = "::" + │ │ │ ├── name: :C + │ │ │ ├── delimiter_loc: (2,4)-(2,6) = "::" + │ │ │ └── name_loc: (2,6)-(2,7) = "C" │ │ ├── requireds: (length: 1) │ │ │ └── @ LocalVariableTargetNode (location: (2,8)-(2,9)) │ │ │ ├── name: :d diff --git a/test/prism/snapshots/seattlerb/case_in_multiple.txt b/test/prism/snapshots/seattlerb/case_in_multiple.txt index d8597c4bfa..eba0084f96 100644 --- a/test/prism/snapshots/seattlerb/case_in_multiple.txt +++ b/test/prism/snapshots/seattlerb/case_in_multiple.txt @@ -18,10 +18,9 @@ │ │ │ ├── parent: │ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4)) │ │ │ │ └── name: :A - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (2,6)-(2,7)) - │ │ │ │ └── name: :B - │ │ │ └── delimiter_loc: (2,4)-(2,6) = "::" + │ │ │ ├── name: :B + │ │ │ ├── delimiter_loc: (2,4)-(2,6) = "::" + │ │ │ └── name_loc: (2,6)-(2,7) = "B" │ │ ├── statements: │ │ │ @ StatementsNode (location: (3,2)-(3,4)) │ │ │ └── body: (length: 1) @@ -39,10 +38,9 @@ │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (4,3)-(4,4)) │ │ │ └── name: :D - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (4,6)-(4,7)) - │ │ │ └── name: :E - │ │ └── delimiter_loc: (4,4)-(4,6) = "::" + │ │ ├── name: :E + │ │ ├── delimiter_loc: (4,4)-(4,6) = "::" + │ │ └── name_loc: (4,6)-(4,7) = "E" │ ├── statements: │ │ @ StatementsNode (location: (5,2)-(5,4)) │ │ └── body: (length: 1) diff --git a/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt b/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt index b018ac48d4..e09eed7d2f 100644 --- a/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt +++ b/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt @@ -9,14 +9,12 @@ │ ├── parent: │ │ @ ConstantPathNode (location: (1,0)-(1,3)) │ │ ├── parent: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (1,2)-(1,3)) - │ │ │ └── name: :X - │ │ └── delimiter_loc: (1,0)-(1,2) = "::" - │ ├── child: - │ │ @ ConstantReadNode (location: (1,5)-(1,6)) - │ │ └── name: :Y - │ └── delimiter_loc: (1,3)-(1,5) = "::" + │ │ ├── name: :X + │ │ ├── delimiter_loc: (1,0)-(1,2) = "::" + │ │ └── name_loc: (1,2)-(1,3) = "X" + │ ├── name: :Y + │ ├── delimiter_loc: (1,3)-(1,5) = "::" + │ └── name_loc: (1,5)-(1,6) = "Y" ├── operator_loc: (1,7)-(1,10) = "||=" └── value: @ IntegerNode (location: (1,11)-(1,12)) diff --git a/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt b/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt index 8d9d94931b..398af888a8 100644 --- a/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt +++ b/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt @@ -7,10 +7,9 @@ ├── target: │ @ ConstantPathNode (location: (1,0)-(1,3)) │ ├── parent: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (1,2)-(1,3)) - │ │ └── name: :X - │ └── delimiter_loc: (1,0)-(1,2) = "::" + │ ├── name: :X + │ ├── delimiter_loc: (1,0)-(1,2) = "::" + │ └── name_loc: (1,2)-(1,3) = "X" ├── operator_loc: (1,4)-(1,7) = "||=" └── value: @ IntegerNode (location: (1,8)-(1,9)) diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt b/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt index b1d61b3752..f9792aebb3 100644 --- a/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt +++ b/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt @@ -7,13 +7,12 @@ ├── target: │ @ ConstantPathNode (location: (1,0)-(1,3)) │ ├── parent: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (1,2)-(1,3)) - │ │ └── name: :X - │ └── delimiter_loc: (1,0)-(1,2) = "::" - ├── operator_loc: (1,4)-(1,6) = "&=" + │ ├── name: :X + │ ├── delimiter_loc: (1,0)-(1,2) = "::" + │ └── name_loc: (1,2)-(1,3) = "X" + ├── binary_operator_loc: (1,4)-(1,6) = "&=" ├── value: │ @ IntegerNode (location: (1,7)-(1,8)) │ ├── flags: decimal │ └── value: 1 - └── operator: :& + └── binary_operator: :& diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt b/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt index 22f6682534..146455d327 100644 --- a/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt +++ b/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt @@ -7,10 +7,9 @@ ├── target: │ @ ConstantPathNode (location: (1,0)-(1,3)) │ ├── parent: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (1,2)-(1,3)) - │ │ └── name: :X - │ └── delimiter_loc: (1,0)-(1,2) = "::" + │ ├── name: :X + │ ├── delimiter_loc: (1,0)-(1,2) = "::" + │ └── name_loc: (1,2)-(1,3) = "X" ├── operator_loc: (1,4)-(1,7) = "&&=" └── value: @ IntegerNode (location: (1,8)-(1,9)) diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_or.txt b/test/prism/snapshots/seattlerb/const_op_asgn_or.txt index 067e0fbb93..5e9dd39604 100644 --- a/test/prism/snapshots/seattlerb/const_op_asgn_or.txt +++ b/test/prism/snapshots/seattlerb/const_op_asgn_or.txt @@ -9,10 +9,9 @@ │ ├── parent: │ │ @ ConstantReadNode (location: (1,0)-(1,1)) │ │ └── name: :X - │ ├── child: - │ │ @ ConstantReadNode (location: (1,3)-(1,4)) - │ │ └── name: :Y - │ └── delimiter_loc: (1,1)-(1,3) = "::" + │ ├── name: :Y + │ ├── delimiter_loc: (1,1)-(1,3) = "::" + │ └── name_loc: (1,3)-(1,4) = "Y" ├── operator_loc: (1,5)-(1,8) = "||=" └── value: @ IntegerNode (location: (1,9)-(1,10)) diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_env.txt b/test/prism/snapshots/seattlerb/defn_kwarg_env.txt index f420420fc3..2aadedd964 100644 --- a/test/prism/snapshots/seattlerb/defn_kwarg_env.txt +++ b/test/prism/snapshots/seattlerb/defn_kwarg_env.txt @@ -33,7 +33,7 @@ │ ├── opening_loc: (1,30)-(1,31) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (1,31)-(1,40)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (1,31)-(1,40)) │ │ ├── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/difficult2_.txt b/test/prism/snapshots/seattlerb/difficult2_.txt index a9b3736fe3..b53d4cad3f 100644 --- a/test/prism/snapshots/seattlerb/difficult2_.txt +++ b/test/prism/snapshots/seattlerb/difficult2_.txt @@ -52,7 +52,7 @@ ├── opening_loc: ∅ ├── arguments: │ @ ArgumentsNode (location: (2,2)-(2,6)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (2,2)-(2,6)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/seattlerb/dstr_evstr.txt b/test/prism/snapshots/seattlerb/dstr_evstr.txt index 8d771e88c2..add8ad6f5c 100644 --- a/test/prism/snapshots/seattlerb/dstr_evstr.txt +++ b/test/prism/snapshots/seattlerb/dstr_evstr.txt @@ -13,7 +13,7 @@ │ │ │ @ StatementsNode (location: (1,3)-(1,6)) │ │ │ └── body: (length: 1) │ │ │ └── @ StringNode (location: (1,3)-(1,6)) - │ │ │ ├── flags: ∅ + │ │ │ ├── flags: frozen │ │ │ ├── opening_loc: (1,3)-(1,4) = "'" │ │ │ ├── content_loc: (1,4)-(1,5) = "a" │ │ │ ├── closing_loc: (1,5)-(1,6) = "'" diff --git a/test/prism/snapshots/seattlerb/dstr_str.txt b/test/prism/snapshots/seattlerb/dstr_str.txt index 70b5752ce3..6fe0781880 100644 --- a/test/prism/snapshots/seattlerb/dstr_str.txt +++ b/test/prism/snapshots/seattlerb/dstr_str.txt @@ -4,7 +4,7 @@ @ StatementsNode (location: (1,0)-(1,10)) └── body: (length: 1) └── @ InterpolatedStringNode (location: (1,0)-(1,10)) - ├── flags: ∅ + ├── flags: mutable ├── opening_loc: (1,0)-(1,1) = "\"" ├── parts: (length: 2) │ ├── @ EmbeddedStatementsNode (location: (1,1)-(1,7)) @@ -13,7 +13,7 @@ │ │ │ @ StatementsNode (location: (1,3)-(1,6)) │ │ │ └── body: (length: 1) │ │ │ └── @ StringNode (location: (1,3)-(1,6)) - │ │ │ ├── flags: ∅ + │ │ │ ├── flags: frozen │ │ │ ├── opening_loc: (1,3)-(1,4) = "'" │ │ │ ├── content_loc: (1,4)-(1,5) = "a" │ │ │ ├── closing_loc: (1,5)-(1,6) = "'" diff --git a/test/prism/snapshots/seattlerb/heredoc_nested.txt b/test/prism/snapshots/seattlerb/heredoc_nested.txt index 26d533a33d..a2322b9632 100644 --- a/test/prism/snapshots/seattlerb/heredoc_nested.txt +++ b/test/prism/snapshots/seattlerb/heredoc_nested.txt @@ -7,7 +7,7 @@ ├── flags: ∅ ├── elements: (length: 2) │ ├── @ InterpolatedStringNode (location: (1,1)-(1,4)) - │ │ ├── flags: ∅ + │ │ ├── flags: mutable │ │ ├── opening_loc: (1,1)-(1,4) = "<<A" │ │ ├── parts: (length: 3) │ │ │ ├── @ EmbeddedStatementsNode (location: (2,0)-(2,6)) @@ -16,7 +16,7 @@ │ │ │ │ │ @ StatementsNode (location: (2,2)-(2,5)) │ │ │ │ │ └── body: (length: 1) │ │ │ │ │ └── @ StringNode (location: (2,2)-(2,5)) - │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ ├── flags: frozen │ │ │ │ │ ├── opening_loc: (2,2)-(2,5) = "<<B" │ │ │ │ │ ├── content_loc: (3,0)-(4,0) = "b\n" │ │ │ │ │ ├── closing_loc: (4,0)-(5,0) = "B\n" diff --git a/test/prism/snapshots/seattlerb/index_0_opasgn.txt b/test/prism/snapshots/seattlerb/index_0_opasgn.txt index 239a549253..322eae9907 100644 --- a/test/prism/snapshots/seattlerb/index_0_opasgn.txt +++ b/test/prism/snapshots/seattlerb/index_0_opasgn.txt @@ -21,8 +21,8 @@ ├── arguments: ∅ ├── closing_loc: (1,2)-(1,3) = "]" ├── block: ∅ - ├── operator: :+ - ├── operator_loc: (1,4)-(1,6) = "+=" + ├── binary_operator: :+ + ├── binary_operator_loc: (1,4)-(1,6) = "+=" └── value: @ CallNode (location: (1,7)-(1,8)) ├── flags: variable_call, ignore_visibility diff --git a/test/prism/snapshots/seattlerb/masgn_colon2.txt b/test/prism/snapshots/seattlerb/masgn_colon2.txt index 73ce8a71da..a0dfe72ffc 100644 --- a/test/prism/snapshots/seattlerb/masgn_colon2.txt +++ b/test/prism/snapshots/seattlerb/masgn_colon2.txt @@ -20,10 +20,9 @@ │ │ ├── arguments: ∅ │ │ ├── closing_loc: ∅ │ │ └── block: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (1,6)-(1,7)) - │ │ └── name: :C - │ └── delimiter_loc: (1,4)-(1,6) = "::" + │ ├── name: :C + │ ├── delimiter_loc: (1,4)-(1,6) = "::" + │ └── name_loc: (1,6)-(1,7) = "C" ├── rest: ∅ ├── rights: (length: 0) ├── lparen_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/masgn_colon3.txt b/test/prism/snapshots/seattlerb/masgn_colon3.txt index 0cf4f8626d..f28ed7ecee 100644 --- a/test/prism/snapshots/seattlerb/masgn_colon3.txt +++ b/test/prism/snapshots/seattlerb/masgn_colon3.txt @@ -7,16 +7,14 @@ ├── lefts: (length: 2) │ ├── @ ConstantPathTargetNode (location: (1,0)-(1,3)) │ │ ├── parent: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (1,2)-(1,3)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (1,0)-(1,2) = "::" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (1,0)-(1,2) = "::" + │ │ └── name_loc: (1,2)-(1,3) = "A" │ └── @ ConstantPathTargetNode (location: (1,5)-(1,8)) │ ├── parent: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (1,7)-(1,8)) - │ │ └── name: :B - │ └── delimiter_loc: (1,5)-(1,7) = "::" + │ ├── name: :B + │ ├── delimiter_loc: (1,5)-(1,7) = "::" + │ └── name_loc: (1,7)-(1,8) = "B" ├── rest: ∅ ├── rights: (length: 0) ├── lparen_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt b/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt index 7a3e9affb5..edef23044a 100644 --- a/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt +++ b/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt @@ -24,11 +24,10 @@ │ │ │ ├── parent: │ │ │ │ @ ConstantReadNode (location: (1,3)-(1,4)) │ │ │ │ └── name: :B - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (1,6)-(1,7)) - │ │ │ │ └── name: :C - │ │ │ └── delimiter_loc: (1,4)-(1,6) = "::" - │ │ ├── operator_loc: (1,8)-(1,10) = "*=" + │ │ │ ├── name: :C + │ │ │ ├── delimiter_loc: (1,4)-(1,6) = "::" + │ │ │ └── name_loc: (1,6)-(1,7) = "C" + │ │ ├── binary_operator_loc: (1,8)-(1,10) = "*=" │ │ ├── value: │ │ │ @ CallNode (location: (1,11)-(1,14)) │ │ │ ├── flags: ignore_visibility @@ -53,7 +52,7 @@ │ │ │ │ └── block: ∅ │ │ │ ├── closing_loc: ∅ │ │ │ └── block: ∅ - │ │ └── operator: :* + │ │ └── binary_operator: :* │ ├── opening_loc: (1,2)-(1,3) = "(" │ └── closing_loc: (1,14)-(1,15) = ")" ├── closing_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt index da10a474c3..1bb8bd0bc1 100644 --- a/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt +++ b/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt @@ -22,7 +22,7 @@ ├── opening_loc: (1,3)-(1,4) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,4)-(1,8)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,4)-(1,8)) │ ├── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt b/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt index 79b0ef5d23..ff28a1798b 100644 --- a/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt +++ b/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt @@ -12,7 +12,7 @@ │ ├── opening_loc: (1,1)-(1,2) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (1,2)-(3,1)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (1,2)-(3,1)) │ │ ├── flags: symbol_keys @@ -42,7 +42,7 @@ │ ├── opening_loc: (5,1)-(5,2) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (5,2)-(6,1)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (5,2)-(6,1)) │ │ ├── flags: symbol_keys @@ -72,7 +72,7 @@ ├── opening_loc: (8,1)-(8,2) = "(" ├── arguments: │ @ ArgumentsNode (location: (8,2)-(8,11)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (8,2)-(8,11)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt index 8e6df3e812..523ccde455 100644 --- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt +++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt @@ -9,11 +9,10 @@ │ ├── parent: │ │ @ ConstantReadNode (location: (1,0)-(1,1)) │ │ └── name: :A - │ ├── child: - │ │ @ ConstantReadNode (location: (1,3)-(1,4)) - │ │ └── name: :B - │ └── delimiter_loc: (1,1)-(1,3) = "::" - ├── operator_loc: (1,5)-(1,7) = "*=" + │ ├── name: :B + │ ├── delimiter_loc: (1,1)-(1,3) = "::" + │ └── name_loc: (1,3)-(1,4) = "B" + ├── binary_operator_loc: (1,5)-(1,7) = "*=" ├── value: │ @ CallNode (location: (1,8)-(1,11)) │ ├── flags: ignore_visibility @@ -38,4 +37,4 @@ │ │ └── block: ∅ │ ├── closing_loc: ∅ │ └── block: ∅ - └── operator: :* + └── binary_operator: :* diff --git a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt index 0daadcf6ff..b9d00edc30 100644 --- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt +++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt @@ -12,8 +12,8 @@ ├── message_loc: (1,3)-(1,4) = "b" ├── read_name: :b ├── write_name: :b= - ├── operator: :+ - ├── operator_loc: (1,5)-(1,7) = "+=" + ├── binary_operator: :+ + ├── binary_operator_loc: (1,5)-(1,7) = "+=" └── value: @ IntegerNode (location: (1,8)-(1,9)) ├── flags: decimal diff --git a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt index ea8603165b..c12ea3983c 100644 --- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt +++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt @@ -12,8 +12,8 @@ ├── message_loc: (1,3)-(1,4) = "b" ├── read_name: :b ├── write_name: :b= - ├── operator: :* - ├── operator_loc: (1,5)-(1,7) = "*=" + ├── binary_operator: :* + ├── binary_operator_loc: (1,5)-(1,7) = "*=" └── value: @ CallNode (location: (1,8)-(1,11)) ├── flags: ignore_visibility diff --git a/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt b/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt index 8199eb2449..84eef70b25 100644 --- a/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt +++ b/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt @@ -40,13 +40,13 @@ │ │ └── block: ∅ │ ├── @ LocalVariableOperatorWriteNode (location: (3,2)-(3,8)) │ │ ├── name_loc: (3,2)-(3,3) = "y" - │ │ ├── operator_loc: (3,4)-(3,6) = "*=" + │ │ ├── binary_operator_loc: (3,4)-(3,6) = "*=" │ │ ├── value: │ │ │ @ IntegerNode (location: (3,7)-(3,8)) │ │ │ ├── flags: decimal │ │ │ └── value: 2 │ │ ├── name: :y - │ │ ├── operator: :* + │ │ ├── binary_operator: :* │ │ └── depth: 0 │ └── @ ReturnNode (location: (4,2)-(4,10)) │ ├── flags: redundant diff --git a/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt b/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt index 5c2eb2da3c..d113f2af9d 100644 --- a/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt +++ b/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt @@ -5,7 +5,7 @@ └── body: (length: 2) ├── @ LocalVariableOperatorWriteNode (location: (1,6)-(2,11)) │ ├── name_loc: (1,6)-(1,9) = "foo" - │ ├── operator_loc: (1,10)-(1,12) = "+=" + │ ├── binary_operator_loc: (1,10)-(1,12) = "+=" │ ├── value: │ │ @ CallNode (location: (2,8)-(2,11)) │ │ ├── flags: variable_call, ignore_visibility @@ -18,7 +18,7 @@ │ │ ├── closing_loc: ∅ │ │ └── block: ∅ │ ├── name: :foo - │ ├── operator: :+ + │ ├── binary_operator: :+ │ └── depth: 0 └── @ CallNode (location: (3,6)-(3,9)) ├── flags: variable_call, ignore_visibility diff --git a/test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt b/test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt index b767a5c17e..dc11e2ca3d 100644 --- a/test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt +++ b/test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt @@ -15,7 +15,7 @@ ├── opening_loc: (1,1)-(1,2) = "[" ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,6)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,2)-(1,6)) │ ├── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt b/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt index c4bc53b723..1b8ec69b56 100644 --- a/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt +++ b/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt @@ -13,7 +13,7 @@ │ │ ├── closing_loc: ∅ │ │ └── unescaped: "1" │ ├── @ InterpolatedStringNode (location: (1,6)-(1,12)) - │ │ ├── flags: ∅ + │ │ ├── flags: mutable │ │ ├── opening_loc: ∅ │ │ ├── parts: (length: 1) │ │ │ └── @ EmbeddedStatementsNode (location: (1,6)-(1,12)) @@ -22,7 +22,7 @@ │ │ │ │ @ StatementsNode (location: (1,8)-(1,11)) │ │ │ │ └── body: (length: 1) │ │ │ │ └── @ StringNode (location: (1,8)-(1,11)) - │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── flags: frozen │ │ │ │ ├── opening_loc: (1,8)-(1,11) = "<<A" │ │ │ │ ├── content_loc: (2,0)-(3,0) = "2\n" │ │ │ │ ├── closing_loc: (3,0)-(4,0) = "A\n" diff --git a/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt b/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt index 64caf51bcb..bbc19d50ef 100644 --- a/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt +++ b/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt @@ -12,7 +12,7 @@ ├── opening_loc: ∅ ├── arguments: │ @ ArgumentsNode (location: (1,5)-(1,12)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,5)-(1,12)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/seattlerb/return_call_assocs.txt b/test/prism/snapshots/seattlerb/return_call_assocs.txt index 66b3cb2f82..8948f7879b 100644 --- a/test/prism/snapshots/seattlerb/return_call_assocs.txt +++ b/test/prism/snapshots/seattlerb/return_call_assocs.txt @@ -8,7 +8,7 @@ │ ├── keyword_loc: (1,0)-(1,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (1,7)-(1,17)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 2) │ ├── @ IntegerNode (location: (1,7)-(1,8)) │ │ ├── flags: decimal @@ -34,7 +34,7 @@ │ ├── keyword_loc: (3,0)-(3,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (3,7)-(3,26)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 2) │ ├── @ IntegerNode (location: (3,7)-(3,8)) │ │ ├── flags: decimal @@ -84,7 +84,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (5,9)-(5,14)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (5,9)-(5,14)) │ │ ├── flags: symbol_keys @@ -120,7 +120,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (7,9)-(7,12)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (7,9)-(7,12)) │ │ ├── flags: symbol_keys @@ -156,7 +156,7 @@ │ ├── opening_loc: (9,8)-(9,9) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (9,9)-(9,12)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (9,9)-(9,12)) │ │ ├── flags: symbol_keys @@ -192,7 +192,7 @@ ├── opening_loc: (11,8)-(11,9) = "(" ├── arguments: │ @ ArgumentsNode (location: (11,9)-(11,13)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (11,9)-(11,13)) │ ├── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/ruby21_numbers.txt b/test/prism/snapshots/seattlerb/ruby21_numbers.txt index 34a3452d1b..e7eec943f8 100644 --- a/test/prism/snapshots/seattlerb/ruby21_numbers.txt +++ b/test/prism/snapshots/seattlerb/ruby21_numbers.txt @@ -12,16 +12,14 @@ │ │ ├── flags: decimal │ │ └── value: 1 │ ├── @ RationalNode (location: (1,5)-(1,7)) - │ │ └── numeric: - │ │ @ IntegerNode (location: (1,5)-(1,6)) - │ │ ├── flags: decimal - │ │ └── value: 2 + │ │ ├── flags: decimal + │ │ ├── numerator: 2 + │ │ └── denominator: 1 │ └── @ ImaginaryNode (location: (1,9)-(1,12)) │ └── numeric: │ @ RationalNode (location: (1,9)-(1,11)) - │ └── numeric: - │ @ IntegerNode (location: (1,9)-(1,10)) - │ ├── flags: decimal - │ └── value: 3 + │ ├── flags: decimal + │ ├── numerator: 3 + │ └── denominator: 1 ├── opening_loc: (1,0)-(1,1) = "[" └── closing_loc: (1,12)-(1,13) = "]" diff --git a/test/prism/snapshots/seattlerb/safe_op_asgn.txt b/test/prism/snapshots/seattlerb/safe_op_asgn.txt index 7a9fd2b7f7..ebcedd6b5e 100644 --- a/test/prism/snapshots/seattlerb/safe_op_asgn.txt +++ b/test/prism/snapshots/seattlerb/safe_op_asgn.txt @@ -20,8 +20,8 @@ ├── message_loc: (1,3)-(1,4) = "b" ├── read_name: :b ├── write_name: :b= - ├── operator: :+ - ├── operator_loc: (1,5)-(1,7) = "+=" + ├── binary_operator: :+ + ├── binary_operator_loc: (1,5)-(1,7) = "+=" └── value: @ CallNode (location: (1,8)-(1,11)) ├── flags: ignore_visibility diff --git a/test/prism/snapshots/seattlerb/str_str.txt b/test/prism/snapshots/seattlerb/str_str.txt index f3f1213a0c..97031c8a65 100644 --- a/test/prism/snapshots/seattlerb/str_str.txt +++ b/test/prism/snapshots/seattlerb/str_str.txt @@ -4,7 +4,7 @@ @ StatementsNode (location: (1,0)-(1,10)) └── body: (length: 1) └── @ InterpolatedStringNode (location: (1,0)-(1,10)) - ├── flags: ∅ + ├── flags: mutable ├── opening_loc: (1,0)-(1,1) = "\"" ├── parts: (length: 2) │ ├── @ StringNode (location: (1,1)-(1,3)) @@ -19,7 +19,7 @@ │ │ @ StatementsNode (location: (1,5)-(1,8)) │ │ └── body: (length: 1) │ │ └── @ StringNode (location: (1,5)-(1,8)) - │ │ ├── flags: ∅ + │ │ ├── flags: frozen │ │ ├── opening_loc: (1,5)-(1,6) = "'" │ │ ├── content_loc: (1,6)-(1,7) = "b" │ │ ├── closing_loc: (1,7)-(1,8) = "'" diff --git a/test/prism/snapshots/seattlerb/str_str_str.txt b/test/prism/snapshots/seattlerb/str_str_str.txt index b01f2b5794..b592d380ef 100644 --- a/test/prism/snapshots/seattlerb/str_str_str.txt +++ b/test/prism/snapshots/seattlerb/str_str_str.txt @@ -4,7 +4,7 @@ @ StatementsNode (location: (1,0)-(1,12)) └── body: (length: 1) └── @ InterpolatedStringNode (location: (1,0)-(1,12)) - ├── flags: ∅ + ├── flags: mutable ├── opening_loc: (1,0)-(1,1) = "\"" ├── parts: (length: 3) │ ├── @ StringNode (location: (1,1)-(1,3)) @@ -19,7 +19,7 @@ │ │ │ @ StatementsNode (location: (1,5)-(1,8)) │ │ │ └── body: (length: 1) │ │ │ └── @ StringNode (location: (1,5)-(1,8)) - │ │ │ ├── flags: ∅ + │ │ │ ├── flags: frozen │ │ │ ├── opening_loc: (1,5)-(1,6) = "'" │ │ │ ├── content_loc: (1,6)-(1,7) = "b" │ │ │ ├── closing_loc: (1,7)-(1,8) = "'" diff --git a/test/prism/snapshots/symbols.txt b/test/prism/snapshots/symbols.txt index dbd3a4d030..48ff0d634f 100644 --- a/test/prism/snapshots/symbols.txt +++ b/test/prism/snapshots/symbols.txt @@ -146,10 +146,9 @@ │ │ ├── @ FloatNode (location: (29,4)-(29,7)) │ │ │ └── value: 1.0 │ │ ├── @ RationalNode (location: (29,9)-(29,11)) - │ │ │ └── numeric: - │ │ │ @ IntegerNode (location: (29,9)-(29,10)) - │ │ │ ├── flags: decimal - │ │ │ └── value: 1 + │ │ │ ├── flags: decimal + │ │ │ ├── numerator: 1 + │ │ │ └── denominator: 1 │ │ └── @ ImaginaryNode (location: (29,13)-(29,15)) │ │ └── numeric: │ │ @ IntegerNode (location: (29,13)-(29,14)) diff --git a/test/prism/snapshots/unparser/corpus/literal/assignment.txt b/test/prism/snapshots/unparser/corpus/literal/assignment.txt index 99c8daf34c..7d3cc389c6 100644 --- a/test/prism/snapshots/unparser/corpus/literal/assignment.txt +++ b/test/prism/snapshots/unparser/corpus/literal/assignment.txt @@ -469,18 +469,16 @@ │ ├── target: │ │ @ ConstantPathNode (location: (18,0)-(18,5)) │ │ ├── parent: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (18,2)-(18,5)) - │ │ │ └── name: :Foo - │ │ └── delimiter_loc: (18,0)-(18,2) = "::" + │ │ ├── name: :Foo + │ │ ├── delimiter_loc: (18,0)-(18,2) = "::" + │ │ └── name_loc: (18,2)-(18,5) = "Foo" │ ├── operator_loc: (18,6)-(18,7) = "=" │ └── value: │ @ ConstantPathNode (location: (18,8)-(18,13)) │ ├── parent: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (18,10)-(18,13)) - │ │ └── name: :Bar - │ └── delimiter_loc: (18,8)-(18,10) = "::" + │ ├── name: :Bar + │ ├── delimiter_loc: (18,8)-(18,10) = "::" + │ └── name_loc: (18,10)-(18,13) = "Bar" ├── @ ClassVariableWriteNode (location: (19,0)-(19,7)) │ ├── name: :@@a │ ├── name_loc: (19,0)-(19,3) = "@@a" @@ -513,14 +511,12 @@ │ │ │ ├── parent: │ │ │ │ @ ConstantReadNode (location: (22,0)-(22,4)) │ │ │ │ └── name: :Name - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (22,6)-(22,12)) - │ │ │ │ └── name: :Spaced - │ │ │ └── delimiter_loc: (22,4)-(22,6) = "::" - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (22,14)-(22,19)) - │ │ │ └── name: :CONST - │ │ └── delimiter_loc: (22,12)-(22,14) = "::" + │ │ │ ├── name: :Spaced + │ │ │ ├── delimiter_loc: (22,4)-(22,6) = "::" + │ │ │ └── name_loc: (22,6)-(22,12) = "Spaced" + │ │ ├── name: :CONST + │ │ ├── delimiter_loc: (22,12)-(22,14) = "::" + │ │ └── name_loc: (22,14)-(22,19) = "CONST" │ ├── operator_loc: (22,20)-(22,21) = "=" │ └── value: │ @ IntegerNode (location: (22,22)-(22,23)) diff --git a/test/prism/snapshots/unparser/corpus/literal/class.txt b/test/prism/snapshots/unparser/corpus/literal/class.txt index 34eb03edb3..5306888398 100644 --- a/test/prism/snapshots/unparser/corpus/literal/class.txt +++ b/test/prism/snapshots/unparser/corpus/literal/class.txt @@ -68,10 +68,9 @@ │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (11,6)-(11,7)) │ │ │ └── name: :A - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (11,9)-(11,10)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (11,7)-(11,9) = "::" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (11,7)-(11,9) = "::" + │ │ └── name_loc: (11,9)-(11,10) = "B" │ ├── inheritance_operator_loc: ∅ │ ├── superclass: ∅ │ ├── body: ∅ @@ -87,14 +86,12 @@ │ │ │ ├── parent: │ │ │ │ @ ConstantReadNode (location: (14,6)-(14,7)) │ │ │ │ └── name: :A - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (14,9)-(14,10)) - │ │ │ │ └── name: :B - │ │ │ └── delimiter_loc: (14,7)-(14,9) = "::" - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (14,12)-(14,13)) - │ │ │ └── name: :C - │ │ └── delimiter_loc: (14,10)-(14,12) = "::" + │ │ │ ├── name: :B + │ │ │ ├── delimiter_loc: (14,7)-(14,9) = "::" + │ │ │ └── name_loc: (14,9)-(14,10) = "B" + │ │ ├── name: :C + │ │ ├── delimiter_loc: (14,10)-(14,12) = "::" + │ │ └── name_loc: (14,12)-(14,13) = "C" │ ├── inheritance_operator_loc: ∅ │ ├── superclass: ∅ │ ├── body: ∅ @@ -125,10 +122,9 @@ │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (20,10)-(20,11)) │ │ │ └── name: :B - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (20,13)-(20,14)) - │ │ │ └── name: :C - │ │ └── delimiter_loc: (20,11)-(20,13) = "::" + │ │ ├── name: :C + │ │ ├── delimiter_loc: (20,11)-(20,13) = "::" + │ │ └── name_loc: (20,13)-(20,14) = "C" │ ├── body: ∅ │ ├── end_keyword_loc: (21,0)-(21,3) = "end" │ └── name: :A @@ -140,20 +136,18 @@ │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (23,6)-(23,7)) │ │ │ └── name: :A - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (23,9)-(23,10)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (23,7)-(23,9) = "::" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (23,7)-(23,9) = "::" + │ │ └── name_loc: (23,9)-(23,10) = "B" │ ├── inheritance_operator_loc: (23,11)-(23,12) = "<" │ ├── superclass: │ │ @ ConstantPathNode (location: (23,13)-(23,17)) │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (23,13)-(23,14)) │ │ │ └── name: :C - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (23,16)-(23,17)) - │ │ │ └── name: :D - │ │ └── delimiter_loc: (23,14)-(23,16) = "::" + │ │ ├── name: :D + │ │ ├── delimiter_loc: (23,14)-(23,16) = "::" + │ │ └── name_loc: (23,16)-(23,17) = "D" │ ├── body: ∅ │ ├── end_keyword_loc: (24,0)-(24,3) = "end" │ └── name: :B @@ -222,10 +216,9 @@ ├── constant_path: │ @ ConstantPathNode (location: (34,6)-(34,9)) │ ├── parent: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (34,8)-(34,9)) - │ │ └── name: :A - │ └── delimiter_loc: (34,6)-(34,8) = "::" + │ ├── name: :A + │ ├── delimiter_loc: (34,6)-(34,8) = "::" + │ └── name_loc: (34,8)-(34,9) = "A" ├── inheritance_operator_loc: ∅ ├── superclass: ∅ ├── body: ∅ diff --git a/test/prism/snapshots/unparser/corpus/literal/defs.txt b/test/prism/snapshots/unparser/corpus/literal/defs.txt index 431843cc19..7858877172 100644 --- a/test/prism/snapshots/unparser/corpus/literal/defs.txt +++ b/test/prism/snapshots/unparser/corpus/literal/defs.txt @@ -225,10 +225,9 @@ │ │ │ │ ├── parent: │ │ │ │ │ @ ConstantReadNode (location: (26,5)-(26,8)) │ │ │ │ │ └── name: :Foo - │ │ │ │ ├── child: - │ │ │ │ │ @ ConstantReadNode (location: (26,10)-(26,13)) - │ │ │ │ │ └── name: :Bar - │ │ │ │ └── delimiter_loc: (26,8)-(26,10) = "::" + │ │ │ │ ├── name: :Bar + │ │ │ │ ├── delimiter_loc: (26,8)-(26,10) = "::" + │ │ │ │ └── name_loc: (26,10)-(26,13) = "Bar" │ │ │ ├── call_operator_loc: (26,13)-(26,14) = "." │ │ │ ├── name: :baz │ │ │ ├── message_loc: (26,14)-(26,17) = "baz" @@ -269,10 +268,9 @@ │ │ │ ├── parent: │ │ │ │ @ ConstantReadNode (location: (30,5)-(30,8)) │ │ │ │ └── name: :Foo - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (30,10)-(30,13)) - │ │ │ │ └── name: :Bar - │ │ │ └── delimiter_loc: (30,8)-(30,10) = "::" + │ │ │ ├── name: :Bar + │ │ │ ├── delimiter_loc: (30,8)-(30,10) = "::" + │ │ │ └── name_loc: (30,10)-(30,13) = "Bar" │ │ ├── opening_loc: (30,4)-(30,5) = "(" │ │ └── closing_loc: (30,13)-(30,14) = ")" │ ├── parameters: ∅ diff --git a/test/prism/snapshots/unparser/corpus/literal/literal.txt b/test/prism/snapshots/unparser/corpus/literal/literal.txt index dcf00bf4e0..ddb10456bf 100644 --- a/test/prism/snapshots/unparser/corpus/literal/literal.txt +++ b/test/prism/snapshots/unparser/corpus/literal/literal.txt @@ -316,18 +316,17 @@ │ ├── flags: decimal │ └── value: 1 ├── @ RationalNode (location: (19,0)-(19,2)) - │ └── numeric: - │ @ IntegerNode (location: (19,0)-(19,1)) - │ ├── flags: decimal - │ └── value: 1 + │ ├── flags: decimal + │ ├── numerator: 1 + │ └── denominator: 1 ├── @ RationalNode (location: (20,0)-(20,4)) - │ └── numeric: - │ @ FloatNode (location: (20,0)-(20,3)) - │ └── value: 1.5 + │ ├── flags: decimal + │ ├── numerator: 3 + │ └── denominator: 2 ├── @ RationalNode (location: (21,0)-(21,4)) - │ └── numeric: - │ @ FloatNode (location: (21,0)-(21,3)) - │ └── value: 1.3 + │ ├── flags: decimal + │ ├── numerator: 13 + │ └── denominator: 10 ├── @ ImaginaryNode (location: (22,0)-(22,2)) │ └── numeric: │ @ IntegerNode (location: (22,0)-(22,1)) @@ -354,10 +353,9 @@ ├── @ ImaginaryNode (location: (27,0)-(27,3)) │ └── numeric: │ @ RationalNode (location: (27,0)-(27,2)) - │ └── numeric: - │ @ IntegerNode (location: (27,0)-(27,1)) - │ ├── flags: decimal - │ └── value: 1 + │ ├── flags: decimal + │ ├── numerator: 1 + │ └── denominator: 1 ├── @ InterpolatedStringNode (location: (28,0)-(28,11)) │ ├── flags: ∅ │ ├── opening_loc: ∅ @@ -635,7 +633,7 @@ │ │ │ @ StatementsNode (location: (53,3)-(53,11)) │ │ │ └── body: (length: 1) │ │ │ └── @ StringNode (location: (53,3)-(53,11)) - │ │ │ ├── flags: ∅ + │ │ │ ├── flags: frozen │ │ │ ├── opening_loc: (53,3)-(53,4) = "\"" │ │ │ ├── content_loc: (53,4)-(53,10) = "\\u0000" │ │ │ ├── closing_loc: (53,10)-(53,11) = "\"" @@ -707,7 +705,7 @@ │ │ │ @ StatementsNode (location: (59,4)-(59,9)) │ │ │ └── body: (length: 1) │ │ │ └── @ StringNode (location: (59,4)-(59,9)) - │ │ │ ├── flags: ∅ + │ │ │ ├── flags: frozen │ │ │ ├── opening_loc: (59,4)-(59,5) = "\"" │ │ │ ├── content_loc: (59,5)-(59,8) = "foo" │ │ │ ├── closing_loc: (59,8)-(59,9) = "\"" diff --git a/test/prism/snapshots/unparser/corpus/literal/module.txt b/test/prism/snapshots/unparser/corpus/literal/module.txt index 5dd8c03b51..6428aeea82 100644 --- a/test/prism/snapshots/unparser/corpus/literal/module.txt +++ b/test/prism/snapshots/unparser/corpus/literal/module.txt @@ -20,10 +20,9 @@ │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (4,7)-(4,8)) │ │ │ └── name: :A - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (4,10)-(4,11)) - │ │ │ └── name: :B - │ │ └── delimiter_loc: (4,8)-(4,10) = "::" + │ │ ├── name: :B + │ │ ├── delimiter_loc: (4,8)-(4,10) = "::" + │ │ └── name_loc: (4,10)-(4,11) = "B" │ ├── body: ∅ │ ├── end_keyword_loc: (5,0)-(5,3) = "end" │ └── name: :B @@ -37,14 +36,12 @@ │ │ │ ├── parent: │ │ │ │ @ ConstantReadNode (location: (7,7)-(7,8)) │ │ │ │ └── name: :A - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (7,10)-(7,11)) - │ │ │ │ └── name: :B - │ │ │ └── delimiter_loc: (7,8)-(7,10) = "::" - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (7,13)-(7,14)) - │ │ │ └── name: :C - │ │ └── delimiter_loc: (7,11)-(7,13) = "::" + │ │ │ ├── name: :B + │ │ │ ├── delimiter_loc: (7,8)-(7,10) = "::" + │ │ │ └── name_loc: (7,10)-(7,11) = "B" + │ │ ├── name: :C + │ │ ├── delimiter_loc: (7,11)-(7,13) = "::" + │ │ └── name_loc: (7,13)-(7,14) = "C" │ ├── body: ∅ │ ├── end_keyword_loc: (8,0)-(8,3) = "end" │ └── name: :C diff --git a/test/prism/snapshots/unparser/corpus/literal/opasgn.txt b/test/prism/snapshots/unparser/corpus/literal/opasgn.txt index 8dc0849638..0761b47348 100644 --- a/test/prism/snapshots/unparser/corpus/literal/opasgn.txt +++ b/test/prism/snapshots/unparser/corpus/literal/opasgn.txt @@ -5,53 +5,53 @@ └── body: (length: 24) ├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,6)) │ ├── name_loc: (1,0)-(1,1) = "a" - │ ├── operator_loc: (1,2)-(1,4) = "+=" + │ ├── binary_operator_loc: (1,2)-(1,4) = "+=" │ ├── value: │ │ @ IntegerNode (location: (1,5)-(1,6)) │ │ ├── flags: decimal │ │ └── value: 2 │ ├── name: :a - │ ├── operator: :+ + │ ├── binary_operator: :+ │ └── depth: 0 ├── @ LocalVariableOperatorWriteNode (location: (2,0)-(2,6)) │ ├── name_loc: (2,0)-(2,1) = "a" - │ ├── operator_loc: (2,2)-(2,4) = "-=" + │ ├── binary_operator_loc: (2,2)-(2,4) = "-=" │ ├── value: │ │ @ IntegerNode (location: (2,5)-(2,6)) │ │ ├── flags: decimal │ │ └── value: 2 │ ├── name: :a - │ ├── operator: :- + │ ├── binary_operator: :- │ └── depth: 0 ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,7)) │ ├── name_loc: (3,0)-(3,1) = "a" - │ ├── operator_loc: (3,2)-(3,5) = "**=" + │ ├── binary_operator_loc: (3,2)-(3,5) = "**=" │ ├── value: │ │ @ IntegerNode (location: (3,6)-(3,7)) │ │ ├── flags: decimal │ │ └── value: 2 │ ├── name: :a - │ ├── operator: :** + │ ├── binary_operator: :** │ └── depth: 0 ├── @ LocalVariableOperatorWriteNode (location: (4,0)-(4,6)) │ ├── name_loc: (4,0)-(4,1) = "a" - │ ├── operator_loc: (4,2)-(4,4) = "*=" + │ ├── binary_operator_loc: (4,2)-(4,4) = "*=" │ ├── value: │ │ @ IntegerNode (location: (4,5)-(4,6)) │ │ ├── flags: decimal │ │ └── value: 2 │ ├── name: :a - │ ├── operator: :* + │ ├── binary_operator: :* │ └── depth: 0 ├── @ LocalVariableOperatorWriteNode (location: (5,0)-(5,6)) │ ├── name_loc: (5,0)-(5,1) = "a" - │ ├── operator_loc: (5,2)-(5,4) = "/=" + │ ├── binary_operator_loc: (5,2)-(5,4) = "/=" │ ├── value: │ │ @ IntegerNode (location: (5,5)-(5,6)) │ │ ├── flags: decimal │ │ └── value: 2 │ ├── name: :a - │ ├── operator: :/ + │ ├── binary_operator: :/ │ └── depth: 0 ├── @ LocalVariableAndWriteNode (location: (6,0)-(6,7)) │ ├── name_loc: (6,0)-(6,1) = "a" @@ -162,8 +162,8 @@ │ ├── message_loc: (10,2)-(10,3) = "b" │ ├── read_name: :b │ ├── write_name: :b= - │ ├── operator: :+ - │ ├── operator_loc: (10,4)-(10,6) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (10,4)-(10,6) = "+=" │ └── value: │ @ IntegerNode (location: (10,7)-(10,8)) │ ├── flags: decimal @@ -178,8 +178,8 @@ │ ├── message_loc: (11,2)-(11,3) = "b" │ ├── read_name: :b │ ├── write_name: :b= - │ ├── operator: :- - │ ├── operator_loc: (11,4)-(11,6) = "-=" + │ ├── binary_operator: :- + │ ├── binary_operator_loc: (11,4)-(11,6) = "-=" │ └── value: │ @ IntegerNode (location: (11,7)-(11,8)) │ ├── flags: decimal @@ -194,8 +194,8 @@ │ ├── message_loc: (12,2)-(12,3) = "b" │ ├── read_name: :b │ ├── write_name: :b= - │ ├── operator: :** - │ ├── operator_loc: (12,4)-(12,7) = "**=" + │ ├── binary_operator: :** + │ ├── binary_operator_loc: (12,4)-(12,7) = "**=" │ └── value: │ @ IntegerNode (location: (12,8)-(12,9)) │ ├── flags: decimal @@ -210,8 +210,8 @@ │ ├── message_loc: (13,2)-(13,3) = "b" │ ├── read_name: :b │ ├── write_name: :b= - │ ├── operator: :* - │ ├── operator_loc: (13,4)-(13,6) = "*=" + │ ├── binary_operator: :* + │ ├── binary_operator_loc: (13,4)-(13,6) = "*=" │ └── value: │ @ IntegerNode (location: (13,7)-(13,8)) │ ├── flags: decimal @@ -226,8 +226,8 @@ │ ├── message_loc: (14,2)-(14,3) = "b" │ ├── read_name: :b │ ├── write_name: :b= - │ ├── operator: :/ - │ ├── operator_loc: (14,4)-(14,6) = "/=" + │ ├── binary_operator: :/ + │ ├── binary_operator_loc: (14,4)-(14,6) = "/=" │ └── value: │ @ IntegerNode (location: (14,7)-(14,8)) │ ├── flags: decimal @@ -293,8 +293,8 @@ │ │ └── block: ∅ │ ├── closing_loc: (17,3)-(17,4) = "]" │ ├── block: ∅ - │ ├── operator: :+ - │ ├── operator_loc: (17,5)-(17,7) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (17,5)-(17,7) = "+=" │ └── value: │ @ IntegerNode (location: (17,8)-(17,9)) │ ├── flags: decimal @@ -323,8 +323,8 @@ │ │ └── block: ∅ │ ├── closing_loc: (18,3)-(18,4) = "]" │ ├── block: ∅ - │ ├── operator: :- - │ ├── operator_loc: (18,5)-(18,7) = "-=" + │ ├── binary_operator: :- + │ ├── binary_operator_loc: (18,5)-(18,7) = "-=" │ └── value: │ @ IntegerNode (location: (18,8)-(18,9)) │ ├── flags: decimal @@ -353,8 +353,8 @@ │ │ └── block: ∅ │ ├── closing_loc: (19,3)-(19,4) = "]" │ ├── block: ∅ - │ ├── operator: :** - │ ├── operator_loc: (19,5)-(19,8) = "**=" + │ ├── binary_operator: :** + │ ├── binary_operator_loc: (19,5)-(19,8) = "**=" │ └── value: │ @ IntegerNode (location: (19,9)-(19,10)) │ ├── flags: decimal @@ -383,8 +383,8 @@ │ │ └── block: ∅ │ ├── closing_loc: (20,3)-(20,4) = "]" │ ├── block: ∅ - │ ├── operator: :* - │ ├── operator_loc: (20,5)-(20,7) = "*=" + │ ├── binary_operator: :* + │ ├── binary_operator_loc: (20,5)-(20,7) = "*=" │ └── value: │ @ IntegerNode (location: (20,8)-(20,9)) │ ├── flags: decimal @@ -413,8 +413,8 @@ │ │ └── block: ∅ │ ├── closing_loc: (21,3)-(21,4) = "]" │ ├── block: ∅ - │ ├── operator: :/ - │ ├── operator_loc: (21,5)-(21,7) = "/=" + │ ├── binary_operator: :/ + │ ├── binary_operator_loc: (21,5)-(21,7) = "/=" │ └── value: │ @ IntegerNode (location: (21,8)-(21,9)) │ ├── flags: decimal @@ -501,8 +501,8 @@ ├── message_loc: (24,4)-(24,5) = "A" ├── read_name: :A ├── write_name: :A= - ├── operator: :+ - ├── operator_loc: (24,6)-(24,8) = "+=" + ├── binary_operator: :+ + ├── binary_operator_loc: (24,6)-(24,8) = "+=" └── value: @ IntegerNode (location: (24,9)-(24,10)) ├── flags: decimal diff --git a/test/prism/snapshots/unparser/corpus/literal/send.txt b/test/prism/snapshots/unparser/corpus/literal/send.txt index b7eb064717..3fd7f719a1 100644 --- a/test/prism/snapshots/unparser/corpus/literal/send.txt +++ b/test/prism/snapshots/unparser/corpus/literal/send.txt @@ -1251,7 +1251,7 @@ │ ├── opening_loc: (63,7)-(63,8) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (63,8)-(63,16)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (63,8)-(63,16)) │ │ ├── flags: symbol_keys @@ -1297,7 +1297,7 @@ │ ├── opening_loc: (64,7)-(64,8) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (64,8)-(64,25)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 2) │ │ ├── @ CallNode (location: (64,8)-(64,11)) │ │ │ ├── flags: variable_call, ignore_visibility @@ -1571,7 +1571,7 @@ │ ├── opening_loc: (70,3)-(70,4) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (70,4)-(70,8)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (70,4)-(70,8)) │ │ ├── flags: symbol_keys @@ -1617,7 +1617,7 @@ │ ├── opening_loc: (71,5)-(71,6) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (71,6)-(71,10)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (71,6)-(71,10)) │ │ ├── flags: symbol_keys @@ -1663,7 +1663,7 @@ │ ├── opening_loc: (72,5)-(72,6) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (72,6)-(72,9)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (72,6)-(72,9)) │ │ ├── flags: ∅ @@ -2082,7 +2082,7 @@ │ ├── opening_loc: (81,1)-(81,2) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (81,2)-(81,7)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (81,2)-(81,7)) │ │ ├── flags: ∅ diff --git a/test/prism/snapshots/unparser/corpus/literal/since/32.txt b/test/prism/snapshots/unparser/corpus/literal/since/32.txt index e72be6d8b7..2b28be2fa8 100644 --- a/test/prism/snapshots/unparser/corpus/literal/since/32.txt +++ b/test/prism/snapshots/unparser/corpus/literal/since/32.txt @@ -36,7 +36,7 @@ │ │ ├── opening_loc: (2,5)-(2,6) = "(" │ │ ├── arguments: │ │ │ @ ArgumentsNode (location: (2,6)-(2,18)) - │ │ │ ├── flags: contains_keyword_splat + │ │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ │ └── arguments: (length: 2) │ │ │ ├── @ LocalVariableReadNode (location: (2,6)-(2,14)) │ │ │ │ ├── name: :argument diff --git a/test/prism/snapshots/unparser/corpus/literal/variables.txt b/test/prism/snapshots/unparser/corpus/literal/variables.txt index bf79de385c..9ae8ad1207 100644 --- a/test/prism/snapshots/unparser/corpus/literal/variables.txt +++ b/test/prism/snapshots/unparser/corpus/literal/variables.txt @@ -29,25 +29,21 @@ │ ├── parent: │ │ @ ConstantReadNode (location: (8,0)-(8,6)) │ │ └── name: :SCOPED - │ ├── child: - │ │ @ ConstantReadNode (location: (8,8)-(8,13)) - │ │ └── name: :CONST - │ └── delimiter_loc: (8,6)-(8,8) = "::" + │ ├── name: :CONST + │ ├── delimiter_loc: (8,6)-(8,8) = "::" + │ └── name_loc: (8,8)-(8,13) = "CONST" ├── @ ConstantPathNode (location: (9,0)-(9,10)) │ ├── parent: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (9,2)-(9,10)) - │ │ └── name: :TOPLEVEL - │ └── delimiter_loc: (9,0)-(9,2) = "::" + │ ├── name: :TOPLEVEL + │ ├── delimiter_loc: (9,0)-(9,2) = "::" + │ └── name_loc: (9,2)-(9,10) = "TOPLEVEL" └── @ ConstantPathNode (location: (10,0)-(10,17)) ├── parent: │ @ ConstantPathNode (location: (10,0)-(10,10)) │ ├── parent: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (10,2)-(10,10)) - │ │ └── name: :TOPLEVEL - │ └── delimiter_loc: (10,0)-(10,2) = "::" - ├── child: - │ @ ConstantReadNode (location: (10,12)-(10,17)) - │ └── name: :CONST - └── delimiter_loc: (10,10)-(10,12) = "::" + │ ├── name: :TOPLEVEL + │ ├── delimiter_loc: (10,0)-(10,2) = "::" + │ └── name_loc: (10,2)-(10,10) = "TOPLEVEL" + ├── name: :CONST + ├── delimiter_loc: (10,10)-(10,12) = "::" + └── name_loc: (10,12)-(10,17) = "CONST" diff --git a/test/prism/snapshots/unparser/corpus/semantic/literal.txt b/test/prism/snapshots/unparser/corpus/semantic/literal.txt index ef666890be..448207f5d3 100644 --- a/test/prism/snapshots/unparser/corpus/semantic/literal.txt +++ b/test/prism/snapshots/unparser/corpus/semantic/literal.txt @@ -4,14 +4,13 @@ @ StatementsNode (location: (1,0)-(14,10)) └── body: (length: 14) ├── @ RationalNode (location: (1,0)-(1,4)) - │ └── numeric: - │ @ FloatNode (location: (1,0)-(1,3)) - │ └── value: 1.0 + │ ├── flags: decimal + │ ├── numerator: 1 + │ └── denominator: 1 ├── @ RationalNode (location: (2,0)-(2,3)) - │ └── numeric: - │ @ IntegerNode (location: (2,0)-(2,2)) - │ ├── flags: decimal - │ └── value: 0 + │ ├── flags: decimal + │ ├── numerator: 0 + │ └── denominator: 1 ├── @ IntegerNode (location: (3,0)-(3,3)) │ ├── flags: hexadecimal │ └── value: 1 diff --git a/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt b/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt index e100dd8ecb..7dd26a38dc 100644 --- a/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt +++ b/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt @@ -44,8 +44,8 @@ │ └── closing_loc: (1,10)-(1,11) = "\"" ├── closing_loc: (1,11)-(1,12) = "]" ├── block: ∅ - ├── operator: :+ - ├── operator_loc: (1,13)-(1,15) = "+=" + ├── binary_operator: :+ + ├── binary_operator_loc: (1,13)-(1,15) = "+=" └── value: @ InterpolatedStringNode (location: (1,16)-(1,25)) ├── flags: ∅ diff --git a/test/prism/snapshots/whitequark/args_args_assocs.txt b/test/prism/snapshots/whitequark/args_args_assocs.txt index 6297f212d8..d257a885ce 100644 --- a/test/prism/snapshots/whitequark/args_args_assocs.txt +++ b/test/prism/snapshots/whitequark/args_args_assocs.txt @@ -12,7 +12,7 @@ │ ├── opening_loc: (1,3)-(1,4) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (1,4)-(1,18)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 2) │ │ ├── @ CallNode (location: (1,4)-(1,7)) │ │ │ ├── flags: variable_call, ignore_visibility @@ -51,7 +51,7 @@ ├── opening_loc: (3,3)-(3,4) = "(" ├── arguments: │ @ ArgumentsNode (location: (3,4)-(3,18)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 2) │ ├── @ CallNode (location: (3,4)-(3,7)) │ │ ├── flags: variable_call, ignore_visibility diff --git a/test/prism/snapshots/whitequark/args_args_assocs_comma.txt b/test/prism/snapshots/whitequark/args_args_assocs_comma.txt index 969514a511..2d986dd90a 100644 --- a/test/prism/snapshots/whitequark/args_args_assocs_comma.txt +++ b/test/prism/snapshots/whitequark/args_args_assocs_comma.txt @@ -22,7 +22,7 @@ ├── opening_loc: (1,3)-(1,4) = "[" ├── arguments: │ @ ArgumentsNode (location: (1,4)-(1,18)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 2) │ ├── @ CallNode (location: (1,4)-(1,7)) │ │ ├── flags: variable_call, ignore_visibility diff --git a/test/prism/snapshots/whitequark/args_assocs_comma.txt b/test/prism/snapshots/whitequark/args_assocs_comma.txt index b1b9fbeefe..64a25bbc45 100644 --- a/test/prism/snapshots/whitequark/args_assocs_comma.txt +++ b/test/prism/snapshots/whitequark/args_assocs_comma.txt @@ -22,7 +22,7 @@ ├── opening_loc: (1,3)-(1,4) = "[" ├── arguments: │ @ ArgumentsNode (location: (1,4)-(1,13)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,4)-(1,13)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/whitequark/bug_cmdarg.txt b/test/prism/snapshots/whitequark/bug_cmdarg.txt index 509dd7e818..32d05746a7 100644 --- a/test/prism/snapshots/whitequark/bug_cmdarg.txt +++ b/test/prism/snapshots/whitequark/bug_cmdarg.txt @@ -12,7 +12,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (1,7)-(1,15)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (1,7)-(1,15)) │ │ ├── flags: symbol_keys @@ -62,7 +62,7 @@ ├── opening_loc: ∅ ├── arguments: │ @ ArgumentsNode (location: (5,2)-(5,26)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (5,2)-(5,26)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/whitequark/casgn_scoped.txt b/test/prism/snapshots/whitequark/casgn_scoped.txt index 4e3fd6fe44..42b90be061 100644 --- a/test/prism/snapshots/whitequark/casgn_scoped.txt +++ b/test/prism/snapshots/whitequark/casgn_scoped.txt @@ -9,10 +9,9 @@ │ ├── parent: │ │ @ ConstantReadNode (location: (1,0)-(1,3)) │ │ └── name: :Bar - │ ├── child: - │ │ @ ConstantReadNode (location: (1,5)-(1,8)) - │ │ └── name: :Foo - │ └── delimiter_loc: (1,3)-(1,5) = "::" + │ ├── name: :Foo + │ ├── delimiter_loc: (1,3)-(1,5) = "::" + │ └── name_loc: (1,5)-(1,8) = "Foo" ├── operator_loc: (1,9)-(1,10) = "=" └── value: @ IntegerNode (location: (1,11)-(1,13)) diff --git a/test/prism/snapshots/whitequark/casgn_toplevel.txt b/test/prism/snapshots/whitequark/casgn_toplevel.txt index 11facfefb3..070d90a46b 100644 --- a/test/prism/snapshots/whitequark/casgn_toplevel.txt +++ b/test/prism/snapshots/whitequark/casgn_toplevel.txt @@ -7,10 +7,9 @@ ├── target: │ @ ConstantPathNode (location: (1,0)-(1,5)) │ ├── parent: ∅ - │ ├── child: - │ │ @ ConstantReadNode (location: (1,2)-(1,5)) - │ │ └── name: :Foo - │ └── delimiter_loc: (1,0)-(1,2) = "::" + │ ├── name: :Foo + │ ├── delimiter_loc: (1,0)-(1,2) = "::" + │ └── name_loc: (1,2)-(1,5) = "Foo" ├── operator_loc: (1,6)-(1,7) = "=" └── value: @ IntegerNode (location: (1,8)-(1,10)) diff --git a/test/prism/snapshots/whitequark/complex.txt b/test/prism/snapshots/whitequark/complex.txt index e688585a5f..bc748db09b 100644 --- a/test/prism/snapshots/whitequark/complex.txt +++ b/test/prism/snapshots/whitequark/complex.txt @@ -10,9 +10,9 @@ ├── @ ImaginaryNode (location: (3,0)-(3,6)) │ └── numeric: │ @ RationalNode (location: (3,0)-(3,5)) - │ └── numeric: - │ @ FloatNode (location: (3,0)-(3,4)) - │ └── value: 42.1 + │ ├── flags: decimal + │ ├── numerator: 421 + │ └── denominator: 10 ├── @ ImaginaryNode (location: (5,0)-(5,3)) │ └── numeric: │ @ IntegerNode (location: (5,0)-(5,2)) @@ -21,7 +21,6 @@ └── @ ImaginaryNode (location: (7,0)-(7,4)) └── numeric: @ RationalNode (location: (7,0)-(7,3)) - └── numeric: - @ IntegerNode (location: (7,0)-(7,2)) - ├── flags: decimal - └── value: 42 + ├── flags: decimal + ├── numerator: 42 + └── denominator: 1 diff --git a/test/prism/snapshots/whitequark/const_op_asgn.txt b/test/prism/snapshots/whitequark/const_op_asgn.txt index 4985f3e54b..71df6208d2 100644 --- a/test/prism/snapshots/whitequark/const_op_asgn.txt +++ b/test/prism/snapshots/whitequark/const_op_asgn.txt @@ -7,41 +7,39 @@ │ ├── target: │ │ @ ConstantPathNode (location: (1,0)-(1,3)) │ │ ├── parent: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (1,2)-(1,3)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (1,0)-(1,2) = "::" - │ ├── operator_loc: (1,4)-(1,6) = "+=" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (1,0)-(1,2) = "::" + │ │ └── name_loc: (1,2)-(1,3) = "A" + │ ├── binary_operator_loc: (1,4)-(1,6) = "+=" │ ├── value: │ │ @ IntegerNode (location: (1,7)-(1,8)) │ │ ├── flags: decimal │ │ └── value: 1 - │ └── operator: :+ + │ └── binary_operator: :+ ├── @ ConstantOperatorWriteNode (location: (3,0)-(3,6)) │ ├── name: :A │ ├── name_loc: (3,0)-(3,1) = "A" - │ ├── operator_loc: (3,2)-(3,4) = "+=" + │ ├── binary_operator_loc: (3,2)-(3,4) = "+=" │ ├── value: │ │ @ IntegerNode (location: (3,5)-(3,6)) │ │ ├── flags: decimal │ │ └── value: 1 - │ └── operator: :+ + │ └── binary_operator: :+ ├── @ ConstantPathOperatorWriteNode (location: (5,0)-(5,9)) │ ├── target: │ │ @ ConstantPathNode (location: (5,0)-(5,4)) │ │ ├── parent: │ │ │ @ ConstantReadNode (location: (5,0)-(5,1)) │ │ │ └── name: :B - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (5,3)-(5,4)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (5,1)-(5,3) = "::" - │ ├── operator_loc: (5,5)-(5,7) = "+=" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (5,1)-(5,3) = "::" + │ │ └── name_loc: (5,3)-(5,4) = "A" + │ ├── binary_operator_loc: (5,5)-(5,7) = "+=" │ ├── value: │ │ @ IntegerNode (location: (5,8)-(5,9)) │ │ ├── flags: decimal │ │ └── value: 1 - │ └── operator: :+ + │ └── binary_operator: :+ ├── @ DefNode (location: (7,0)-(7,21)) │ ├── name: :x │ ├── name_loc: (7,4)-(7,5) = "x" @@ -54,10 +52,9 @@ │ │ ├── target: │ │ │ @ ConstantPathNode (location: (7,7)-(7,10)) │ │ │ ├── parent: ∅ - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (7,9)-(7,10)) - │ │ │ │ └── name: :A - │ │ │ └── delimiter_loc: (7,7)-(7,9) = "::" + │ │ │ ├── name: :A + │ │ │ ├── delimiter_loc: (7,7)-(7,9) = "::" + │ │ │ └── name_loc: (7,9)-(7,10) = "A" │ │ ├── operator_loc: (7,11)-(7,14) = "||=" │ │ └── value: │ │ @ IntegerNode (location: (7,15)-(7,16)) @@ -83,10 +80,9 @@ │ │ @ ConstantPathNode (location: (9,7)-(9,14)) │ │ ├── parent: │ │ │ @ SelfNode (location: (9,7)-(9,11)) - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (9,13)-(9,14)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (9,11)-(9,13) = "::" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (9,11)-(9,13) = "::" + │ │ └── name_loc: (9,13)-(9,14) = "A" │ ├── operator_loc: (9,15)-(9,18) = "||=" │ └── value: │ @ IntegerNode (location: (9,19)-(9,20)) diff --git a/test/prism/snapshots/whitequark/const_scoped.txt b/test/prism/snapshots/whitequark/const_scoped.txt index 1e2bccef96..83af4b187b 100644 --- a/test/prism/snapshots/whitequark/const_scoped.txt +++ b/test/prism/snapshots/whitequark/const_scoped.txt @@ -7,7 +7,6 @@ ├── parent: │ @ ConstantReadNode (location: (1,0)-(1,3)) │ └── name: :Bar - ├── child: - │ @ ConstantReadNode (location: (1,5)-(1,8)) - │ └── name: :Foo - └── delimiter_loc: (1,3)-(1,5) = "::" + ├── name: :Foo + ├── delimiter_loc: (1,3)-(1,5) = "::" + └── name_loc: (1,5)-(1,8) = "Foo" diff --git a/test/prism/snapshots/whitequark/const_toplevel.txt b/test/prism/snapshots/whitequark/const_toplevel.txt index b54b069d06..3d7df5defc 100644 --- a/test/prism/snapshots/whitequark/const_toplevel.txt +++ b/test/prism/snapshots/whitequark/const_toplevel.txt @@ -5,7 +5,6 @@ └── body: (length: 1) └── @ ConstantPathNode (location: (1,0)-(1,5)) ├── parent: ∅ - ├── child: - │ @ ConstantReadNode (location: (1,2)-(1,5)) - │ └── name: :Foo - └── delimiter_loc: (1,0)-(1,2) = "::" + ├── name: :Foo + ├── delimiter_loc: (1,0)-(1,2) = "::" + └── name_loc: (1,2)-(1,5) = "Foo" diff --git a/test/prism/snapshots/whitequark/cpath.txt b/test/prism/snapshots/whitequark/cpath.txt index b892525646..e801456bf7 100644 --- a/test/prism/snapshots/whitequark/cpath.txt +++ b/test/prism/snapshots/whitequark/cpath.txt @@ -9,10 +9,9 @@ │ ├── constant_path: │ │ @ ConstantPathNode (location: (1,7)-(1,12)) │ │ ├── parent: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (1,9)-(1,12)) - │ │ │ └── name: :Foo - │ │ └── delimiter_loc: (1,7)-(1,9) = "::" + │ │ ├── name: :Foo + │ │ ├── delimiter_loc: (1,7)-(1,9) = "::" + │ │ └── name_loc: (1,9)-(1,12) = "Foo" │ ├── body: ∅ │ ├── end_keyword_loc: (1,14)-(1,17) = "end" │ └── name: :Foo @@ -24,10 +23,9 @@ │ ├── parent: │ │ @ ConstantReadNode (location: (3,7)-(3,10)) │ │ └── name: :Bar - │ ├── child: - │ │ @ ConstantReadNode (location: (3,12)-(3,15)) - │ │ └── name: :Foo - │ └── delimiter_loc: (3,10)-(3,12) = "::" + │ ├── name: :Foo + │ ├── delimiter_loc: (3,10)-(3,12) = "::" + │ └── name_loc: (3,12)-(3,15) = "Foo" ├── body: ∅ ├── end_keyword_loc: (3,17)-(3,20) = "end" └── name: :Foo diff --git a/test/prism/snapshots/whitequark/dedenting_heredoc.txt b/test/prism/snapshots/whitequark/dedenting_heredoc.txt index acb79e83d2..67896b2415 100644 --- a/test/prism/snapshots/whitequark/dedenting_heredoc.txt +++ b/test/prism/snapshots/whitequark/dedenting_heredoc.txt @@ -15,7 +15,7 @@ │ │ ├── flags: ∅ │ │ └── arguments: (length: 1) │ │ └── @ InterpolatedStringNode (location: (1,2)-(1,8)) - │ │ ├── flags: ∅ + │ │ ├── flags: mutable │ │ ├── opening_loc: (1,2)-(1,8) = "<<~\"E\"" │ │ ├── parts: (length: 3) │ │ │ ├── @ StringNode (location: (2,0)-(3,0)) @@ -30,7 +30,7 @@ │ │ │ │ │ @ StatementsNode (location: (3,4)-(3,9)) │ │ │ │ │ └── body: (length: 1) │ │ │ │ │ └── @ StringNode (location: (3,4)-(3,9)) - │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ ├── flags: frozen │ │ │ │ │ ├── opening_loc: (3,4)-(3,5) = "\"" │ │ │ │ │ ├── content_loc: (3,5)-(3,8) = " y" │ │ │ │ │ ├── closing_loc: (3,8)-(3,9) = "\"" diff --git a/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt b/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt index c06818a98b..acaf9c052d 100644 --- a/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt +++ b/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt @@ -36,7 +36,7 @@ │ ├── opening_loc: (1,26)-(1,27) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (1,27)-(1,39)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 2) │ │ ├── @ LocalVariableReadNode (location: (1,27)-(1,35)) │ │ │ ├── name: :argument diff --git a/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt b/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt index adaf111fd7..b4235fb20a 100644 --- a/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt +++ b/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt @@ -33,7 +33,7 @@ │ ├── opening_loc: (1,16)-(1,17) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (1,17)-(1,19)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (1,17)-(1,19)) │ │ ├── flags: ∅ diff --git a/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt b/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt index a03421455c..33779abcc1 100644 --- a/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt +++ b/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt @@ -33,7 +33,7 @@ │ ├── opening_loc: (1,16)-(1,17) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (1,17)-(1,35)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (1,17)-(1,35)) │ │ ├── flags: ∅ diff --git a/test/prism/snapshots/whitequark/keyword_argument_omission.txt b/test/prism/snapshots/whitequark/keyword_argument_omission.txt index 62e8fecf4e..446b45b56b 100644 --- a/test/prism/snapshots/whitequark/keyword_argument_omission.txt +++ b/test/prism/snapshots/whitequark/keyword_argument_omission.txt @@ -12,7 +12,7 @@ ├── opening_loc: (1,3)-(1,4) = "(" ├── arguments: │ @ ArgumentsNode (location: (1,4)-(1,10)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,4)-(1,10)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt b/test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt index 6d0bdfb817..db281e2f0d 100644 --- a/test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt +++ b/test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt @@ -39,7 +39,7 @@ │ ├── opening_loc: (1,20)-(1,21) = "(" │ ├── arguments: │ │ @ ArgumentsNode (location: (1,21)-(1,23)) - │ │ ├── flags: contains_keyword_splat + │ │ ├── flags: contains_keywords, contains_keyword_splat │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (1,21)-(1,23)) │ │ ├── flags: ∅ diff --git a/test/prism/snapshots/whitequark/masgn_const.txt b/test/prism/snapshots/whitequark/masgn_const.txt index 56169deb17..ddfccb0d8b 100644 --- a/test/prism/snapshots/whitequark/masgn_const.txt +++ b/test/prism/snapshots/whitequark/masgn_const.txt @@ -7,10 +7,9 @@ │ ├── lefts: (length: 2) │ │ ├── @ ConstantPathTargetNode (location: (1,0)-(1,3)) │ │ │ ├── parent: ∅ - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (1,2)-(1,3)) - │ │ │ │ └── name: :A - │ │ │ └── delimiter_loc: (1,0)-(1,2) = "::" + │ │ │ ├── name: :A + │ │ │ ├── delimiter_loc: (1,0)-(1,2) = "::" + │ │ │ └── name_loc: (1,2)-(1,3) = "A" │ │ └── @ LocalVariableTargetNode (location: (1,5)-(1,8)) │ │ ├── name: :foo │ │ └── depth: 0 @@ -28,10 +27,9 @@ │ ├── @ ConstantPathTargetNode (location: (3,0)-(3,7)) │ │ ├── parent: │ │ │ @ SelfNode (location: (3,0)-(3,4)) - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (3,6)-(3,7)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (3,4)-(3,6) = "::" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (3,4)-(3,6) = "::" + │ │ └── name_loc: (3,6)-(3,7) = "A" │ └── @ LocalVariableTargetNode (location: (3,9)-(3,12)) │ ├── name: :foo │ └── depth: 0 diff --git a/test/prism/snapshots/whitequark/newline_in_hash_argument.txt b/test/prism/snapshots/whitequark/newline_in_hash_argument.txt index d5e89d87f9..7ef006645b 100644 --- a/test/prism/snapshots/whitequark/newline_in_hash_argument.txt +++ b/test/prism/snapshots/whitequark/newline_in_hash_argument.txt @@ -102,7 +102,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (10,8)-(11,1)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (10,8)-(11,1)) │ │ ├── flags: symbol_keys @@ -141,7 +141,7 @@ ├── opening_loc: ∅ ├── arguments: │ @ ArgumentsNode (location: (13,8)-(14,1)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (13,8)-(14,1)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/whitequark/op_asgn.txt b/test/prism/snapshots/whitequark/op_asgn.txt index 8f24a35ad0..f726617904 100644 --- a/test/prism/snapshots/whitequark/op_asgn.txt +++ b/test/prism/snapshots/whitequark/op_asgn.txt @@ -20,8 +20,8 @@ │ ├── message_loc: (1,4)-(1,5) = "A" │ ├── read_name: :A │ ├── write_name: :A= - │ ├── operator: :+ - │ ├── operator_loc: (1,6)-(1,8) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (1,6)-(1,8) = "+=" │ └── value: │ @ IntegerNode (location: (1,9)-(1,10)) │ ├── flags: decimal @@ -43,8 +43,8 @@ │ ├── message_loc: (3,4)-(3,5) = "a" │ ├── read_name: :a │ ├── write_name: :a= - │ ├── operator: :+ - │ ├── operator_loc: (3,6)-(3,8) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (3,6)-(3,8) = "+=" │ └── value: │ @ IntegerNode (location: (3,9)-(3,10)) │ ├── flags: decimal @@ -66,8 +66,8 @@ ├── message_loc: (5,5)-(5,6) = "a" ├── read_name: :a ├── write_name: :a= - ├── operator: :+ - ├── operator_loc: (5,7)-(5,9) = "+=" + ├── binary_operator: :+ + ├── binary_operator_loc: (5,7)-(5,9) = "+=" └── value: @ IntegerNode (location: (5,10)-(5,11)) ├── flags: decimal diff --git a/test/prism/snapshots/whitequark/op_asgn_cmd.txt b/test/prism/snapshots/whitequark/op_asgn_cmd.txt index 109c2fd2ed..d2d86b1bf9 100644 --- a/test/prism/snapshots/whitequark/op_asgn_cmd.txt +++ b/test/prism/snapshots/whitequark/op_asgn_cmd.txt @@ -20,8 +20,8 @@ │ ├── message_loc: (1,4)-(1,5) = "A" │ ├── read_name: :A │ ├── write_name: :A= - │ ├── operator: :+ - │ ├── operator_loc: (1,6)-(1,8) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (1,6)-(1,8) = "+=" │ └── value: │ @ CallNode (location: (1,9)-(1,14)) │ ├── flags: ignore_visibility @@ -63,8 +63,8 @@ │ ├── message_loc: (3,4)-(3,5) = "a" │ ├── read_name: :a │ ├── write_name: :a= - │ ├── operator: :+ - │ ├── operator_loc: (3,6)-(3,8) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (3,6)-(3,8) = "+=" │ └── value: │ @ CallNode (location: (3,9)-(3,14)) │ ├── flags: ignore_visibility @@ -103,11 +103,10 @@ │ │ │ ├── arguments: ∅ │ │ │ ├── closing_loc: ∅ │ │ │ └── block: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (5,5)-(5,6)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (5,3)-(5,5) = "::" - │ ├── operator_loc: (5,7)-(5,9) = "+=" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (5,3)-(5,5) = "::" + │ │ └── name_loc: (5,5)-(5,6) = "A" + │ ├── binary_operator_loc: (5,7)-(5,9) = "+=" │ ├── value: │ │ @ CallNode (location: (5,10)-(5,15)) │ │ ├── flags: ignore_visibility @@ -132,7 +131,7 @@ │ │ │ └── block: ∅ │ │ ├── closing_loc: ∅ │ │ └── block: ∅ - │ └── operator: :+ + │ └── binary_operator: :+ └── @ CallOperatorWriteNode (location: (7,0)-(7,15)) ├── flags: ∅ ├── receiver: @@ -150,8 +149,8 @@ ├── message_loc: (7,5)-(7,6) = "a" ├── read_name: :a ├── write_name: :a= - ├── operator: :+ - ├── operator_loc: (7,7)-(7,9) = "+=" + ├── binary_operator: :+ + ├── binary_operator_loc: (7,7)-(7,9) = "+=" └── value: @ CallNode (location: (7,10)-(7,15)) ├── flags: ignore_visibility diff --git a/test/prism/snapshots/whitequark/op_asgn_index.txt b/test/prism/snapshots/whitequark/op_asgn_index.txt index fe077fae13..b302abdafe 100644 --- a/test/prism/snapshots/whitequark/op_asgn_index.txt +++ b/test/prism/snapshots/whitequark/op_asgn_index.txt @@ -30,8 +30,8 @@ │ └── value: 1 ├── closing_loc: (1,8)-(1,9) = "]" ├── block: ∅ - ├── operator: :+ - ├── operator_loc: (1,10)-(1,12) = "+=" + ├── binary_operator: :+ + ├── binary_operator_loc: (1,10)-(1,12) = "+=" └── value: @ IntegerNode (location: (1,13)-(1,14)) ├── flags: decimal diff --git a/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt b/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt index 87082aad94..319ed1a51a 100644 --- a/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt +++ b/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt @@ -30,8 +30,8 @@ │ └── value: 1 ├── closing_loc: (1,8)-(1,9) = "]" ├── block: ∅ - ├── operator: :+ - ├── operator_loc: (1,10)-(1,12) = "+=" + ├── binary_operator: :+ + ├── binary_operator_loc: (1,10)-(1,12) = "+=" └── value: @ CallNode (location: (1,13)-(1,18)) ├── flags: ignore_visibility diff --git a/test/prism/snapshots/whitequark/parser_bug_525.txt b/test/prism/snapshots/whitequark/parser_bug_525.txt index a69b8a207f..3a31a97cdc 100644 --- a/test/prism/snapshots/whitequark/parser_bug_525.txt +++ b/test/prism/snapshots/whitequark/parser_bug_525.txt @@ -12,7 +12,7 @@ ├── opening_loc: ∅ ├── arguments: │ @ ArgumentsNode (location: (1,3)-(1,11)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 1) │ └── @ KeywordHashNode (location: (1,3)-(1,11)) │ ├── flags: symbol_keys diff --git a/test/prism/snapshots/whitequark/rational.txt b/test/prism/snapshots/whitequark/rational.txt index 90bbd17929..e8c8eed508 100644 --- a/test/prism/snapshots/whitequark/rational.txt +++ b/test/prism/snapshots/whitequark/rational.txt @@ -4,11 +4,10 @@ @ StatementsNode (location: (1,0)-(3,3)) └── body: (length: 2) ├── @ RationalNode (location: (1,0)-(1,5)) - │ └── numeric: - │ @ FloatNode (location: (1,0)-(1,4)) - │ └── value: 42.1 + │ ├── flags: decimal + │ ├── numerator: 421 + │ └── denominator: 10 └── @ RationalNode (location: (3,0)-(3,3)) - └── numeric: - @ IntegerNode (location: (3,0)-(3,2)) - ├── flags: decimal - └── value: 42 + ├── flags: decimal + ├── numerator: 42 + └── denominator: 1 diff --git a/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt b/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt index b269104f30..840e5a4fc0 100644 --- a/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt +++ b/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt @@ -5,7 +5,7 @@ └── body: (length: 1) └── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,22)) ├── name_loc: (1,0)-(1,3) = "foo" - ├── operator_loc: (1,4)-(1,6) = "+=" + ├── binary_operator_loc: (1,4)-(1,6) = "+=" ├── value: │ @ RescueModifierNode (location: (1,7)-(1,22)) │ ├── expression: @@ -32,5 +32,5 @@ │ ├── closing_loc: ∅ │ └── block: ∅ ├── name: :foo - ├── operator: :+ + ├── binary_operator: :+ └── depth: 0 diff --git a/test/prism/snapshots/whitequark/ruby_bug_11380.txt b/test/prism/snapshots/whitequark/ruby_bug_11380.txt index b7a7ef9a98..d5ec10b06c 100644 --- a/test/prism/snapshots/whitequark/ruby_bug_11380.txt +++ b/test/prism/snapshots/whitequark/ruby_bug_11380.txt @@ -12,7 +12,7 @@ ├── opening_loc: ∅ ├── arguments: │ @ ArgumentsNode (location: (1,2)-(1,21)) - │ ├── flags: ∅ + │ ├── flags: contains_keywords │ └── arguments: (length: 2) │ ├── @ LambdaNode (location: (1,2)-(1,15)) │ │ ├── locals: [] diff --git a/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt b/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt index 93418e6448..831d57e30d 100644 --- a/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt +++ b/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt @@ -225,9 +225,9 @@ │ │ │ ├── closing_loc: (7,7)-(7,8) = ")" │ │ │ └── block: ∅ │ │ └── @ RationalNode (location: (7,10)-(7,14)) - │ │ └── numeric: - │ │ @ FloatNode (location: (7,10)-(7,13)) - │ │ └── value: 1.0 + │ │ ├── flags: decimal + │ │ ├── numerator: 1 + │ │ └── denominator: 1 │ ├── closing_loc: ∅ │ └── block: │ @ BlockNode (location: (7,15)-(7,21)) @@ -519,9 +519,9 @@ │ │ │ ├── closing_loc: (17,8)-(17,9) = ")" │ │ │ └── block: ∅ │ │ └── @ RationalNode (location: (17,11)-(17,15)) - │ │ └── numeric: - │ │ @ FloatNode (location: (17,11)-(17,14)) - │ │ └── value: 1.0 + │ │ ├── flags: decimal + │ │ ├── numerator: 1 + │ │ └── denominator: 1 │ ├── closing_loc: ∅ │ └── block: │ @ BlockNode (location: (17,16)-(17,22)) @@ -833,9 +833,9 @@ │ │ │ ├── opening_loc: (27,3)-(27,4) = "{" │ │ │ └── closing_loc: (27,7)-(27,8) = "}" │ │ └── @ RationalNode (location: (27,10)-(27,14)) - │ │ └── numeric: - │ │ @ FloatNode (location: (27,10)-(27,13)) - │ │ └── value: 1.0 + │ │ ├── flags: decimal + │ │ ├── numerator: 1 + │ │ └── denominator: 1 │ ├── closing_loc: ∅ │ └── block: │ @ BlockNode (location: (27,15)-(27,21)) @@ -1152,9 +1152,9 @@ │ │ │ ├── opening_loc: (37,3)-(37,4) = "{" │ │ │ └── closing_loc: (37,8)-(37,9) = "}" │ │ └── @ RationalNode (location: (37,11)-(37,15)) - │ │ └── numeric: - │ │ @ FloatNode (location: (37,11)-(37,14)) - │ │ └── value: 1.0 + │ │ ├── flags: decimal + │ │ ├── numerator: 1 + │ │ └── denominator: 1 │ ├── closing_loc: ∅ │ └── block: │ @ BlockNode (location: (37,16)-(37,22)) diff --git a/test/prism/snapshots/whitequark/ruby_bug_12073.txt b/test/prism/snapshots/whitequark/ruby_bug_12073.txt index 9db30f6fec..2b4d3eab2a 100644 --- a/test/prism/snapshots/whitequark/ruby_bug_12073.txt +++ b/test/prism/snapshots/whitequark/ruby_bug_12073.txt @@ -21,7 +21,7 @@ │ ├── opening_loc: ∅ │ ├── arguments: │ │ @ ArgumentsNode (location: (1,9)-(1,13)) - │ │ ├── flags: ∅ + │ │ ├── flags: contains_keywords │ │ └── arguments: (length: 1) │ │ └── @ KeywordHashNode (location: (1,9)-(1,13)) │ │ ├── flags: symbol_keys @@ -75,10 +75,9 @@ │ │ │ ├── parent: │ │ │ │ @ ConstantReadNode (location: (3,21)-(3,22)) │ │ │ │ └── name: :A - │ │ │ ├── child: - │ │ │ │ @ ConstantReadNode (location: (3,24)-(3,25)) - │ │ │ │ └── name: :B - │ │ │ └── delimiter_loc: (3,22)-(3,24) = "::" + │ │ │ ├── name: :B + │ │ │ ├── delimiter_loc: (3,22)-(3,24) = "::" + │ │ │ └── name_loc: (3,24)-(3,25) = "B" │ │ └── @ StringNode (location: (3,27)-(3,29)) │ │ ├── flags: ∅ │ │ ├── opening_loc: (3,27)-(3,28) = "'" diff --git a/test/prism/snapshots/whitequark/ruby_bug_12402.txt b/test/prism/snapshots/whitequark/ruby_bug_12402.txt index df5aea00c3..4935007f8a 100644 --- a/test/prism/snapshots/whitequark/ruby_bug_12402.txt +++ b/test/prism/snapshots/whitequark/ruby_bug_12402.txt @@ -5,7 +5,7 @@ └── body: (length: 14) ├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,27)) │ ├── name_loc: (1,0)-(1,3) = "foo" - │ ├── operator_loc: (1,4)-(1,6) = "+=" + │ ├── binary_operator_loc: (1,4)-(1,6) = "+=" │ ├── value: │ │ @ RescueModifierNode (location: (1,7)-(1,27)) │ │ ├── expression: @@ -36,11 +36,11 @@ │ │ └── rescue_expression: │ │ @ NilNode (location: (1,24)-(1,27)) │ ├── name: :foo - │ ├── operator: :+ + │ ├── binary_operator: :+ │ └── depth: 0 ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,28)) │ ├── name_loc: (3,0)-(3,3) = "foo" - │ ├── operator_loc: (3,4)-(3,6) = "+=" + │ ├── binary_operator_loc: (3,4)-(3,6) = "+=" │ ├── value: │ │ @ RescueModifierNode (location: (3,7)-(3,28)) │ │ ├── expression: @@ -71,7 +71,7 @@ │ │ └── rescue_expression: │ │ @ NilNode (location: (3,25)-(3,28)) │ ├── name: :foo - │ ├── operator: :+ + │ ├── binary_operator: :+ │ └── depth: 0 ├── @ LocalVariableWriteNode (location: (5,0)-(5,26)) │ ├── name: :foo @@ -151,8 +151,8 @@ │ ├── message_loc: (9,4)-(9,5) = "C" │ ├── read_name: :C │ ├── write_name: :C= - │ ├── operator: :+ - │ ├── operator_loc: (9,6)-(9,8) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (9,6)-(9,8) = "+=" │ └── value: │ @ RescueModifierNode (location: (9,9)-(9,29)) │ ├── expression: @@ -192,8 +192,8 @@ │ ├── message_loc: (11,4)-(11,5) = "C" │ ├── read_name: :C │ ├── write_name: :C= - │ ├── operator: :+ - │ ├── operator_loc: (11,6)-(11,8) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (11,6)-(11,8) = "+=" │ └── value: │ @ RescueModifierNode (location: (11,9)-(11,30)) │ ├── expression: @@ -233,8 +233,8 @@ │ ├── message_loc: (13,4)-(13,5) = "m" │ ├── read_name: :m │ ├── write_name: :m= - │ ├── operator: :+ - │ ├── operator_loc: (13,6)-(13,8) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (13,6)-(13,8) = "+=" │ └── value: │ @ RescueModifierNode (location: (13,9)-(13,29)) │ ├── expression: @@ -274,8 +274,8 @@ │ ├── message_loc: (15,4)-(15,5) = "m" │ ├── read_name: :m │ ├── write_name: :m= - │ ├── operator: :+ - │ ├── operator_loc: (15,6)-(15,8) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (15,6)-(15,8) = "+=" │ └── value: │ @ RescueModifierNode (location: (15,9)-(15,30)) │ ├── expression: @@ -312,10 +312,9 @@ │ │ │ @ LocalVariableReadNode (location: (17,0)-(17,3)) │ │ │ ├── name: :foo │ │ │ └── depth: 0 - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (17,5)-(17,6)) - │ │ │ └── name: :C - │ │ └── delimiter_loc: (17,3)-(17,5) = "::" + │ │ ├── name: :C + │ │ ├── delimiter_loc: (17,3)-(17,5) = "::" + │ │ └── name_loc: (17,5)-(17,6) = "C" │ ├── operator_loc: (17,7)-(17,10) = "||=" │ └── value: │ @ RescueModifierNode (location: (17,11)-(17,31)) @@ -353,10 +352,9 @@ │ │ │ @ LocalVariableReadNode (location: (19,0)-(19,3)) │ │ │ ├── name: :foo │ │ │ └── depth: 0 - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (19,5)-(19,6)) - │ │ │ └── name: :C - │ │ └── delimiter_loc: (19,3)-(19,5) = "::" + │ │ ├── name: :C + │ │ ├── delimiter_loc: (19,3)-(19,5) = "::" + │ │ └── name_loc: (19,5)-(19,6) = "C" │ ├── operator_loc: (19,7)-(19,10) = "||=" │ └── value: │ @ RescueModifierNode (location: (19,11)-(19,32)) @@ -397,8 +395,8 @@ │ ├── message_loc: (21,5)-(21,6) = "m" │ ├── read_name: :m │ ├── write_name: :m= - │ ├── operator: :+ - │ ├── operator_loc: (21,7)-(21,9) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (21,7)-(21,9) = "+=" │ └── value: │ @ RescueModifierNode (location: (21,10)-(21,30)) │ ├── expression: @@ -438,8 +436,8 @@ │ ├── message_loc: (23,5)-(23,6) = "m" │ ├── read_name: :m │ ├── write_name: :m= - │ ├── operator: :+ - │ ├── operator_loc: (23,7)-(23,9) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (23,7)-(23,9) = "+=" │ └── value: │ @ RescueModifierNode (location: (23,10)-(23,31)) │ ├── expression: @@ -486,8 +484,8 @@ │ │ └── value: 0 │ ├── closing_loc: (25,5)-(25,6) = "]" │ ├── block: ∅ - │ ├── operator: :+ - │ ├── operator_loc: (25,7)-(25,9) = "+=" + │ ├── binary_operator: :+ + │ ├── binary_operator_loc: (25,7)-(25,9) = "+=" │ └── value: │ @ RescueModifierNode (location: (25,10)-(25,30)) │ ├── expression: @@ -534,8 +532,8 @@ │ └── value: 0 ├── closing_loc: (27,5)-(27,6) = "]" ├── block: ∅ - ├── operator: :+ - ├── operator_loc: (27,7)-(27,9) = "+=" + ├── binary_operator: :+ + ├── binary_operator_loc: (27,7)-(27,9) = "+=" └── value: @ RescueModifierNode (location: (27,10)-(27,31)) ├── expression: diff --git a/test/prism/snapshots/whitequark/ruby_bug_12669.txt b/test/prism/snapshots/whitequark/ruby_bug_12669.txt index 86b021351b..6151143ba8 100644 --- a/test/prism/snapshots/whitequark/ruby_bug_12669.txt +++ b/test/prism/snapshots/whitequark/ruby_bug_12669.txt @@ -5,11 +5,11 @@ └── body: (length: 4) ├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,18)) │ ├── name_loc: (1,0)-(1,1) = "a" - │ ├── operator_loc: (1,2)-(1,4) = "+=" + │ ├── binary_operator_loc: (1,2)-(1,4) = "+=" │ ├── value: │ │ @ LocalVariableOperatorWriteNode (location: (1,5)-(1,18)) │ │ ├── name_loc: (1,5)-(1,6) = "b" - │ │ ├── operator_loc: (1,7)-(1,9) = "+=" + │ │ ├── binary_operator_loc: (1,7)-(1,9) = "+=" │ │ ├── value: │ │ │ @ CallNode (location: (1,10)-(1,18)) │ │ │ ├── flags: ignore_visibility @@ -31,14 +31,14 @@ │ │ │ ├── closing_loc: ∅ │ │ │ └── block: ∅ │ │ ├── name: :b - │ │ ├── operator: :+ + │ │ ├── binary_operator: :+ │ │ └── depth: 0 │ ├── name: :a - │ ├── operator: :+ + │ ├── binary_operator: :+ │ └── depth: 0 ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,17)) │ ├── name_loc: (3,0)-(3,1) = "a" - │ ├── operator_loc: (3,2)-(3,4) = "+=" + │ ├── binary_operator_loc: (3,2)-(3,4) = "+=" │ ├── value: │ │ @ LocalVariableWriteNode (location: (3,5)-(3,17)) │ │ ├── name: :b @@ -66,7 +66,7 @@ │ │ │ └── block: ∅ │ │ └── operator_loc: (3,7)-(3,8) = "=" │ ├── name: :a - │ ├── operator: :+ + │ ├── binary_operator: :+ │ └── depth: 0 ├── @ LocalVariableWriteNode (location: (5,0)-(5,17)) │ ├── name: :a @@ -75,7 +75,7 @@ │ ├── value: │ │ @ LocalVariableOperatorWriteNode (location: (5,4)-(5,17)) │ │ ├── name_loc: (5,4)-(5,5) = "b" - │ │ ├── operator_loc: (5,6)-(5,8) = "+=" + │ │ ├── binary_operator_loc: (5,6)-(5,8) = "+=" │ │ ├── value: │ │ │ @ CallNode (location: (5,9)-(5,17)) │ │ │ ├── flags: ignore_visibility @@ -97,7 +97,7 @@ │ │ │ ├── closing_loc: ∅ │ │ │ └── block: ∅ │ │ ├── name: :b - │ │ ├── operator: :+ + │ │ ├── binary_operator: :+ │ │ └── depth: 0 │ └── operator_loc: (5,2)-(5,3) = "=" └── @ LocalVariableWriteNode (location: (7,0)-(7,16)) diff --git a/test/prism/snapshots/whitequark/send_attr_asgn.txt b/test/prism/snapshots/whitequark/send_attr_asgn.txt index 392ae5587e..1d09daa4a6 100644 --- a/test/prism/snapshots/whitequark/send_attr_asgn.txt +++ b/test/prism/snapshots/whitequark/send_attr_asgn.txt @@ -69,10 +69,9 @@ │ │ │ ├── arguments: ∅ │ │ │ ├── closing_loc: ∅ │ │ │ └── block: ∅ - │ │ ├── child: - │ │ │ @ ConstantReadNode (location: (5,5)-(5,6)) - │ │ │ └── name: :A - │ │ └── delimiter_loc: (5,3)-(5,5) = "::" + │ │ ├── name: :A + │ │ ├── delimiter_loc: (5,3)-(5,5) = "::" + │ │ └── name_loc: (5,5)-(5,6) = "A" │ ├── operator_loc: (5,7)-(5,8) = "=" │ └── value: │ @ IntegerNode (location: (5,9)-(5,10)) diff --git a/test/prism/snapshots/whitequark/var_op_asgn.txt b/test/prism/snapshots/whitequark/var_op_asgn.txt index f423a62dee..f20f612fa2 100644 --- a/test/prism/snapshots/whitequark/var_op_asgn.txt +++ b/test/prism/snapshots/whitequark/var_op_asgn.txt @@ -6,30 +6,30 @@ ├── @ ClassVariableOperatorWriteNode (location: (1,0)-(1,11)) │ ├── name: :@@var │ ├── name_loc: (1,0)-(1,5) = "@@var" - │ ├── operator_loc: (1,6)-(1,8) = "|=" + │ ├── binary_operator_loc: (1,6)-(1,8) = "|=" │ ├── value: │ │ @ IntegerNode (location: (1,9)-(1,11)) │ │ ├── flags: decimal │ │ └── value: 10 - │ └── operator: :| + │ └── binary_operator: :| ├── @ InstanceVariableOperatorWriteNode (location: (3,0)-(3,7)) │ ├── name: :@a │ ├── name_loc: (3,0)-(3,2) = "@a" - │ ├── operator_loc: (3,3)-(3,5) = "|=" + │ ├── binary_operator_loc: (3,3)-(3,5) = "|=" │ ├── value: │ │ @ IntegerNode (location: (3,6)-(3,7)) │ │ ├── flags: decimal │ │ └── value: 1 - │ └── operator: :| + │ └── binary_operator: :| ├── @ LocalVariableOperatorWriteNode (location: (5,0)-(5,6)) │ ├── name_loc: (5,0)-(5,1) = "a" - │ ├── operator_loc: (5,2)-(5,4) = "+=" + │ ├── binary_operator_loc: (5,2)-(5,4) = "+=" │ ├── value: │ │ @ IntegerNode (location: (5,5)-(5,6)) │ │ ├── flags: decimal │ │ └── value: 1 │ ├── name: :a - │ ├── operator: :+ + │ ├── binary_operator: :+ │ └── depth: 0 └── @ DefNode (location: (7,0)-(7,23)) ├── name: :a @@ -42,12 +42,12 @@ │ └── @ ClassVariableOperatorWriteNode (location: (7,7)-(7,18)) │ ├── name: :@@var │ ├── name_loc: (7,7)-(7,12) = "@@var" - │ ├── operator_loc: (7,13)-(7,15) = "|=" + │ ├── binary_operator_loc: (7,13)-(7,15) = "|=" │ ├── value: │ │ @ IntegerNode (location: (7,16)-(7,18)) │ │ ├── flags: decimal │ │ └── value: 10 - │ └── operator: :| + │ └── binary_operator: :| ├── locals: [] ├── def_keyword_loc: (7,0)-(7,3) = "def" ├── operator_loc: ∅ diff --git a/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt b/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt index d56c099c7e..0bfa06d5b7 100644 --- a/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt +++ b/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt @@ -5,7 +5,7 @@ └── body: (length: 1) └── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,12)) ├── name_loc: (1,0)-(1,3) = "foo" - ├── operator_loc: (1,4)-(1,6) = "+=" + ├── binary_operator_loc: (1,4)-(1,6) = "+=" ├── value: │ @ CallNode (location: (1,7)-(1,12)) │ ├── flags: ignore_visibility @@ -24,5 +24,5 @@ │ ├── closing_loc: ∅ │ └── block: ∅ ├── name: :foo - ├── operator: :+ + ├── binary_operator: :+ └── depth: 0 diff --git a/test/prism/static_inspect_test.rb b/test/prism/static_inspect_test.rb index 8df2fd241e..cc8ed28c95 100644 --- a/test/prism/static_inspect_test.rb +++ b/test/prism/static_inspect_test.rb @@ -2,8 +2,6 @@ require_relative "test_helper" -return if Prism::BACKEND == :FFI - module Prism class StaticInspectTest < TestCase def test_false @@ -84,7 +82,8 @@ module Prism private def static_inspect(source, **options) - Debug.static_inspect(source, **options) + warnings = Prism.parse("{ #{source} => 1, #{source} => 1 }", **options).warnings + warnings.last.message[/^key (.+) is duplicated and overwritten on line \d/, 1] end end end diff --git a/test/prism/unescape_test.rb b/test/prism/unescape_test.rb index 2a352c5234..3f78a59b11 100644 --- a/test/prism/unescape_test.rb +++ b/test/prism/unescape_test.rb @@ -38,7 +38,7 @@ module Prism end def prism(escape) - result = Prism.parse(code(escape)) + result = Prism.parse(code(escape), encoding: "binary") if result.success? yield result.value.statements.body.first diff --git a/test/prism/warnings_test.rb b/test/prism/warnings_test.rb index d01db01a0e..7ad704918a 100644 --- a/test/prism/warnings_test.rb +++ b/test/prism/warnings_test.rb @@ -23,6 +23,23 @@ module Prism assert_warning("a /b/", "wrap regexp in parentheses") end + def test_binary_operator + [ + [:**, "argument prefix"], + [:*, "argument prefix"], + [:<<, "here document"], + [:&, "argument prefix"], + [:+, "unary operator"], + [:-, "unary operator"], + [:/, "regexp literal"], + [:%, "string literal"] + ].each do |(operator, warning)| + assert_warning("puts 1 #{operator}0", warning) + assert_warning("puts :a #{operator}0", warning) + assert_warning("m = 1; puts m #{operator}0", warning) + end + end + def test_equal_in_conditional assert_warning("if a = 1; end; a = a", "should be ==") end @@ -48,7 +65,7 @@ module Prism end def test_duplicated_when_clause - assert_warning("case 1; when 1, 1; end", "clause with line") + assert_warning("case 1; when 1, 1; end", "when' clause") end def test_float_out_of_range @@ -64,6 +81,15 @@ module Prism assert_warning("if true\nelsif\nfalse; end", "end of line") end + def test_shareable_constant_value + assert_warning("foo # shareable_constant_value: none", "ignored") + assert_warning("\v # shareable_constant_value: none", "ignored") + + refute_warning("# shareable_constant_value: none") + refute_warning(" # shareable_constant_value: none") + refute_warning("\t\t# shareable_constant_value: none") + end + def test_string_in_predicate assert_warning("if 'foo'; end", "string") assert_warning("if \"\#{foo}\"; end", "string") diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb index e9f0a9449d..03e4178f32 100644 --- a/test/reline/test_config.rb +++ b/test/reline/test_config.rb @@ -275,6 +275,78 @@ class Reline::Config::Test < Reline::TestCase assert_equal "INPUTRC:1: unmatched endif", e.message end + def test_if_with_mode + @config.read_lines(<<~LINES.lines) + $if mode=emacs + "\C-e": history-search-backward # comment + $else + "\C-f": history-search-forward + $endif + LINES + + assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs]) + assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert]) + assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command]) + end + + def test_else + @config.read_lines(<<~LINES.lines) + $if mode=vi + "\C-e": history-search-backward # comment + $else + "\C-f": history-search-forward + $endif + LINES + + assert_equal({[6] => :history_search_forward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs]) + assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert]) + assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command]) + end + + def test_if_with_invalid_mode + @config.read_lines(<<~LINES.lines) + $if mode=vim + "\C-e": history-search-backward + $else + "\C-f": history-search-forward # comment + $endif + LINES + + assert_equal({[6] => :history_search_forward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs]) + assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert]) + assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command]) + end + + def test_mode_label_differs_from_keymap_label + @config.read_lines(<<~LINES.lines) + # Sets mode_label and keymap_label to vi + set editing-mode vi + # Change keymap_label to emacs. mode_label is still vi. + set keymap emacs + # condition=true because current mode_label is vi + $if mode=vi + # sets keybinding to current keymap_label=emacs + "\C-e": history-search-backward + $endif + LINES + assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs]) + assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert]) + assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command]) + end + + def test_if_without_else_condition + @config.read_lines(<<~LINES.lines) + set editing-mode vi + $if mode=vi + "\C-e": history-search-backward + $endif + LINES + + assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:emacs]) + assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert]) + assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command]) + end + def test_default_key_bindings @config.add_default_key_binding('abcd'.bytes, 'EFGH'.bytes) @config.read_lines(<<~'LINES'.lines) @@ -345,6 +417,18 @@ class Reline::Config::Test < Reline::TestCase assert_equal expected, @config.key_bindings end + def test_key_bindings_with_reset + # @config.reset is called after each readline. + # inputrc file is read once, so key binding shouldn't be cleared by @config.reset + @config.add_default_key_binding('default'.bytes, 'DEFAULT'.bytes) + @config.read_lines(<<~'LINES'.lines) + "additional": "ADDITIONAL" + LINES + @config.reset + expected = { 'default'.bytes => 'DEFAULT'.bytes, 'additional'.bytes => 'ADDITIONAL'.bytes } + assert_equal expected, @config.key_bindings + end + def test_history_size @config.read_lines(<<~LINES.lines) set history-size 5000 @@ -375,6 +459,17 @@ class Reline::Config::Test < Reline::TestCase ENV['INPUTRC'] = inputrc_backup end + def test_inputrc_raw_value + @config.read_lines(<<~'LINES'.lines) + set editing-mode vi ignored-string + set vi-ins-mode-string aaa aaa + set vi-cmd-mode-string bbb ccc # comment + LINES + assert_equal :vi_insert, @config.instance_variable_get(:@editing_mode_label) + assert_equal 'aaa aaa', @config.vi_ins_mode_string + assert_equal 'bbb ccc # comment', @config.vi_cmd_mode_string + end + def test_inputrc_with_utf8 # This file is encoded by UTF-8 so this heredoc string is also UTF-8. @config.read_lines(<<~'LINES'.lines) @@ -458,4 +553,3 @@ class Reline::Config::Test < Reline::TestCase ENV['HOME'] = home_backup end end - diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb index a9baf9ad37..a2ea060ab9 100644 --- a/test/reline/test_key_actor_emacs.rb +++ b/test/reline/test_key_actor_emacs.rb @@ -787,9 +787,22 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase input_keys('b') input_keys("\C-i", false) assert_line_around_cursor('foo_ba', '') + input_keys("\C-h") + input_key_by_symbol(:complete) + assert_line_around_cursor('foo_ba', '') + input_keys("\C-h", false) + input_key_by_symbol(:menu_complete) + assert_line_around_cursor('foo_bar', '') + input_key_by_symbol(:menu_complete) + assert_line_around_cursor('foo_baz', '') + input_keys("\C-h", false) + input_key_by_symbol(:menu_complete_backward) + assert_line_around_cursor('foo_baz', '') + input_key_by_symbol(:menu_complete_backward) + assert_line_around_cursor('foo_bar', '') end - def test_autocompletion_with_upward_navigation + def test_autocompletion @config.autocompletion = true @line_editor.completion_proc = proc { |word| %w{ @@ -806,31 +819,14 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase assert_line_around_cursor('Readline', '') input_keys("\C-i", false) assert_line_around_cursor('Regexp', '') - @line_editor.input_key(Reline::Key.new(:completion_journey_up, :completion_journey_up, false)) - assert_line_around_cursor('Readline', '') - ensure - @config.autocompletion = false - end - - def test_autocompletion_with_upward_navigation_and_menu_complete_backward - @config.autocompletion = true - @line_editor.completion_proc = proc { |word| - %w{ - Readline - Regexp - RegexpError - }.map { |i| - i.encode(@encoding) - } - } - input_keys('Re') - assert_line_around_cursor('Re', '') - input_keys("\C-i", false) + input_key_by_symbol(:completion_journey_up) assert_line_around_cursor('Readline', '') - input_keys("\C-i", false) + input_key_by_symbol(:complete) assert_line_around_cursor('Regexp', '') - @line_editor.input_key(Reline::Key.new(:menu_complete_backward, :menu_complete_backward, false)) + input_key_by_symbol(:menu_complete_backward) assert_line_around_cursor('Readline', '') + input_key_by_symbol(:menu_complete) + assert_line_around_cursor('Regexp', '') ensure @config.autocompletion = false end @@ -1441,4 +1437,176 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase @line_editor.__send__(:vi_editing_mode, nil) assert(@config.editing_mode_is?(:vi_insert)) end + + def test_undo + input_keys("\C-_", false) + assert_line_around_cursor('', '') + input_keys("aあb\C-h\C-h\C-h", false) + assert_line_around_cursor('', '') + input_keys("\C-_", false) + assert_line_around_cursor('a', '') + input_keys("\C-_", false) + assert_line_around_cursor('aあ', '') + input_keys("\C-_", false) + assert_line_around_cursor('aあb', '') + input_keys("\C-_", false) + assert_line_around_cursor('aあ', '') + input_keys("\C-_", false) + assert_line_around_cursor('a', '') + input_keys("\C-_", false) + assert_line_around_cursor('', '') + end + + def test_undo_with_cursor_position + input_keys("abc\C-b\C-h", false) + assert_line_around_cursor('a', 'c') + input_keys("\C-_", false) + assert_line_around_cursor('ab', 'c') + input_keys("あいう\C-b\C-h", false) + assert_line_around_cursor('abあ', 'うc') + input_keys("\C-_", false) + assert_line_around_cursor('abあい', 'うc') + end + + def test_undo_with_multiline + @line_editor.multiline_on + @line_editor.confirm_multiline_termination_proc = proc {} + input_keys("1\n2\n3", false) + assert_whole_lines(["1", "2", "3"]) + assert_line_index(2) + assert_line_around_cursor('3', '') + input_keys("\C-p\C-h\C-h", false) + assert_whole_lines(["1", "3"]) + assert_line_index(0) + assert_line_around_cursor('1', '') + input_keys("\C-_", false) + assert_whole_lines(["1", "", "3"]) + assert_line_index(1) + assert_line_around_cursor('', '') + input_keys("\C-_", false) + assert_whole_lines(["1", "2", "3"]) + assert_line_index(1) + assert_line_around_cursor('2', '') + input_keys("\C-_", false) + assert_whole_lines(["1", "2", ""]) + assert_line_index(2) + assert_line_around_cursor('', '') + input_keys("\C-_", false) + assert_whole_lines(["1", "2"]) + assert_line_index(1) + assert_line_around_cursor('2', '') + end + + def test_undo_with_many_times + str = "a" + "b" * 99 + input_keys(str, false) + 100.times { input_keys("\C-_", false) } + assert_line_around_cursor('a', '') + input_keys("\C-_", false) + assert_line_around_cursor('a', '') + end + + def test_redo + input_keys("aあb", false) + assert_line_around_cursor('aあb', '') + input_keys("\M-\C-_", false) + assert_line_around_cursor('aあb', '') + input_keys("\C-_", false) + assert_line_around_cursor('aあ', '') + input_keys("\C-_", false) + assert_line_around_cursor('a', '') + input_keys("\M-\C-_", false) + assert_line_around_cursor('aあ', '') + input_keys("\M-\C-_", false) + assert_line_around_cursor('aあb', '') + input_keys("\C-_", false) + assert_line_around_cursor('aあ', '') + input_keys("c", false) + assert_line_around_cursor('aあc', '') + input_keys("\M-\C-_", false) + assert_line_around_cursor('aあc', '') + end + + def test_redo_with_cursor_position + input_keys("abc\C-b\C-h", false) + assert_line_around_cursor('a', 'c') + input_keys("\M-\C-_", false) + assert_line_around_cursor('a', 'c') + input_keys("\C-_", false) + assert_line_around_cursor('ab', 'c') + input_keys("\M-\C-_", false) + assert_line_around_cursor('a', 'c') + end + + def test_redo_with_multiline + @line_editor.multiline_on + @line_editor.confirm_multiline_termination_proc = proc {} + input_keys("1\n2\n3", false) + assert_whole_lines(["1", "2", "3"]) + assert_line_index(2) + assert_line_around_cursor('3', '') + + input_keys("\C-_", false) + assert_whole_lines(["1", "2", ""]) + assert_line_index(2) + assert_line_around_cursor('', '') + + input_keys("\C-_", false) + assert_whole_lines(["1", "2"]) + assert_line_index(1) + assert_line_around_cursor('2', '') + + input_keys("\M-\C-_", false) + assert_whole_lines(["1", "2", ""]) + assert_line_index(2) + assert_line_around_cursor('', '') + + input_keys("\M-\C-_", false) + assert_whole_lines(["1", "2", "3"]) + assert_line_index(2) + assert_line_around_cursor('3', '') + + input_keys("\C-p\C-h\C-h", false) + assert_whole_lines(["1", "3"]) + assert_line_index(0) + assert_line_around_cursor('1', '') + + input_keys("\C-n", false) + assert_whole_lines(["1", "3"]) + assert_line_index(1) + assert_line_around_cursor('3', '') + + input_keys("\C-_", false) + assert_whole_lines(["1", "", "3"]) + assert_line_index(1) + assert_line_around_cursor('', '') + + input_keys("\C-_", false) + assert_whole_lines(["1", "2", "3"]) + assert_line_index(1) + assert_line_around_cursor('2', '') + + input_keys("\M-\C-_", false) + assert_whole_lines(["1", "", "3"]) + assert_line_index(1) + assert_line_around_cursor('', '') + + input_keys("\M-\C-_", false) + assert_whole_lines(["1", "3"]) + assert_line_index(1) + assert_line_around_cursor('3', '') + end + + def test_redo_with_many_times + str = "a" + "b" * 98 + "c" + input_keys(str, false) + 100.times { input_keys("\C-_", false) } + assert_line_around_cursor('a', '') + input_keys("\C-_", false) + assert_line_around_cursor('a', '') + 100.times { input_keys("\M-\C-_", false) } + assert_line_around_cursor(str, '') + input_keys("\M-\C-_", false) + assert_line_around_cursor(str, '') + end end diff --git a/test/reline/test_line_editor.rb b/test/reline/test_line_editor.rb index bf688ac3c6..7a38ecd596 100644 --- a/test/reline/test_line_editor.rb +++ b/test/reline/test_line_editor.rb @@ -112,6 +112,36 @@ class Reline::LineEditor end end + def test_multibyte + base = [0, 12, '一二三一二三'] + left = [0, 3, 'LLL'] + right = [9, 3, 'RRR'] + front = [3, 6, 'FFFFFF'] + # 一 FFFFFF 三 + # 一二三一二三 + assert_output '[COL_2]二三一二' do + @line_editor.render_line_differential([base, front], [base, nil]) + end + + # LLLFFFFFF 三 + # LLL 三一二三 + assert_output '[COL_3] 三一二' do + @line_editor.render_line_differential([base, left, front], [base, left, nil]) + end + + # 一 FFFFFFRRR + # 一二三一 RRR + assert_output '[COL_2]二三一 ' do + @line_editor.render_line_differential([base, right, front], [base, right, nil]) + end + + # LLLFFFFFFRRR + # LLL 三一 RRR + assert_output '[COL_3] 三一 ' do + @line_editor.render_line_differential([base, left, right, front], [base, left, right, nil]) + end + end + def test_complicated state_a = [nil, [19, 7, 'bbbbbbb'], [15, 8, 'cccccccc'], [10, 5, 'ddddd'], [18, 4, 'eeee'], [1, 3, 'fff'], [17, 2, 'gg'], [7, 1, 'h']] state_b = [[5, 9, 'aaaaaaaaa'], nil, [15, 8, 'cccccccc'], nil, [18, 4, 'EEEE'], [25, 4, 'ffff'], [17, 2, 'gg'], [2, 2, 'hh']] diff --git a/test/reline/test_reline.rb b/test/reline/test_reline.rb index 40c880c11f..a20a5c9f44 100644 --- a/test/reline/test_reline.rb +++ b/test/reline/test_reline.rb @@ -378,10 +378,28 @@ class Reline::Test < Reline::TestCase assert_equal("Reline::GeneralIO", out.chomp) end + def test_require_reline_should_not_trigger_winsize + pend if win? + lib = File.expand_path("../../lib", __dir__) + code = <<~RUBY + require "io/console" + def STDIN.tty?; true; end + def STDOUT.tty?; true; end + def STDIN.winsize; raise; end + require("reline") && p(Reline.core.io_gate) + RUBY + out = IO.popen([{}, Reline.test_rubybin, "-I#{lib}", "-e", code], &:read) + assert_equal("Reline::ANSI", out.chomp) + end + + def win? + /mswin|mingw/.match?(RUBY_PLATFORM) + end + def get_reline_encoding if encoding = Reline.core.encoding encoding - elsif RUBY_PLATFORM =~ /mswin|mingw/ + elsif win? Encoding::UTF_8 else Encoding::default_external diff --git a/test/reline/test_unicode.rb b/test/reline/test_unicode.rb index a9d82e2c56..deba4d4681 100644 --- a/test/reline/test_unicode.rb +++ b/test/reline/test_unicode.rb @@ -46,8 +46,8 @@ class Reline::Unicode::Test < Reline::TestCase def test_take_range assert_equal 'cdef', Reline::Unicode.take_range('abcdefghi', 2, 4) assert_equal 'あde', Reline::Unicode.take_range('abあdef', 2, 4) - assert_equal 'zerocdef', Reline::Unicode.take_range("ab\1zero\2cdef", 2, 4) - assert_equal 'bzerocde', Reline::Unicode.take_range("ab\1zero\2cdef", 1, 4) + assert_equal "\1zero\2cdef", Reline::Unicode.take_range("ab\1zero\2cdef", 2, 4) + assert_equal "b\1zero\2cde", Reline::Unicode.take_range("ab\1zero\2cdef", 1, 4) assert_equal "\e[31mcd\e[42mef", Reline::Unicode.take_range("\e[31mabcd\e[42mefg", 2, 4) assert_equal "\e]0;1\acd", Reline::Unicode.take_range("ab\e]0;1\acd", 2, 3) assert_equal 'いう', Reline::Unicode.take_range('あいうえお', 2, 4) @@ -67,4 +67,26 @@ class Reline::Unicode::Test < Reline::TestCase assert_equal 10, Reline::Unicode.calculate_width('あいうえお') assert_equal 10, Reline::Unicode.calculate_width('あいうえお', true) end + + def test_take_mbchar_range + assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4) + assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, padding: true) + assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, cover_begin: true) + assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, cover_end: true) + assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4) + assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4, padding: true) + assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4, cover_begin: true) + assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4, cover_end: true) + assert_equal ['う', 4, 2], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4) + assert_equal [' う ', 3, 4], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, padding: true) + assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_begin: true) + assert_equal ['うえ', 4, 4], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_end: true) + assert_equal ['いう ', 2, 5], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_begin: true, padding: true) + assert_equal [' うえ', 3, 5], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_end: true, padding: true) + assert_equal [' うえお ', 3, 10], Reline::Unicode.take_mbchar_range('あいうえお', 3, 10, padding: true) + assert_equal [" \e[41mうえお\e[0m ", 3, 10], Reline::Unicode.take_mbchar_range("あい\e[41mうえお", 3, 10, padding: true) + assert_equal ["\e[41m \e[42mい\e[43m ", 1, 4], Reline::Unicode.take_mbchar_range("\e[41mあ\e[42mい\e[43mう", 1, 4, padding: true) + assert_equal ["\e[31mc\1ABC\2d\e[0mef", 2, 4], Reline::Unicode.take_mbchar_range("\e[31mabc\1ABC\2d\e[0mefghi", 2, 4) + assert_equal ["\e[41m \e[42mい\e[43m ", 1, 4], Reline::Unicode.take_mbchar_range("\e[41mあ\e[42mい\e[43mう", 1, 4, padding: true) + end end diff --git a/test/reline/test_within_pipe.rb b/test/reline/test_within_pipe.rb index a42ca755fc..4f05255301 100644 --- a/test/reline/test_within_pipe.rb +++ b/test/reline/test_within_pipe.rb @@ -23,7 +23,6 @@ class Reline::WithinPipeTest < Reline::TestCase @reader.close @output_writer.close @config.reset - @config.reset_default_key_bindings Reline.test_reset end diff --git a/test/reline/yamatanooroti/multiline_repl b/test/reline/yamatanooroti/multiline_repl index eba410f6dd..8b82be60f4 100755 --- a/test/reline/yamatanooroti/multiline_repl +++ b/test/reline/yamatanooroti/multiline_repl @@ -12,7 +12,7 @@ opt = OptionParser.new opt.on('--dynamic-prompt') { Reline.prompt_proc = proc { |lines| lines.each_with_index.map { |l, i| - '[%04d]> ' % i + "\e[1m[%04d]>\e[m " % i } } } @@ -222,7 +222,7 @@ rescue end begin - prompt = ENV['RELINE_TEST_PROMPT'] || 'prompt> ' + prompt = ENV['RELINE_TEST_PROMPT'] || "\e[1mprompt>\e[m " puts 'Multiline REPL.' while code = Reline.readmultiline(prompt, true) { |code| TerminationChecker.terminated?(code) } case code.chomp diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb index 7b96e7b6a6..1cf46b4cd1 100644 --- a/test/reline/yamatanooroti/test_rendering.rb +++ b/test/reline/yamatanooroti/test_rendering.rb @@ -543,15 +543,10 @@ begin EOC end - def test_enable_bracketed_paste + def test_bracketed_paste omit if Reline.core.io_gate.win? - write_inputrc <<~LINES - set enable-bracketed-paste on - LINES start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("\e[200~,") - write("def hoge\n 3\nend") - write("\e[200~.") + write("\e[200~def hoge\r\t3\rend\e[201~") close assert_screen(<<~EOC) Multiline REPL. @@ -561,6 +556,35 @@ begin EOC end + def test_bracketed_paste_with_undo + omit if Reline.core.io_gate.win? + start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') + write("abc") + write("\e[200~def hoge\r\t3\rend\e[201~") + write("\C-_") + close + assert_screen(<<~EOC) + Multiline REPL. + prompt> abc + EOC + end + + def test_bracketed_paste_with_redo + omit if Reline.core.io_gate.win? + start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') + write("abc") + write("\e[200~def hoge\r\t3\rend\e[201~") + write("\C-_") + write("\M-\C-_") + close + assert_screen(<<~EOC) + Multiline REPL. + prompt> abcdef hoge + prompt> 3 + prompt> end + EOC + end + def test_backspace_until_returns_to_initial start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') write("ABC") @@ -945,18 +969,30 @@ begin EOC end - def test_with_newline + def test_eof_with_newline omit if Reline.core.io_gate.win? cmd = %Q{ruby -e 'print(%Q{abc def \\e\\r})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'} start_terminal(40, 50, ['bash', '-c', cmd]) sleep 1 - close + close rescue nil assert_screen(<<~'EOC') > abc def "abc def " EOC end + def test_eof_without_newline + omit if Reline.core.io_gate.win? + cmd = %Q{ruby -e 'print(%{hello})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'} + start_terminal(40, 50, ['bash', '-c', cmd]) + sleep 1 + close rescue nil + assert_screen(<<~'EOC') + > hello + "hello" + EOC + end + def test_em_set_mark_and_em_exchange_mark start_terminal(10, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') write("aaa bbb ccc ddd\M-b\M-b\M-\x20\M-b\C-x\C-xX\C-x\C-xY") @@ -1173,7 +1209,36 @@ begin assert_screen(<<~'EOC') Multiline REPL. prompt> St - r String + r + String + Struct + EOC + end + + def test_autocomplete_target_at_end_of_line + start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') + write(' ') + write('Str') + write("\C-i") + close + assert_screen(<<~'EOC') + Multiline REPL. + prompt> Str + ing String + Struct + EOC + end + + def test_autocomplete_completed_input_is_wrapped + start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') + write(' ') + write('Str') + write("\C-i") + close + assert_screen(<<~'EOC') + Multiline REPL. + prompt> Stri + ng String Struct EOC end diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb index cbae6e7ed5..a5c7401968 100644 --- a/test/ripper/test_parser_events.rb +++ b/test/ripper/test_parser_events.rb @@ -269,15 +269,27 @@ class TestRipper::ParserEvents < Test::Unit::TestCase def test_assign_error_backref thru_assign_error = false result = - parse('$` = 1', :on_assign_error) {thru_assign_error = true} + parse('$& = 1', :on_assign_error) {thru_assign_error = true} assert_equal true, thru_assign_error - assert_equal '[assign(assign_error(var_field($`)),1)]', result + assert_equal '[assign(assign_error(var_field($&)),1)]', result thru_assign_error = false result = - parse('$`, _ = 1', :on_assign_error) {thru_assign_error = true} + parse('$&, _ = 1', :on_assign_error) {thru_assign_error = true} assert_equal true, thru_assign_error - assert_equal '[massign([assign_error(var_field($`)),var_field(_)],1)]', result + assert_equal '[massign([assign_error(var_field($&)),var_field(_)],1)]', result + + thru_assign_error = false + result = + parse('$& += 1', :on_assign_error) {thru_assign_error = true} + assert_equal true, thru_assign_error + assert_equal '[assign_error(opassign(var_field($&),+=,1))]', result + + thru_assign_error = false + result = + parse('$& += cmd 1, 2', :on_assign_error) {thru_assign_error = true} + assert_equal true, thru_assign_error + assert_equal '[assign_error(opassign(var_field($&),+=,command(cmd,[1,2])))]', result end def test_assign_error_const_qualified @@ -1682,8 +1694,8 @@ class TestRipper::ParserEvents < Test::Unit::TestCase else end STR - assert_match(/duplicated 'when' clause/, fmt) - assert_equal([3], args) + assert_match(/duplicates 'when' clause/, fmt) + assert_equal([4, 3], args) end def test_warn_duplicated_hash_keys diff --git a/test/ripper/test_ripper.rb b/test/ripper/test_ripper.rb index 6061496d9c..f129a41be9 100644 --- a/test/ripper/test_ripper.rb +++ b/test/ripper/test_ripper.rb @@ -170,6 +170,14 @@ end end; end + def test_sexp_no_memory_leak + assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true) + 1_000_000.times do + Ripper.sexp("") + end + end; + end + class TestInput < self Input = Struct.new(:lines) do def gets diff --git a/test/ruby/test_allocation.rb b/test/ruby/test_allocation.rb index 48348c0fbd..fbe0548899 100644 --- a/test/ruby/test_allocation.rb +++ b/test/ruby/test_allocation.rb @@ -25,6 +25,10 @@ class TestAllocation < Test::Unit::TestCase empty_array = empty_array = [] empty_hash = empty_hash = {} array1 = array1 = [1] + r2k_array = r2k_array = [Hash.ruby2_keywords_hash(a: 3)] + r2k_array1 = r2k_array1 = [1, Hash.ruby2_keywords_hash(a: 3)] + r2k_empty_array = r2k_empty_array = [Hash.ruby2_keywords_hash({})] + r2k_empty_array1 = r2k_empty_array1 = [1, Hash.ruby2_keywords_hash({})] hash1 = hash1 = {a: 2} nill = nill = nil block = block = lambda{} @@ -95,6 +99,8 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 0, "none(*empty_array, *empty_array#{block})") check_allocations(0, 1, "none(**empty_hash, **empty_hash#{block})") check_allocations(1, 1, "none(*empty_array, *empty_array, **empty_hash, **empty_hash#{block})") + + check_allocations(0, 0, "none(*r2k_empty_array#{block})") RUBY end @@ -114,6 +120,9 @@ class TestAllocation < Test::Unit::TestCase check_allocations(0, 1, "required(**hash1, **empty_hash#{block})") check_allocations(1, 0, "required(*array1, *empty_array, **empty_hash#{block})") + check_allocations(0, 0, "required(*r2k_empty_array1#{block})") + check_allocations(0, 1, "required(*r2k_array#{block})") + # Currently allocates 1 array unnecessarily due to splatarray true check_allocations(1, 1, "required(*empty_array, **hash1, **empty_hash#{block})") RUBY @@ -135,6 +144,10 @@ class TestAllocation < Test::Unit::TestCase check_allocations(0, 1, "optional(**hash1, **empty_hash#{block})") check_allocations(1, 0, "optional(*array1, *empty_array, **empty_hash#{block})") + check_allocations(0, 0, "optional(*r2k_empty_array#{block})") + check_allocations(0, 0, "optional(*r2k_empty_array1#{block})") + check_allocations(0, 1, "optional(*r2k_array#{block})") + # Currently allocates 1 array unnecessarily due to splatarray true check_allocations(1, 1, "optional(*empty_array, **hash1, **empty_hash#{block})") RUBY @@ -166,6 +179,11 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "splat(**hash1, **empty_hash#{block})") check_allocations(1, 0, "splat(*array1, *empty_array, **empty_hash#{block})") check_allocations(1, 1, "splat(*empty_array, **hash1, **empty_hash#{block})") + + check_allocations(1, 0, "splat(*r2k_empty_array#{block})") + check_allocations(1, 0, "splat(*r2k_empty_array1#{block})") + check_allocations(1, 1, "splat(*r2k_array#{block})") + check_allocations(1, 1, "splat(*r2k_array1#{block})") RUBY end @@ -195,6 +213,10 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "req_splat(**hash1, **empty_hash#{block})") check_allocations(1, 0, "req_splat(*array1, *empty_array, **empty_hash#{block})") check_allocations(1, 1, "req_splat(*empty_array, **hash1, **empty_hash#{block})") + + check_allocations(1, 0, "req_splat(*r2k_empty_array1#{block})") + check_allocations(1, 1, "req_splat(*r2k_array#{block})") + check_allocations(1, 1, "req_splat(*r2k_array1#{block})") RUBY end @@ -224,6 +246,10 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "splat_post(**hash1, **empty_hash#{block})") check_allocations(1, 0, "splat_post(*array1, *empty_array, **empty_hash#{block})") check_allocations(1, 1, "splat_post(*empty_array, **hash1, **empty_hash#{block})") + + check_allocations(1, 0, "splat_post(*r2k_empty_array1#{block})") + check_allocations(1, 1, "splat_post(*r2k_array#{block})") + check_allocations(1, 1, "splat_post(*r2k_array1#{block})") RUBY end @@ -251,6 +277,9 @@ class TestAllocation < Test::Unit::TestCase check_allocations(0, 1, "keyword(**hash1, **empty_hash#{block})") check_allocations(1, 0, "keyword(*empty_array, *empty_array, **empty_hash#{block})") + check_allocations(1, 0, "keyword(*r2k_empty_array#{block})") + check_allocations(1, 1, "keyword(*r2k_array#{block})") + # Currently allocates 1 array unnecessarily due to splatarray true check_allocations(1, 1, "keyword(*empty_array, a: 2, **empty_hash#{block})") check_allocations(1, 1, "keyword(*empty_array, **hash1, **empty_hash#{block})") @@ -281,6 +310,9 @@ class TestAllocation < Test::Unit::TestCase check_allocations(0, 1, "keyword_splat(**hash1, **empty_hash#{block})") check_allocations(1, 1, "keyword_splat(*empty_array, *empty_array, **empty_hash#{block})") + check_allocations(1, 1, "keyword_splat(*r2k_empty_array#{block})") + check_allocations(1, 1, "keyword_splat(*r2k_array#{block})") + # Currently allocates 1 array unnecessarily due to splatarray true check_allocations(1, 1, "keyword_splat(*empty_array, a: 2, **empty_hash#{block})") check_allocations(1, 1, "keyword_splat(*empty_array, **hash1, **empty_hash#{block})") @@ -311,6 +343,9 @@ class TestAllocation < Test::Unit::TestCase check_allocations(0, 1, "keyword_and_keyword_splat(**hash1, **empty_hash#{block})") check_allocations(1, 1, "keyword_and_keyword_splat(*empty_array, *empty_array, **empty_hash#{block})") + check_allocations(1, 1, "keyword_and_keyword_splat(*r2k_empty_array#{block})") + check_allocations(1, 1, "keyword_and_keyword_splat(*r2k_array#{block})") + # Currently allocates 1 array unnecessarily due to splatarray true check_allocations(1, 1, "keyword_and_keyword_splat(*empty_array, a: 2, **empty_hash#{block})") check_allocations(1, 1, "keyword_and_keyword_splat(*empty_array, **hash1, **empty_hash#{block})") @@ -350,6 +385,9 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "required_and_keyword(*array1, *empty_array, a: 2, **empty_hash#{block})") check_allocations(1, 1, "required_and_keyword(*array1, *empty_array, **hash1, **empty_hash#{block})") + check_allocations(1, 0, "required_and_keyword(*r2k_empty_array1#{block})") + check_allocations(1, 1, "required_and_keyword(*r2k_array1#{block})") + # Currently allocates 1 array unnecessarily due to splatarray true check_allocations(1, 1, "required_and_keyword(1, *empty_array, a: 2, **empty_hash#{block})") check_allocations(1, 1, "required_and_keyword(1, *empty_array, **hash1, **empty_hash#{block})") @@ -397,6 +435,11 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "splat_and_keyword(*array1, **empty_hash, a: 2#{block})") check_allocations(1, 1, "splat_and_keyword(*array1, **hash1, **empty_hash#{block})") check_allocations(1, 0, "splat_and_keyword(*array1, **nil#{block})") + + check_allocations(1, 0, "splat_and_keyword(*r2k_empty_array#{block})") + check_allocations(1, 1, "splat_and_keyword(*r2k_array#{block})") + check_allocations(1, 0, "splat_and_keyword(*r2k_empty_array1#{block})") + check_allocations(1, 1, "splat_and_keyword(*r2k_array1#{block})") RUBY end @@ -433,6 +476,9 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "required_and_keyword_splat(*array1, *empty_array, a: 2, **empty_hash#{block})") check_allocations(1, 1, "required_and_keyword_splat(*array1, *empty_array, **hash1, **empty_hash#{block})") + check_allocations(1, 1, "required_and_keyword_splat(*r2k_empty_array1#{block})") + check_allocations(1, 1, "required_and_keyword_splat(*r2k_array1#{block})") + # Currently allocates 1 array unnecessarily due to splatarray true check_allocations(1, 1, "required_and_keyword_splat(1, *empty_array, a: 2, **empty_hash#{block})") check_allocations(1, 1, "required_and_keyword_splat(1, *empty_array, **hash1, **empty_hash#{block})") @@ -480,6 +526,11 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "splat_and_keyword_splat(*array1, **empty_hash, a: 2#{block})") check_allocations(1, 1, "splat_and_keyword_splat(*array1, **hash1, **empty_hash#{block})") check_allocations(1, 1, "splat_and_keyword_splat(*array1, **nil#{block})") + + check_allocations(1, 1, "splat_and_keyword_splat(*r2k_empty_array#{block})") + check_allocations(1, 1, "splat_and_keyword_splat(*r2k_array#{block})") + check_allocations(1, 1, "splat_and_keyword_splat(*r2k_empty_array1#{block})") + check_allocations(1, 1, "splat_and_keyword_splat(*r2k_array1#{block})") RUBY end @@ -521,6 +572,11 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, **empty_hash, a: 2#{block})") check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, **hash1, **empty_hash#{block})") check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(*array1, **nil#{block})") + + check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_empty_array#{block})") + check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_array#{block})") + check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_empty_array1#{block})") + check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_array1#{block})") RUBY end @@ -562,6 +618,11 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, **empty_hash, a: 2#{block})") check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, **hash1, **empty_hash#{block})") check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(*array1, **nil#{block})") + + check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_empty_array#{block})") + check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_array#{block})") + check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_empty_array1#{block})") + check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_array1#{block})") RUBY end @@ -603,6 +664,11 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "argument_forwarding(*array1, **empty_hash, a: 2#{block})") check_allocations(1, 1, "argument_forwarding(*array1, **hash1, **empty_hash#{block})") check_allocations(1, 0, "argument_forwarding(*array1, **nil#{block})") + + check_allocations(1, 1, "argument_forwarding(*r2k_empty_array#{block})") + check_allocations(1, 1, "argument_forwarding(*r2k_array#{block})") + check_allocations(1, 1, "argument_forwarding(*r2k_empty_array1#{block})") + check_allocations(1, 1, "argument_forwarding(*r2k_array1#{block})") RUBY end @@ -644,6 +710,61 @@ class TestAllocation < Test::Unit::TestCase check_allocations(1, 1, "argument_forwarding(*array1, **empty_hash, a: 2#{block})") check_allocations(1, 1, "argument_forwarding(*array1, **hash1, **empty_hash#{block})") check_allocations(1, 0, "argument_forwarding(*array1, **nil#{block})") + + check_allocations(1, 1, "argument_forwarding(*r2k_empty_array#{block})") + check_allocations(1, 1, "argument_forwarding(*r2k_array#{block})") + check_allocations(1, 1, "argument_forwarding(*r2k_empty_array1#{block})") + check_allocations(1, 1, "argument_forwarding(*r2k_array1#{block})") + RUBY + end + + def test_ruby2_keywords + check_allocations(<<~RUBY) + def self.r2k(*a#{block}); end + singleton_class.send(:ruby2_keywords, :r2k) + + check_allocations(1, 1, "r2k(1, a: 2#{block})") + check_allocations(1, 1, "r2k(1, *empty_array, a: 2#{block})") + check_allocations(1, 1, "r2k(1, a:2, **empty_hash#{block})") + check_allocations(1, 1, "r2k(1, **empty_hash, a: 2#{block})") + + check_allocations(1, 0, "r2k(1, **nil#{block})") + check_allocations(1, 1, "r2k(1, **empty_hash#{block})") + check_allocations(1, 1, "r2k(1, **hash1#{block})") + check_allocations(1, 1, "r2k(1, *empty_array, **hash1#{block})") + check_allocations(1, 1, "r2k(1, **hash1, **empty_hash#{block})") + check_allocations(1, 1, "r2k(1, **empty_hash, **hash1#{block})") + + check_allocations(1, 0, "r2k(1, *empty_array#{block})") + check_allocations(1, 1, "r2k(1, **hash1, **empty_hash#{block})") + check_allocations(1, 1, "r2k(1, *empty_array, *empty_array, **empty_hash#{block})") + + check_allocations(1, 1, "r2k(*array1, a: 2#{block})") + + check_allocations(1, 0, "r2k(*array1, **nill#{block})") + check_allocations(1, 1, "r2k(*array1, **empty_hash#{block})") + check_allocations(1, 1, "r2k(*array1, **hash1#{block})") + check_allocations(1, 1, "r2k(*array1, *empty_array, **hash1#{block})") + + check_allocations(1, 0, "r2k(*array1, *empty_array#{block})") + check_allocations(1, 1, "r2k(*array1, *empty_array, **empty_hash#{block})") + + check_allocations(1, 1, "r2k(*array1, *empty_array, a: 2, **empty_hash#{block})") + check_allocations(1, 1, "r2k(*array1, *empty_array, **hash1, **empty_hash#{block})") + + check_allocations(1, 1, "r2k(1, *empty_array, a: 2, **empty_hash#{block})") + check_allocations(1, 1, "r2k(1, *empty_array, **hash1, **empty_hash#{block})") + check_allocations(1, 1, "r2k(*array1, **empty_hash, a: 2#{block})") + check_allocations(1, 1, "r2k(*array1, **hash1, **empty_hash#{block})") + check_allocations(1, 0, "r2k(*array1, **nil#{block})") + + check_allocations(1, 0, "r2k(*r2k_empty_array#{block})") + check_allocations(1, 1, "r2k(*r2k_array#{block})") + unless defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled? + # YJIT may or may not allocate depending on arch? + check_allocations(1, 0, "r2k(*r2k_empty_array1#{block})") + check_allocations(1, 1, "r2k(*r2k_array1#{block})") + end RUBY end diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb index 29da607fc5..45c6b63963 100644 --- a/test/ruby/test_ast.rb +++ b/test/ruby/test_ast.rb @@ -337,6 +337,8 @@ class TestAst < Test::Unit::TestCase end def test_node_id_for_location + omit if compiling_with_prism? + exception = begin raise rescue => e @@ -356,6 +358,8 @@ class TestAst < Test::Unit::TestCase end def test_of_proc_and_method + omit if compiling_with_prism? + proc = Proc.new { 1 + 2 } method = self.method(__method__) @@ -385,6 +389,8 @@ class TestAst < Test::Unit::TestCase end def test_of_backtrace_location + omit if compiling_with_prism? + backtrace_location, lineno = sample_backtrace_location node = RubyVM::AbstractSyntaxTree.of(backtrace_location) assert_instance_of(RubyVM::AbstractSyntaxTree::Node, node) @@ -396,6 +402,8 @@ class TestAst < Test::Unit::TestCase end def test_of_proc_and_method_under_eval + omit if compiling_with_prism? + keep_script_lines_back = RubyVM.keep_script_lines RubyVM.keep_script_lines = false @@ -425,6 +433,7 @@ class TestAst < Test::Unit::TestCase end def test_of_proc_and_method_under_eval_with_keep_script_lines + omit if compiling_with_prism? pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO keep_script_lines_back = RubyVM.keep_script_lines @@ -456,6 +465,8 @@ class TestAst < Test::Unit::TestCase end def test_of_backtrace_location_under_eval + omit if compiling_with_prism? + keep_script_lines_back = RubyVM.keep_script_lines RubyVM.keep_script_lines = false @@ -474,6 +485,7 @@ class TestAst < Test::Unit::TestCase end def test_of_backtrace_location_under_eval_with_keep_script_lines + omit if compiling_with_prism? pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO keep_script_lines_back = RubyVM.keep_script_lines @@ -736,6 +748,8 @@ dummy end def test_keep_script_lines_for_of + omit if compiling_with_prism? + proc = Proc.new { 1 + 2 } method = self.method(__method__) @@ -1238,6 +1252,24 @@ dummy end end + def test_memory_leak + assert_no_memory_leak([], "#{<<~"begin;"}", "\n#{<<~'end;'}", rss: true) + begin; + 1_000_000.times do + eval("") + end + end; + end + + private + + # We can't revisit instruction sequences to find node ids if the prism + # compiler was used instead of the parse.y compiler. In that case, we'll omit + # some tests. + def compiling_with_prism? + RubyVM::InstructionSequence.compile("").to_a[4][:parser] == :prism + end + def assert_error_tolerant(src, expected, keep_tokens: false) begin verbose_bak, $VERBOSE = $VERBOSE, false diff --git a/test/ruby/test_file.rb b/test/ruby/test_file.rb index aa10566bfa..9fa96f8a7c 100644 --- a/test/ruby/test_file.rb +++ b/test/ruby/test_file.rb @@ -460,6 +460,39 @@ class TestFile < Test::Unit::TestCase end end + def test_initialize + Dir.mktmpdir(__method__.to_s) do |tmpdir| + path = File.join(tmpdir, "foo") + + assert_raise(Errno::ENOENT) {File.new(path)} + f = File.new(path, "w") + f.write("FOO\n") + f.close + f = File.new(path) + data = f.read + f.close + assert_equal("FOO\n", data) + + f = File.new(path, File::WRONLY) + f.write("BAR\n") + f.close + f = File.new(path, File::RDONLY) + data = f.read + f.close + assert_equal("BAR\n", data) + + data = File.open(path) {|file| + File.new(file.fileno, mode: File::RDONLY, autoclose: false).read + } + assert_equal("BAR\n", data) + + data = File.open(path) {|file| + File.new(file.fileno, File::RDONLY, autoclose: false).read + } + assert_equal("BAR\n", data) + end + end + def test_file_open_newline_option Dir.mktmpdir(__method__.to_s) do |tmpdir| path = File.join(tmpdir, "foo") diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index 476d9f882f..ce81286c4d 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -2929,6 +2929,15 @@ class TestIO < Test::Unit::TestCase f.close assert_equal("FOO\n", File.read(t.path)) + + fd = IO.sysopen(t.path) + %w[w r+ w+ a+].each do |mode| + assert_raise(Errno::EINVAL, "#{mode} [ruby-dev:38571]") {IO.new(fd, mode)} + end + f = IO.new(fd, "r") + data = f.read + f.close + assert_equal("FOO\n", data) } end diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb index d2a39e673f..a47419253b 100644 --- a/test/ruby/test_iseq.rb +++ b/test/ruby/test_iseq.rb @@ -347,11 +347,17 @@ class TestISeq < Test::Unit::TestCase end end assert_equal([m1, e1.message], [m2, e2.message], feature11951) - message = e1.message.each_line - message.with_index(1) do |line, i| - next if /^ / =~ line - assert_send([line, :start_with?, __FILE__], - proc {message.map {|l, j| (i == j ? ">" : " ") + l}.join("")}) + + if e1.message.lines[0] == "#{__FILE__}:#{line}: syntax errors found\n" + # Prism lays out the error messages in line with the source, so the + # following assertions do not make sense in that context. + else + message = e1.message.each_line + message.with_index(1) do |line, i| + next if /^ / =~ line + assert_send([line, :start_with?, __FILE__], + proc {message.map {|l, j| (i == j ? ">" : " ") + l}.join("")}) + end end end @@ -463,7 +469,7 @@ class TestISeq < Test::Unit::TestCase ["<class:C>@1", ["bar@10", ["block in bar@11", ["block (2 levels) in bar@12"]]], - ["foo@2", ["ensure in foo@2"], + ["foo@2", ["ensure in foo@7"], ["rescue in foo@4"]]], ["<class:D>@17"]] @@ -496,7 +502,7 @@ class TestISeq < Test::Unit::TestCase [4, :line], [7, :line], [9, :return]]], - [["ensure in foo@2", [[7, :line]]]], + [["ensure in foo@7", [[7, :line]]]], [["rescue in foo@4", [[5, :line], [5, :rescue]]]]]], [["<class:D>@17", [[17, :class], diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb index c6154af1f6..8732d8f0d0 100644 --- a/test/ruby/test_literal.rb +++ b/test/ruby/test_literal.rb @@ -640,11 +640,20 @@ class TestRubyLiteral < Test::Unit::TestCase end begin r2 = eval(s) - rescue NameError, SyntaxError + rescue ArgumentError + # Debug log for a random failure: ArgumentError: SyntaxError#path changed + $stderr.puts "TestRubyLiteral#test_float failed: %p" % s + raise + rescue SyntaxError => e + r2 = :err + rescue NameError r2 = :err end r2 = :err if Range === r2 - assert_equal(r1, r2, "Float(#{s.inspect}) != eval(#{s.inspect})") + s = s.inspect + mesg = "Float(#{s}) != eval(#{s})" + mesg << ":" << e.message if e + assert_equal(r1, r2, mesg) } } } diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb index 79d9577737..bcd8892f23 100644 --- a/test/ruby/test_marshal.rb +++ b/test/ruby/test_marshal.rb @@ -570,13 +570,19 @@ class TestMarshal < Test::Unit::TestCase def test_class_ivar assert_raise(TypeError) {Marshal.load("\x04\x08Ic\x1bTestMarshal::TestClass\x06:\x0e@ivar_bug\"\x08bug")} assert_raise(TypeError) {Marshal.load("\x04\x08IM\x1bTestMarshal::TestClass\x06:\x0e@ivar_bug\"\x08bug")} - assert_not_operator(TestClass, :instance_variable_defined?, :@bug) + assert_not_operator(TestClass, :instance_variable_defined?, :@ivar_bug) + + assert_raise(TypeError) {Marshal.load("\x04\x08[\x07c\x1bTestMarshal::TestClassI@\x06\x06:\x0e@ivar_bug\"\x08bug")} + assert_not_operator(TestClass, :instance_variable_defined?, :@ivar_bug) end def test_module_ivar assert_raise(TypeError) {Marshal.load("\x04\x08Im\x1cTestMarshal::TestModule\x06:\x0e@ivar_bug\"\x08bug")} assert_raise(TypeError) {Marshal.load("\x04\x08IM\x1cTestMarshal::TestModule\x06:\x0e@ivar_bug\"\x08bug")} - assert_not_operator(TestModule, :instance_variable_defined?, :@bug) + assert_not_operator(TestModule, :instance_variable_defined?, :@ivar_bug) + + assert_raise(TypeError) {Marshal.load("\x04\x08[\x07m\x1cTestMarshal::TestModuleI@\x06\x06:\x0e@ivar_bug\"\x08bug")} + assert_not_operator(TestModule, :instance_variable_defined?, :@ivar_bug) end class TestForRespondToFalse diff --git a/test/ruby/test_pack.rb b/test/ruby/test_pack.rb index 1ce46e8916..a0c66c188b 100644 --- a/test/ruby/test_pack.rb +++ b/test/ruby/test_pack.rb @@ -895,4 +895,22 @@ EXPECTED } assert_equal [nil], "a".unpack("C", offset: 1) end + + def test_monkey_pack + assert_separately([], <<-'end;') + $-w = false + class Array + alias :old_pack :pack + def pack _; "oh no"; end + end + + v = [2 ** 15].pack('n') + + class Array + alias :pack :old_pack + end + + assert_equal "oh no", v + end; + end end diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb index fe649cddb9..3857f3cc17 100644 --- a/test/ruby/test_parse.rb +++ b/test/ruby/test_parse.rb @@ -18,7 +18,7 @@ class TestParse < Test::Unit::TestCase end def test_else_without_rescue - assert_syntax_error(<<-END, %r":#{__LINE__+2}: else without rescue"o, [__FILE__, __LINE__+1]) + assert_syntax_error(<<-END, %r"(:#{__LINE__+2}:|#{__LINE__+2} \|.+?\n.+?\^~.+?;) else without rescue"o, [__FILE__, __LINE__+1]) begin else 42 @@ -555,34 +555,42 @@ class TestParse < Test::Unit::TestCase mesg = 'from the backslash through the invalid char' e = assert_syntax_error('"\xg1"', /hex escape/) - assert_equal(' ^~'"\n", e.message.lines.last, mesg) + assert_match(/(^|\| ) \^~(?!~)/, e.message.lines.last, mesg) e = assert_syntax_error('"\u{1234"', 'unterminated Unicode escape') - assert_equal(' ^'"\n", e.message.lines.last, mesg) + assert_match(/(^|\| ) \^(?!~)/, e.message.lines.last, mesg) e = assert_syntax_error('"\u{xxxx}"', 'invalid Unicode escape') - assert_equal(' ^'"\n", e.message.lines.last, mesg) + assert_match(/(^|\| ) \^(?!~)/, e.message.lines.last, mesg) e = assert_syntax_error('"\u{xxxx', 'Unicode escape') - assert_pattern_list([ - /.*: invalid Unicode escape\n.*\n/, - / \^/, - /\n/, - /.*: unterminated Unicode escape\n.*\n/, - / \^/, - /\n/, - /.*: unterminated string.*\n.*\n/, - / \^\n/, - ], e.message) + if e.message.lines.first == "#{__FILE__}:#{__LINE__ - 1}: syntax errors found\n" + assert_pattern_list([ + /\s+\| \^ unterminated string;.+\n/, + /\s+\| \^ unterminated Unicode escape\n/, + /\s+\| \^ invalid Unicode escape sequence\n/, + ], e.message.lines[2..-1].join) + else + assert_pattern_list([ + /.*: invalid Unicode escape\n.*\n/, + / \^/, + /\n/, + /.*: unterminated Unicode escape\n.*\n/, + / \^/, + /\n/, + /.*: unterminated string.*\n.*\n/, + / \^\n/, + ], e.message) + end e = assert_syntax_error('"\M1"', /escape character syntax/) - assert_equal(' ^~~'"\n", e.message.lines.last, mesg) + assert_match(/(^|\| ) \^~~(?!~)/, e.message.lines.last, mesg) e = assert_syntax_error('"\C1"', /escape character syntax/) - assert_equal(' ^~~'"\n", e.message.lines.last, mesg) + assert_match(/(^|\| ) \^~~(?!~)/, e.message.lines.last, mesg) src = '"\xD0\u{90'"\n""000000000000000000000000" - assert_syntax_error(src, /:#{__LINE__}: unterminated/o) + assert_syntax_error(src, /(:#{__LINE__}:|> #{__LINE__} \|.+) unterminated/om) assert_syntax_error('"\u{100000000}"', /invalid Unicode escape/) assert_equal("", eval('"\u{}"')) @@ -605,22 +613,22 @@ class TestParse < Test::Unit::TestCase assert_syntax_error("\"\\C-\\M-\x01\"", 'Invalid escape character syntax') e = assert_syntax_error('"\c\u0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~(?!~)/, e.message.lines.last) e = assert_syntax_error('"\c\U0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~(?!~)/, e.message.lines.last) e = assert_syntax_error('"\C-\u0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last) e = assert_syntax_error('"\C-\U0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last) e = assert_syntax_error('"\M-\u0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last) e = assert_syntax_error('"\M-\U0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last) e = assert_syntax_error(%["\\C-\u3042"], 'Invalid escape character syntax') - assert_match(/^\s \^(?# \\ ) ~(?# C ) ~(?# - ) ~+(?# U+3042 )$/x, e.message.lines.last) + assert_match(/(^|\|\s)\s \^(?# \\ ) ~(?# C ) ~(?# - ) ~+(?# U+3042 )($|\s)/x, e.message.lines.last) assert_not_include(e.message, "invalid multibyte char") end @@ -875,7 +883,8 @@ x = __ENCODING__ $test_parse_foobarbazqux = nil assert_equal(nil, $&) assert_equal(nil, eval('alias $& $preserve_last_match')) - assert_syntax_error('a = $#', /as a global variable name\na = \$\#\n \^~$/) + assert_syntax_error('a = $#', /as a global variable name/) + assert_syntax_error('a = $#', /a = \$\#\n(^|.+?\| ) \^~(?!~)/) end def test_invalid_instance_variable @@ -1259,8 +1268,8 @@ x = __ENCODING__ assert_syntax_error("def f r:def d; def f 0end", /unexpected/) end; - assert_syntax_error("def\nf(000)end", /^ \^~~/) - assert_syntax_error("def\nf(&0)end", /^ \^/) + assert_syntax_error("def\nf(000)end", /(^|\| ) \^~~/) + assert_syntax_error("def\nf(&0)end", /(^|\| ) \^/) end def test_method_location_in_rescue @@ -1336,17 +1345,21 @@ x = __ENCODING__ end def test_unexpected_token_after_numeric - assert_syntax_error('0000xyz', /^ \^~~\Z/) - assert_syntax_error('1.2i1.1', /^ \^~~\Z/) - assert_syntax_error('1.2.3', /^ \^~\Z/) + assert_syntax_error('0000xyz', /(^|\| ) \^~~(?!~)/) + assert_syntax_error('1.2i1.1', /(^|\| ) \^~~(?!~)/) + assert_syntax_error('1.2.3', /(^|\| ) \^~(?!~)/) assert_syntax_error('1.', /unexpected end-of-input/) assert_syntax_error('1e', /expecting end-of-input/) end def test_truncated_source_line - e = assert_syntax_error("'0123456789012345678901234567890123456789' abcdefghijklmnopqrstuvwxyz0123456789 0123456789012345678901234567890123456789", + lineno = __LINE__ + 1 + e = assert_syntax_error("'0123456789012345678901234567890123456789' abcdefghijklmnopqrstuvwxyz0123456789 123456789012345678901234567890123456789", /unexpected local variable or method/) + line = e.message.lines[1] + line.delete_prefix!("> #{lineno} | ") if line.start_with?(">") + assert_operator(line, :start_with?, "...") assert_operator(line, :end_with?, "...\n") end @@ -1390,11 +1403,11 @@ x = __ENCODING__ end def test_unexpected_eof - assert_syntax_error('unless', /^ \^\Z/) + assert_syntax_error('unless', /(^|\| ) \^(?!~)/) end def test_location_of_invalid_token - assert_syntax_error('class xxx end', /^ \^~~\Z/) + assert_syntax_error('class xxx end', /(^|\| ) \^~~(?!~)/) end def test_whitespace_warning diff --git a/test/ruby/test_pattern_matching.rb b/test/ruby/test_pattern_matching.rb index db6ad06b82..cfe3bd1e19 100644 --- a/test/ruby/test_pattern_matching.rb +++ b/test/ruby/test_pattern_matching.rb @@ -1331,7 +1331,7 @@ END end assert_block do - case {} + case C.new({}) in {} C.keys == nil end diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb index 76be9152a7..d9b98be8ba 100644 --- a/test/ruby/test_rubyoptions.rb +++ b/test/ruby/test_rubyoptions.rb @@ -1208,15 +1208,12 @@ class TestRubyOptions < Test::Unit::TestCase end def test_frozen_string_literal_debug - default_frozen = eval("'test'").frozen? - with_debug_pat = /created at/ wo_debug_pat = /can\'t modify frozen String: "\w+" \(FrozenError\)\n\z/ frozen = [ ["--enable-frozen-string-literal", true], ["--disable-frozen-string-literal", false], ] - frozen << [nil, false] unless default_frozen debugs = [ ["--debug-frozen-string-literal", true], diff --git a/test/ruby/test_rubyvm.rb b/test/ruby/test_rubyvm.rb index d729aa5af8..053a914a8a 100644 --- a/test/ruby/test_rubyvm.rb +++ b/test/ruby/test_rubyvm.rb @@ -32,6 +32,7 @@ class TestRubyVM < Test::Unit::TestCase end def test_keep_script_lines + omit if compiling_with_prism? pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO prev_conf = RubyVM.keep_script_lines @@ -68,4 +69,12 @@ class TestRubyVM < Test::Unit::TestCase ensure RubyVM.keep_script_lines = prev_conf end + + private + + # RubyVM.keep_script_lines does not mean anything in the context of prism, so + # we should omit tests that are looking for that functionality. + def compiling_with_prism? + RubyVM::InstructionSequence.compile("").to_a[4][:parser] == :prism + end end diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb index c453ecd350..8cf2c63a20 100644 --- a/test/ruby/test_sprintf.rb +++ b/test/ruby/test_sprintf.rb @@ -266,8 +266,8 @@ class TestSprintf < Test::Unit::TestCase # Specifying the precision multiple times with negative star arguments: assert_raise(ArgumentError, "[ruby-core:11570]") {sprintf("%.*.*.*.*f", -1, -1, -1, 5, 1)} - # Null bytes after percent signs are removed: - assert_equal("%\0x hello", sprintf("%\0x hello"), "[ruby-core:11571]") + assert_raise(ArgumentError) {sprintf("%\0x hello")} + assert_raise(ArgumentError) {sprintf("%\nx hello")} assert_raise(ArgumentError, "[ruby-core:11573]") {sprintf("%.25555555555555555555555555555555555555s", "hello")} @@ -279,10 +279,9 @@ class TestSprintf < Test::Unit::TestCase assert_raise_with_message(ArgumentError, /unnumbered\(1\) mixed with numbered/) { sprintf("%1$*d", 3) } assert_raise_with_message(ArgumentError, /unnumbered\(1\) mixed with numbered/) { sprintf("%1$.*d", 3) } - verbose, $VERBOSE = $VERBOSE, nil - assert_nothing_raised { sprintf("", 1) } - ensure - $VERBOSE = verbose + assert_warning(/too many arguments/) do + sprintf("", 1) + end end def test_float diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index ebe85dac82..9bd86dfb78 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -3617,17 +3617,16 @@ CODE def test_chilled_string chilled_string = eval('"chilled"') - # Chilled strings pretend to be frozen - assert_predicate chilled_string, :frozen? + assert_not_predicate chilled_string, :frozen? assert_not_predicate chilled_string.dup, :frozen? - assert_predicate chilled_string.clone, :frozen? + assert_not_predicate chilled_string.clone, :frozen? # @+ treat the original string as frozen assert_not_predicate(+chilled_string, :frozen?) assert_not_same chilled_string, +chilled_string - # @- the original string as mutable + # @- treat the original string as mutable assert_predicate(-chilled_string, :frozen?) assert_not_same chilled_string, -chilled_string end diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index 44162f06cb..8f94ec71fc 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -506,10 +506,6 @@ class TestSyntax < Test::Unit::TestCase end def test_warn_balanced - warning = <<WARN -test:1: warning: '%s' after local variable or literal is interpreted as binary operator -test:1: warning: even though it seems like %s -WARN [ [:**, "argument prefix"], [:*, "argument prefix"], @@ -523,7 +519,9 @@ WARN all_assertions do |a| ["puts 1 #{op}0", "puts :a #{op}0", "m = 1; puts m #{op}0"].each do |src| a.for(src) do - assert_warning(warning % [op, syn], src) do + warning = /'#{Regexp.escape(op)}' after local variable or literal is interpreted as binary operator.+?even though it seems like #{syn}/m + + assert_warning(warning, src) do assert_valid_syntax(src, "test", verbose: true) end end @@ -715,8 +713,8 @@ WARN end def test_duplicated_when - w = 'warning: duplicated \'when\' clause with line 3 is ignored' - assert_warning(/3: #{w}.+4: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m) { + w = ->(line) { "warning: 'when' clause on line #{line} duplicates 'when' clause on line 3 and is ignored" } + assert_warning(/#{w[3]}.+#{w[4]}.+#{w[4]}.+#{w[5]}.+#{w[5]}/m) { eval %q{ case 1 when 1, 1 @@ -725,7 +723,7 @@ WARN end } } - assert_warning(/#{w}/) {#/3: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m){ + assert_warning(/#{w[3]}.+#{w[4]}.+#{w[5]}.+#{w[5]}/m) { a = a = 1 eval %q{ case 1 @@ -735,7 +733,7 @@ WARN end } } - assert_warning(/3: #{w}/m) { + assert_warning(/#{w[3]}/) { eval %q{ case 1 when __LINE__, __LINE__ @@ -744,7 +742,7 @@ WARN end } } - assert_warning(/3: #{w}/m) { + assert_warning(/#{w[3]}/) { eval %q{ case 1 when __FILE__, __FILE__ @@ -756,7 +754,7 @@ WARN end def test_duplicated_when_check_option - w = /duplicated \'when\' clause with line 3 is ignored/ + w = /'when' clause on line 4 duplicates 'when' clause on line 3 and is ignored/ assert_in_out_err(%[-wc], "#{<<~"begin;"}\n#{<<~'end;'}", ["Syntax OK"], w) begin; case 1 @@ -889,6 +887,16 @@ e" assert_dedented_heredoc(expect, result) end + def test_dedented_heredoc_with_leading_blank_line + # the blank line has six leading spaces + result = " \n" \ + " b\n" + expect = " \n" \ + "b\n" + assert_dedented_heredoc(expect, result) + end + + def test_dedented_heredoc_with_blank_more_indented_line_escaped result = " a\n" \ "\\ \\ \\ \\ \\ \\ \n" \ @@ -996,7 +1004,7 @@ eom end def test_dedented_heredoc_concatenation - assert_equal("\n0\n1", eval("<<~0 '1'\n \n0\#{}\n0")) + assert_equal(" \n0\n1", eval("<<~0 '1'\n \n0\#{}\n0")) end def test_heredoc_mixed_encoding @@ -1238,6 +1246,20 @@ eom assert_syntax_error("a&.x,=0", /multiple assignment destination/) end + def test_safe_call_in_for_variable + assert_valid_syntax("for x&.bar in []; end") + assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + foo = nil + for foo&.bar in [1]; end + assert_nil(foo) + + foo = Struct.new(:bar).new + for foo&.bar in [1]; end + assert_equal(1, foo.bar) + end; + end + def test_no_warning_logop_literal assert_warning("") do eval("true||raise;nil") @@ -1577,7 +1599,7 @@ eom end def test_syntax_error_at_newline - expected = "\n ^" + expected = /(\n|\| ) \^/ assert_syntax_error("%[abcdef", expected) assert_syntax_error("%[abcdef\n", expected) end @@ -1755,8 +1777,8 @@ eom assert_equal("instance ok", k.new.rescued("ok")) # Current technical limitation: cannot prepend "private" or something for command endless def - error = /syntax error, unexpected string literal/ - error2 = /syntax error, unexpected local variable or method/ + error = /(syntax error,|\^~*) unexpected string literal/ + error2 = /(syntax error,|\^~*) unexpected local variable or method/ assert_syntax_error('private def foo = puts "Hello"', error) assert_syntax_error('private def foo() = puts "Hello"', error) assert_syntax_error('private def foo(x) = puts x', error2) @@ -1900,7 +1922,7 @@ eom ] end assert_valid_syntax('proc {def foo(_);end;it}') - assert_syntax_error('p { [it **2] }', /unexpected \*\*arg/) + assert_syntax_error('p { [it **2] }', /unexpected \*\*/) end def test_value_expr_in_condition diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb index f97306717d..7014843bba 100644 --- a/test/rubygems/helper.rb +++ b/test/rubygems/helper.rb @@ -76,8 +76,6 @@ class Gem::TestCase < Test::Unit::TestCase attr_accessor :uri # :nodoc: - @@tempdirs = [] - def assert_activate(expected, *specs) specs.each do |spec| case spec @@ -451,9 +449,7 @@ class Gem::TestCase < Test::Unit::TestCase Dir.chdir @current_dir - FileUtils.rm_rf @tempdir - - restore_env + ENV.replace(@orig_env) Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE, @@ -481,12 +477,9 @@ class Gem::TestCase < Test::Unit::TestCase @back_ui.close - refute_directory_exists @tempdir, "may be still in use" - ghosts = @@tempdirs.filter_map do |test_name, tempdir| - test_name if File.exist?(tempdir) - end - @@tempdirs << [method_name, @tempdir] - assert_empty ghosts + FileUtils.rm_rf @tempdir + + refute_directory_exists @tempdir, "#{@tempdir} used by test #{method_name} is still in use" end def credential_setup @@ -541,6 +534,16 @@ class Gem::TestCase < Test::Unit::TestCase ENV["BUNDLE_GEMFILE"] = File.join(@tempdir, "Gemfile") end + def with_env(overrides, &block) + orig_env = ENV.to_h + ENV.replace(overrides) + begin + block.call + ensure + ENV.replace(orig_env) + end + end + ## # A git_gem is used with a gem dependencies file. The gem created here # has no files, just a gem specification for the given +name+ and +version+. @@ -1526,23 +1529,6 @@ Also, a list: PUBLIC_KEY = nil PUBLIC_CERT = nil end if Gem::HAVE_OPENSSL - - private - - def restore_env - unless Gem.win_platform? - ENV.replace(@orig_env) - return - end - - # Fallback logic for Windows below to workaround - # https://bugs.ruby-lang.org/issues/16798. Can be dropped once all - # supported rubies include the fix for that. - - ENV.clear - - @orig_env.each {|k, v| ENV[k] = v } - end end # https://github.com/seattlerb/minitest/blob/13c48a03d84a2a87855a4de0c959f96800100357/lib/minitest/mock.rb#L192 diff --git a/test/rubygems/test_bundled_ca.rb b/test/rubygems/test_bundled_ca.rb index 50e621f22b..a737185681 100644 --- a/test/rubygems/test_bundled_ca.rb +++ b/test/rubygems/test_bundled_ca.rb @@ -33,7 +33,7 @@ class TestGemBundledCA < Gem::TestCase http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.cert_store = bundled_certificate_store http.get("/") - rescue Errno::ENOENT, Errno::ETIMEDOUT, SocketError, Net::OpenTimeout + rescue Errno::ENOENT, Errno::ETIMEDOUT, SocketError, Gem::Net::OpenTimeout pend "#{host} seems offline, I can't tell whether ssl would work." rescue OpenSSL::SSL::SSLError => e # Only fail for certificate verification errors diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index 244b7749a5..40a473f8d6 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -516,7 +516,10 @@ class TestGem < Gem::TestCase Gem.clear_paths - assert_nil Gem::Specification.send(:class_variable_get, :@@all) + with_env("GEM_HOME" => "foo", "GEM_PATH" => "bar") do + assert_equal("foo", Gem.dir) + assert_equal("bar", Gem.path.first) + end end def test_self_configuration @@ -1281,7 +1284,6 @@ class TestGem < Gem::TestCase def test_self_try_activate_missing_extensions spec = util_spec "ext", "1" do |s| s.extensions = %w[ext/extconf.rb] - s.mark_version s.installed_by_version = v("2.2") end diff --git a/test/rubygems/test_gem_ci_detector.rb b/test/rubygems/test_gem_ci_detector.rb index 3caefce97d..a28ee49f4b 100644 --- a/test/rubygems/test_gem_ci_detector.rb +++ b/test/rubygems/test_gem_ci_detector.rb @@ -3,7 +3,7 @@ require_relative "helper" require "rubygems" -class TestCiDetector < Test::Unit::TestCase +class TestCiDetector < Gem::TestCase def test_ci? with_env("FOO" => "bar") { assert_equal(false, Gem::CIDetector.ci?) } with_env("CI" => "true") { assert_equal(true, Gem::CIDetector.ci?) } @@ -29,16 +29,4 @@ class TestCiDetector < Test::Unit::TestCase assert_equal(["dsari", "taskcluster"], Gem::CIDetector.ci_strings) end end - - private - - def with_env(overrides, &block) - @orig_env = ENV.to_h - ENV.replace(overrides) - begin - block.call - ensure - ENV.replace(@orig_env) - end - end end diff --git a/test/rubygems/test_gem_commands_rebuild_command.rb b/test/rubygems/test_gem_commands_rebuild_command.rb index 5e8c797e2d..3b7927c44e 100644 --- a/test/rubygems/test_gem_commands_rebuild_command.rb +++ b/test/rubygems/test_gem_commands_rebuild_command.rb @@ -105,7 +105,7 @@ class TestGemCommandsRebuildCommand < Gem::TestCase assert_equal old_spec.name, new_spec.name assert_equal old_spec.summary, new_spec.summary - reproduced + [reproduced, original] end def test_build_is_reproducible @@ -134,12 +134,21 @@ class TestGemCommandsRebuildCommand < Gem::TestCase # also testing that `gem rebuild` overrides the value. ENV["SOURCE_DATE_EPOCH"] = Time.new(2007, 8, 9, 10, 11, 12).to_s - rebuild_gem_file = util_test_rebuild_gem(@gem, [@gem_name, @gem_version], original_gem_file, gemspec_file, timestamp) + rebuild_gem_file, saved_gem_file = + util_test_rebuild_gem(@gem, [@gem_name, @gem_version], original_gem_file, gemspec_file, timestamp) rebuild_contents = File.read(rebuild_gem_file) assert_equal build_contents, rebuild_contents ensure ENV["SOURCE_DATE_EPOCH"] = epoch + if rebuild_gem_file + File.unlink(rebuild_gem_file) + dir = File.dirname(rebuild_gem_file) + Dir.rmdir(dir) + File.unlink(saved_gem_file) + Dir.rmdir(File.dirname(saved_gem_file)) + Dir.rmdir(File.dirname(dir)) + end end end diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb index 43f695f147..8eedb6c03a 100644 --- a/test/rubygems/test_gem_commands_setup_command.rb +++ b/test/rubygems/test_gem_commands_setup_command.rb @@ -159,6 +159,23 @@ class TestGemCommandsSetupCommand < Gem::TestCase end end + def test_destdir_flag_regenerates_binstubs + # install to destdir + destdir = File.join(@tempdir, "foo") + gem_bin_path = gem_install "destdir-only-gem", install_dir: destdir + + # change binstub manually + write_file gem_bin_path do |io| + io.puts "I changed it!" + end + + @cmd.options[:destdir] = destdir + @cmd.options[:prefix] = "/" + @cmd.execute + + assert_match(/\A#!/, File.read(gem_bin_path)) + end + def test_files_in assert_equal %w[rubygems.rb rubygems/requirement.rb rubygems/ssl_certs/rubygems.org/foo.pem], @cmd.files_in("lib").sort @@ -412,7 +429,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase end end - def gem_install(name) + def gem_install(name, **options) gem = util_spec name do |s| s.executables = [name] s.files = %W[bin/#{name}] @@ -420,8 +437,8 @@ class TestGemCommandsSetupCommand < Gem::TestCase write_file File.join @tempdir, "bin", name do |f| f.puts "#!/usr/bin/ruby" end - install_gem gem - File.join @gemhome, "bin", name + install_gem gem, **options + File.join options[:install_dir] || @gemhome, "bin", name end def gem_install_with_plugin(name) diff --git a/test/rubygems/test_gem_package_tar_header.rb b/test/rubygems/test_gem_package_tar_header.rb index 4469750f9a..a3f95bb770 100644 --- a/test/rubygems/test_gem_package_tar_header.rb +++ b/test/rubygems/test_gem_package_tar_header.rb @@ -99,6 +99,31 @@ class TestGemPackageTarHeader < Gem::Package::TarTestCase assert_empty @tar_header end + def test_empty + @tar_header = Gem::Package::TarHeader.from(StringIO.new(Gem::Package::TarHeader::EMPTY_HEADER)) + + assert_empty @tar_header + assert_equal Gem::Package::TarHeader.new( + checksum: 0, + devmajor: 0, + devminor: 0, + empty: true, + gid: 0, + gname: "", + linkname: "", + magic: "", + mode: 0, + mtime: 0, + name: "", + prefix: "", + size: 0, + typeflag: "0", + uid: 0, + uname: "", + version: 0, + ), @tar_header + end + def test_equals2 assert_equal @tar_header, @tar_header assert_equal @tar_header, @tar_header.dup diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb index e4bf882317..00e48498c6 100644 --- a/test/rubygems/test_gem_platform.rb +++ b/test/rubygems/test_gem_platform.rb @@ -145,6 +145,9 @@ class TestGemPlatform < Gem::TestCase "x86_64-openbsd3.9" => ["x86_64", "openbsd", "3.9"], "x86_64-openbsd4.0" => ["x86_64", "openbsd", "4.0"], "x86_64-openbsd" => ["x86_64", "openbsd", nil], + "wasm32-wasi" => ["wasm32", "wasi", nil], + "wasm32-wasip1" => ["wasm32", "wasi", nil], + "wasm32-wasip2" => ["wasm32", "wasi", nil], } test_cases.each do |arch, expected| diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index 9e05649f7c..9395e34f75 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -56,7 +56,6 @@ end s.add_dependency "jabber4r", "> 0.0.0" s.add_dependency "pqa", ["> 0.4", "<= 0.6"] - s.mark_version s.files = %w[lib/code.rb] end end @@ -69,7 +68,6 @@ end s.license = "MIT" s.platform = platform - s.mark_version s.files = %w[lib/code.rb] s.installed_by_version = v("2.2") end @@ -96,7 +94,6 @@ end s.requirements << "A working computer" s.license = "MIT" - s.mark_version s.files = %w[lib/code.rb] end @@ -970,7 +967,10 @@ dependencies: [] def test_self_stubs_for_lazy_loading Gem.loaded_specs.clear - Gem::Specification.class_variable_set(:@@stubs, nil) + + specification_record = Gem::Specification.specification_record + + specification_record.instance_variable_set(:@stubs, nil) dir_standard_specs = File.join Gem.dir, "specifications" @@ -978,9 +978,9 @@ dependencies: [] save_gemspec("b-1", "1", dir_standard_specs) {|s| s.name = "b" } assert_equal ["a-1"], Gem::Specification.stubs_for("a").map(&:full_name) - assert_equal 1, Gem::Specification.class_variable_get(:@@stubs_by_name).length + assert_equal 1, specification_record.instance_variable_get(:@stubs_by_name).length assert_equal ["b-1"], Gem::Specification.stubs_for("b").map(&:full_name) - assert_equal 2, Gem::Specification.class_variable_get(:@@stubs_by_name).length + assert_equal 2, specification_record.instance_variable_get(:@stubs_by_name).length assert_equal( Gem::Specification.stubs_for("a").map(&:object_id), @@ -989,7 +989,7 @@ dependencies: [] Gem.loaded_specs.delete "a" Gem.loaded_specs.delete "b" - Gem::Specification.class_variable_set(:@@stubs, nil) + specification_record.instance_variable_set(:@stubs, nil) end def test_self_stubs_for_no_lazy_loading_after_all_specs_setup @@ -3187,7 +3187,7 @@ or set it to nil if you don't want to specify a license. end def test_removed_methods - assert_equal Gem::Specification::REMOVED_METHODS, [:rubyforge_project=] + assert_equal Gem::Specification::REMOVED_METHODS, [:rubyforge_project=, :mark_version] end def test_validate_removed_rubyforge_project @@ -3480,12 +3480,17 @@ Did you mean 'Ruby'? util_setup_validate @a1.rubygems_version = "3" - e = assert_raise Gem::InvalidSpecificationException do + + use_ui @ui do @a1.validate end - assert_equal "expected RubyGems version #{Gem::VERSION}, was 3", - e.message + expected = <<~EXPECTED + #{w}: expected RubyGems version #{Gem::VERSION}, was 3 + #{w}: See https://guides.rubygems.org/specification-reference/ for help + EXPECTED + + assert_equal expected, @ui.error end def test_validate_specification_version diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb index 9e0c1aa3d8..aa5ab0ed67 100644 --- a/test/rubygems/test_gem_uninstaller.rb +++ b/test/rubygems/test_gem_uninstaller.rb @@ -188,22 +188,81 @@ class TestGemUninstaller < Gem::InstallerTestCase refute File.exist?(plugin_path), "plugin not removed" end - def test_remove_plugins_with_install_dir + def test_uninstall_with_install_dir_removes_plugins write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| io.write "# do nothing" end @spec.files += %w[lib/rubygems_plugin.rb] - Gem::Installer.at(Gem::Package.build(@spec), force: true).install + package = Gem::Package.build(@spec) + + Gem::Installer.at(package, force: true).install plugin_path = File.join Gem.plugindir, "a_plugin.rb" assert File.exist?(plugin_path), "plugin not written" - Dir.mkdir "#{@gemhome}2" - Gem::Uninstaller.new(nil, install_dir: "#{@gemhome}2").remove_plugins @spec + install_dir = "#{@gemhome}2" + + Gem::Installer.at(package, force: true, install_dir: install_dir).install + + install_dir_plugin_path = File.join install_dir, "plugins/a_plugin.rb" + assert File.exist?(install_dir_plugin_path), "plugin not written" + + Gem::Specification.dirs = [install_dir] + Gem::Uninstaller.new(@spec.name, executables: true, install_dir: install_dir).uninstall assert File.exist?(plugin_path), "plugin unintentionally removed" + refute File.exist?(install_dir_plugin_path), "plugin not removed" + end + + def test_uninstall_with_install_dir_regenerates_plugins + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| + io.write "# do nothing" + end + + @spec.files += %w[lib/rubygems_plugin.rb] + + install_dir = "#{@gemhome}2" + + package = Gem::Package.build(@spec) + + spec_v9 = @spec.dup + spec_v9.version = "9" + package_v9 = Gem::Package.build(spec_v9) + + Gem::Installer.at(package, force: true, install_dir: install_dir).install + Gem::Installer.at(package_v9, force: true, install_dir: install_dir).install + + install_dir_plugin_path = File.join install_dir, "plugins/a_plugin.rb" + assert File.exist?(install_dir_plugin_path), "plugin not written" + + Gem::Specification.dirs = [install_dir] + Gem::Uninstaller.new(@spec.name, version: "9", executables: true, install_dir: install_dir).uninstall + assert File.exist?(install_dir_plugin_path), "plugin unintentionally removed" + + Gem::Specification.dirs = [install_dir] + Gem::Uninstaller.new(@spec.name, executables: true, install_dir: install_dir).uninstall + refute File.exist?(install_dir_plugin_path), "plugin not removed" + end + + def test_remove_plugins_user_installed + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| + io.write "# do nothing" + end + + @spec.files += %w[lib/rubygems_plugin.rb] + + Gem::Installer.at(Gem::Package.build(@spec), force: true, user_install: true).install + + plugin_path = File.join Gem.user_dir, "plugins/a_plugin.rb" + assert File.exist?(plugin_path), "plugin not written" + + Gem::Specification.dirs = [Gem.dir, Gem.user_dir] + + Gem::Uninstaller.new(@spec.name, executables: true, force: true, user_install: true).uninstall + + refute File.exist?(plugin_path), "plugin not removed" end def test_regenerate_plugins_for @@ -370,7 +429,7 @@ create_makefile '#{@spec.name}' end def test_uninstall_user_install - @user_spec = Gem::Specification.find_by_name "b" + Gem::Specification.dirs = [Gem.user_dir] uninstaller = Gem::Uninstaller.new(@user_spec.name, executables: true, @@ -394,6 +453,32 @@ create_makefile '#{@spec.name}' assert_same uninstaller, @post_uninstall_hook_arg end + def test_uninstall_user_install_with_symlinked_home + pend "Symlinks not supported or not enabled" unless symlink_supported? + + Gem::Specification.dirs = [Gem.user_dir] + + symlinked_home = File.join(@tempdir, "new-home") + FileUtils.ln_s(Gem.user_home, symlinked_home) + + ENV["HOME"] = symlinked_home + Gem.instance_variable_set(:@user_home, nil) + Gem.instance_variable_set(:@data_home, nil) + + uninstaller = Gem::Uninstaller.new(@user_spec.name, + executables: true, + user_install: true, + force: true) + + gem_dir = File.join @user_spec.gem_dir + + assert_path_exist gem_dir + + uninstaller.uninstall + + assert_path_not_exist gem_dir + end + def test_uninstall_wrong_repo Dir.mkdir "#{@gemhome}2" Gem.use_paths "#{@gemhome}2", [@gemhome] diff --git a/test/rubygems/test_webauthn_poller.rb b/test/rubygems/test_webauthn_poller.rb index 23290d8ea1..fd24081758 100644 --- a/test/rubygems/test_webauthn_poller.rb +++ b/test/rubygems/test_webauthn_poller.rb @@ -13,7 +13,7 @@ class WebauthnPollerTest < Gem::TestCase @fetcher = Gem::FakeFetcher.new Gem::RemoteFetcher.fetcher = @fetcher @credentials = { - email: "email@example.com", + identifier: "email@example.com", password: "password", } end @@ -121,4 +121,14 @@ class WebauthnPollerTest < Gem::TestCase assert_equal error.message, "Security device verification failed: The token in the link you used has either expired or been used already." end + + def test_poll_for_otp_missing_credentials + @credentials = { password: "password" } + + error = assert_raise Gem::WebauthnVerificationError do + Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials) + end + + assert_equal error.message, "Security device verification failed: Provided missing credentials" + end end diff --git a/test/test_delegate.rb b/test/test_delegate.rb index 57480b18ea..f7bedf37fb 100644 --- a/test/test_delegate.rb +++ b/test/test_delegate.rb @@ -3,14 +3,6 @@ require 'test/unit' require 'delegate' class TestDelegateClass < Test::Unit::TestCase - module PP - def mu_pp(obj) - str = super - str = "#<#{obj.class}: #{str}>" if Delegator === obj - str - end - end - module M attr_reader :m end @@ -215,7 +207,6 @@ class TestDelegateClass < Test::Unit::TestCase end def test_eql? - extend PP s0 = SimpleDelegator.new("foo") s1 = SimpleDelegator.new("bar") s2 = SimpleDelegator.new("foo") diff --git a/test/test_timeout.rb b/test/test_timeout.rb index e900b10cd7..34966f92a4 100644 --- a/test/test_timeout.rb +++ b/test/test_timeout.rb @@ -66,7 +66,7 @@ class TestTimeout < Test::Unit::TestCase a = nil assert_raise(Timeout::Error) do Timeout.timeout(0.1) { - Timeout.timeout(1) { + Timeout.timeout(30) { nil while true } a = 1 @@ -84,7 +84,7 @@ class TestTimeout < Test::Unit::TestCase def test_nested_timeout_error_identity begin Timeout.timeout(0.1, MyNewErrorOuter) { - Timeout.timeout(1, MyNewErrorInner) { + Timeout.timeout(30, MyNewErrorInner) { nil while true } } diff --git a/test/win32/test_registry.rb b/test/win32/test_registry.rb new file mode 100644 index 0000000000..02cafc09b0 --- /dev/null +++ b/test/win32/test_registry.rb @@ -0,0 +1,97 @@ +if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM + begin + require 'win32/registry' + rescue LoadError + else + require 'test/unit' + end +end + +if defined?(Win32::Registry) + class TestWin32Registry < Test::Unit::TestCase + COMPUTERNAME = 'SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName' + VOLATILE_ENVIRONMENT = 'Volatile Environment' + + def test_predefined + assert_predefined_key Win32::Registry::HKEY_CLASSES_ROOT + assert_predefined_key Win32::Registry::HKEY_CURRENT_USER + assert_predefined_key Win32::Registry::HKEY_LOCAL_MACHINE + assert_predefined_key Win32::Registry::HKEY_USERS + assert_predefined_key Win32::Registry::HKEY_PERFORMANCE_DATA + assert_predefined_key Win32::Registry::HKEY_PERFORMANCE_TEXT + assert_predefined_key Win32::Registry::HKEY_PERFORMANCE_NLSTEXT + assert_predefined_key Win32::Registry::HKEY_CURRENT_CONFIG + assert_predefined_key Win32::Registry::HKEY_DYN_DATA + end + + def test_class_open + name1, keys1 = Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, "SYSTEM") do |reg| + assert_predicate reg, :open? + [reg.name, reg.keys] + end + name2, keys2 = Win32::Registry::HKEY_LOCAL_MACHINE.open("SYSTEM") do |reg| + assert_predicate reg, :open? + [reg.name, reg.keys] + end + assert_equal name1, name2 + assert_equal keys1, keys2 + end + + def test_read + computername = ENV['COMPUTERNAME'] + Win32::Registry::HKEY_LOCAL_MACHINE.open(COMPUTERNAME) do |reg| + assert_equal computername, reg['ComputerName'] + assert_equal [Win32::Registry::REG_SZ, computername], reg.read('ComputerName') + assert_raise(TypeError) {reg.read('ComputerName', Win32::Registry::REG_DWORD)} + end + end + + def test_create + desired = Win32::Registry::KEY_ALL_ACCESS + option = Win32::Registry::REG_OPTION_VOLATILE + Win32::Registry::HKEY_CURRENT_USER.open(VOLATILE_ENVIRONMENT, desired) do |reg| + v = self.class.unused_value(reg) + begin + reg.create(v, desired, option) {} + ensure + reg.delete_key(v, true) + end + end + end + + def test_write + desired = Win32::Registry::KEY_ALL_ACCESS + Win32::Registry::HKEY_CURRENT_USER.open(VOLATILE_ENVIRONMENT, desired) do |reg| + v = self.class.unused_value(reg) + begin + reg.write_s(v, "data") + assert_equal [Win32::Registry::REG_SZ, "data"], reg.read(v) + reg.write_i(v, 0x5fe79027) + assert_equal [Win32::Registry::REG_DWORD, 0x5fe79027], reg.read(v) + ensure + reg.delete(v) + end + end + end + + private + + def assert_predefined_key(key) + assert_kind_of Win32::Registry, key + assert_predicate key, :open? + assert_not_predicate key, :created? + end + + class << self + def unused_value(reg, prefix = "Test_", limit = 100, fail: true) + limit.times do + v = + rand(0x100000).to_s(36) + reg.read(v) + rescue + return v + end + omit "Unused value not found in #{reg}" if fail + end + end + end +end diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index ae4adc21fe..15e5bd852f 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -991,6 +991,25 @@ if defined? Zlib assert_raise(ArgumentError) { f.read(-1) } assert_equal(str, f.read) end + + Zlib::GzipReader.open(t.path) do |f| + s = "".b + + assert_raise(ArgumentError) { f.read(-1, s) } + + assert_same s, f.read(1, s) + assert_equal "\xE3".b, s + + assert_same s, f.read(2, s) + assert_equal "\x81\x82".b, s + + assert_same s, f.read(6, s) + assert_equal "\u3044\u3046".b, s + + assert_nil f.read(1, s) + assert_equal "".b, s + assert_predicate f, :eof? + end } end @@ -1005,10 +1024,14 @@ if defined? Zlib Zlib::GzipReader.open(t.path) do |f| s = "".dup - f.readpartial(3, s) + assert_same s, f.readpartial(3, s) assert("foo".start_with?(s)) assert_raise(ArgumentError) { f.readpartial(-1) } + + assert_same s, f.readpartial(3, s) + + assert_predicate f, :eof? end } end |